library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_unsigned.all; use IEEE.std_logic_arith.all; entity gestion_verin is port ( clk, chipselect, write_n, reset_n, data_in : in std_logic; writedata : in std_logic_vector (31 downto 0); address : in std_logic_vector (2 downto 0); readdata : out std_logic_vector (31 downto 0); out_pwm, cs_n, clk_adc, out_sens : out std_logic ); end entity; ARCHITECTURE arch_gestion_verin of gestion_verin IS -- signaux relatifs au circuit gestion PWM signal freq : std_logic_vector (15 downto 0); signal duty : std_logic_vector (15 downto 0); signal counter : std_logic_vector (15 downto 0); signal pwm_on, enable : std_logic; -- signaux relatifs au circuit contrôle butéees signal butee_g, butee_d , angle_barre: std_logic_vector (11 downto 0); signal sens, fin_course_d, fin_course_g : std_logic; -- signaux relatifs à l'interface adc signal raz_compteur, fin, s_clk_adc, clk_1M, start_conv : std_logic; signal compt_front : integer range 0 to 15; signal s_data : std_logic_vector (11 downto 0); -- signaux relatifs au pilotage de tous les circuits signal config : std_logic_vector (2 downto 0); signal raz_n : std_logic; BEGIN --0000000000000000000000000000000000000000000000000000 -- circuit de gestion de la PWM --**************************************************** -- fixe la fréquence de la pwm --***************************************************** divide: process (clk, raz_n) begin if raz_n = '0' then counter <= (others => '0'); elsif clk'event and clk = '1' then if counter >= freq then counter <= (others => '0'); else counter <= counter + 1; end if; end if; end process divide; --****************************************************** --****************************************************** --génère le rapport cyclique --****************************************************** compare: process (clk, raz_n) begin if raz_n = '0' then pwm_on <= '0'; elsif clk'event and clk = '1' then if counter >= duty then pwm_on <= '0'; else pwm_on <= '1'; end if; end if; end process compare; --******************************************************* --0000000000000000000000000000000000000000000000000000000 --0000000000000000000000000000000000000000000000000000000 -- circuit de contrôle des butées --******************************************************* -- génère la sortie pwm en fonction des butées --******************************************************* controle_butées: process (sens, butee_g, butee_d, angle_barre, pwm_on) begin if angle_barre >= butee_d then fin_course_d <= '1'; else fin_course_d <= '0'; end if; if angle_barre <= butee_g then fin_course_g <= '1'; else fin_course_g <= '0'; end if; end process controle_butées; out_pwm <= enable and pwm_on and (((not fin_course_d) and sens) or ((not fin_course_g) and (not sens))) ; out_sens <= sens; --******************************************************* --0000000000000000000000000000000000000000000000000000000000000000 --0000000000000000000000000000000000000000000000000000000000000000 -- ********************************************************** -- interface avec adc mcp3201 --*********************************************************** -- machine à état pour piloter l'adc et mémoriser la donnée --*********************************************************** pilote_adc: process (raz_n, clk_1M) variable etat_pilote:integer range 0 to 4; begin if raz_n='0' then etat_pilote:=0; cs_n<= '1'; s_clk_adc <= '0'; raz_compteur <= '1';angle_barre <= X"000"; elsif clk_1M'event and clk_1M='1' then case etat_pilote is when 0 => if start_conv='1' then etat_pilote:=1 ; cs_n <= '0'; raz_compteur <= '0'; end if; when 1 => etat_pilote:=2 ; s_clk_adc <= '1'; when 2 => etat_pilote:=3; s_clk_adc <= '0'; when 3 => if fin='1' then etat_pilote:=4 ; s_clk_adc <= '0'; cs_n <= '1'; angle_barre <= s_data;--mémo donnée else etat_pilote := 2; s_clk_adc <= '1'; end if; when 4 => if start_conv='0' then etat_pilote:=0 ; cs_n <= '1'; s_clk_adc <= '0'; raz_compteur <= '1'; end if; when others => etat_pilote :=0; s_clk_adc <= '0'; cs_n <= '1'; end case; end if; end process pilote_adc; --****************************************************** --********************************************************** -- process de comptage des fronts d'horloge de clk_adc --********************************************************** compt_fronts: process (s_clk_adc, raz_compteur) begin if raz_compteur = '1' then compt_front <=0; elsif s_clk_adc'event and s_clk_adc='1' then if compt_front=14 then compt_front <= 0; fin <= '1'; else compt_front <= compt_front +1; fin <= '0'; end if; end if; end process compt_fronts; --******************************************************* --******************************************************** -- process registre à décalage --******************************************************** rec_dec: process (s_clk_adc) variable i: integer ; begin if s_clk_adc'event and s_clk_adc='1' then s_data(0) <= data_in ; For i in 1 to 11 loop s_data(i) <= s_data(i-1); end loop; End if ; end process rec_dec; --*********************************************************** --********************************************************************* -- génération 1MHz --********************************************************************* gene_1M: process(clk,reset_n) variable count_gene_1M : integer range 0 to 25; BEGIN if raz_n= '0' then count_gene_1M:=0; elsif clk'event and clk='1' then count_gene_1M:= count_gene_1M +1; if count_gene_1M = 24 then clk_1M <= not(clk_1M); count_gene_1M:= 0; end if; end if; end process gene_1M; --********************************************************************* --********************************************************************* -- génération du start_conv toutes les 100ms --********************************************************************* gene_start_conv: process(clk_1M,reset_n) variable count_conv : integer range 0 to 50000; BEGIN if raz_n= '0' then count_conv:=0; elsif clk_1M'event and clk_1M='1' then count_conv:= count_conv +1; if count_conv = 49999 then start_conv <= not start_conv; count_conv:= 0; end if; end if; end process gene_start_conv; --********************************************************************* --**************************** -- mise à jour des sorties --**************************** clk_adc <= s_clk_adc; --0000000000000000000000000000000000000000000000000000000000000000 --0000000000000000000000000000000000000000000000000000000000000000 -- interface bus avalon --****************************************************** -- écriture registres --******************************************************* ecriture: process (clk, reset_n) begin if reset_n = '0' then freq <= (others => '0'); duty <= (others => '0'); butee_g <= (others => '0'); butee_d <= (others => '0'); config <= (others => '0'); elsif clk'event and clk = '1' then if chipselect ='1' and write_n = '0' then case address is when "000" => freq (15 downto 0) <= (writedata (15 downto 0)); when "001" => duty (15 downto 0) <= (writedata (15 downto 0)); when "010" => butee_g (11 downto 0) <= (writedata (11 downto 0)); when "011" => butee_d (11 downto 0) <= (writedata (11 downto 0)); when "100" => config (2 downto 0)<= (writedata (2 downto 0)); when others => config <= (others => '0'); end case; end if; end if; end process ecriture; --**************************************************************** raz_n <= config (0); enable <= config (1); sens <= config (2); --***************************************************************** -- lecture des registres --***************************************************************** lecture: process (address, freq, duty, butee_g, butee_d,angle_barre, fin_course_g, fin_course_d, enable, sens) begin case address is when "000" => readdata <= X"0000"&freq ; when "001" => readdata <= X"0000"&duty ; when "010" => readdata <= X"00000"&butee_g; when "011" => readdata <= X"00000"&butee_d; when "100" => readdata <= X"000000"&"000"&fin_course_g&fin_course_d&sens&enable&raz_n; when "101" => readdata <= X"00000"&angle_barre; when others => readdata <= (others => '0'); end case; end process lecture; --********************************************************************** --00000000000000000000000000000000000000000000000000000000000000000000000 --************************************************************** END arch_gestion_verin ;