library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; -- nota mia: considerato che il segnale principale per la comparazione con la PWM arriva qui nel PI, il controllo della direzione sarebbe meglio farlo qui per evitare dei flick entity PI is generic ( Kp : real; -- Coefficiente proporzionale Ki : real -- Coefficiente integrativo ); port ( reference_signal : in signed(7 downto 0); -- Segnale di riferimento (velocità desiderata) encoder_signal : in signed(7 downto 0); -- Segnale dall'encoder (velocità effettiva) pwm_output : out signed(7 downto 0) -- Uscita per pilotare la PWM ); end entity; architecture ARC of PI is signal error : signed (7 downto 0) := "00000000"; -- Errore tra velocità di riferimento e velocità effettiva signal integral_term : signed (7 downto 0) := "00000000"; -- Termine integrativo signal ref : signed(7 downto 0); signal feed : signed (7 downto 0); constant Max_Pwm : signed(7 downto 0) := "01111111"; -- Valore massimo della PWM (127) constant Min_Pwm : signed(7 downto 0) := "10000000"; -- Valore minimo della PWM (-128) begin process(reference_signal, encoder_signal)is begin -- Calcolo dell'errore tra velocità di riferimento e velocità effettiva error <= to_integer(ref) - to_integer(feed); -- Calcolo del termine integrativo integral_term <= integral_term + error; -- Calcolo del segnale di controllo pwm_output <= signed(signed(encoder_signal) + to_signed(integer(Kp * error + Ki * integral_term), pwm_output'length));--pwm_output'length è l'equivalenente di (7 downto 0) ma più skillato end process; end architecture;