Bonjour,
J'essaye de faire la transmission SPI qui respecte cette photo:
SPI transmission.png
J'ai fais le composant en utilisant le syntaxe de FSM du cour: je obtiens ca:
tb_emission_spi.png
le code est :
Ayant été bloqué j'ai fais avec la methode plus facile et plus claire (en faisant une seul process) j'obtiens ca :Code:library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity SPI_TX is Port ( data_in : in STD_LOGIC_VECTOR (7 downto 0); spi_start : in STD_LOGIC; rst : in STD_LOGIC; clk : in STD_LOGIC; SPI_CS : out STD_LOGIC; SPI_SCK : out STD_LOGIC; SPI_MOSI : out STD_LOGIC); end SPI_TX; architecture Behavioral of SPI_TX is type T_etat is (idle,bitsdata); signal next_etat, reg_etat : T_etat; signal next_bitcpt, reg_bitcpt : unsigned (2 downto 0); --compte le bit qu'on veut passer en serie signal txdatas_next, txdatas_reg : STD_LOGIC_VECTOR (7 downto 0);-- pour enlever bit par bit et les passer en serie signal cpt_spi : STD_LOGIC ; -- signal pour faire le SPI_CLK signal CS_reg,CS_next : STD_LOGIC ; signal MOSI_reg,MOSI_next : STD_LOGIC ; begin etat_suivant: process(data_in,spi_start,reg_etat,reg_bitcpt,txdatas_reg,CS_reg,MOSI_reg,cpt_spi) begin next_etat <= reg_etat; --SPI_MOSI <= '0'; --SPI_CS <= '1'; next_bitcpt <= reg_bitcpt; txdatas_next <= txdatas_reg; CS_next <= CS_reg; MOSI_next <= MOSI_reg; case reg_etat is when idle => MOSI_next <= '0'; CS_next <= '1'; next_bitcpt <= (others =>'0'); if spi_start ='1' then txdatas_next <= data_in; next_etat <= bitsdata; end if; when bitsdata => CS_next <= '0'; if cpt_spi = '1' then -- if put rising_edge(cpt_spi) it doesn't work MOSI_next <= txdatas_reg(0) ; txdatas_next <= '0' &txdatas_reg(7 downto 1); if reg_bitcpt = "111" then -- if the 8 data bits have been sent next_etat <= idle ; else next_bitcpt <= reg_bitcpt + 1 ; end if; end if; end case; end process etat_suivant; SPI_SCK<=cpt_spi; SPI_CS<=CS_reg; SPI_MOSI<=MOSI_reg; -- Creating SPI_clk (ici c'est le clk /2) compteur: process(clk) begin if rst = '1' then cpt_spi <= '0'; else if rising_edge(clk) then if CS_reg = '0' then if cpt_spi='1' then cpt_spi <='0'; else cpt_spi <= '1'; end if; else --CS_reg=1 cpt_spi <='0'; end if ; end if; end if; end process compteur; registre_etat: process(clk) begin if rising_edge(clk) then if rst = '1' then reg_etat <= idle; reg_bitcpt <= (others =>'0'); txdatas_reg <=(others =>'0') ; CS_reg<='1'; MOSI_reg<='0'; else reg_etat <= next_etat; reg_bitcpt <= next_bitcpt; txdatas_reg <=txdatas_next; CS_reg<=CS_next ; MOSI_reg<=MOSI_next ; end if; end if; end process registre_etat; end Behavioral;
tb_emission_spi_one_process.png
Le code est:
Mes questions comment peut on faire pour corriger les 2 codes pour avoir un resultat similaire au premier photo.Code:library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity SPI_TX is Port ( data_in : in STD_LOGIC_VECTOR (7 downto 0); spi_start : in STD_LOGIC; rst : in STD_LOGIC; clk : in STD_LOGIC; SPI_CS : out STD_LOGIC; SPI_SCK : out STD_LOGIC; SPI_MOSI : out STD_LOGIC); end SPI_TX; architecture Behavioral of SPI_TX is type T_etat is (idle,bitsdata); signal reg_etat : T_etat; signal reg_bitcpt : unsigned (3 downto 0); --compte le bit qu'on veut passer en serie signal txdatas_reg : STD_LOGIC_VECTOR (7 downto 0);-- pour enlever bit par bit et les passer en serie signal cpt_spi: STD_LOGIC ; -- signal pour faire le SPI_CLK signal CS_reg,CS_next : STD_LOGIC ; signal MOSI_reg,MOSI_next : STD_LOGIC ; begin ---------------------------------------------------------------------------------- etat_suivant: process(CLK,rst) begin if rising_edge(CLK) then if rst = '1' then reg_etat <= idle; reg_bitcpt <= (others =>'0'); txdatas_reg <=(others =>'0') ; CS_reg<='1'; MOSI_reg<='0'; else case reg_etat is when idle => MOSI_reg <= '0'; CS_reg <= '1'; reg_bitcpt <= (others =>'0'); if spi_start ='1' then txdatas_reg <= data_in; reg_etat <= bitsdata; end if; when bitsdata => CS_reg <= '0'; if cpt_spi = '0' then --if CS_reg = '0' then MOSI_reg <= txdatas_reg(0) ; txdatas_reg <= '0' &txdatas_reg(7 downto 1); if reg_bitcpt = "1000" then -- if the 8 data bits have been sent reg_etat <= idle ; else reg_bitcpt <= reg_bitcpt + 1 ; end if; --end if; end if; when others => -- il faut TOUJOURS un "when others" car ton "CASE" n'énumère pas forcement tous les as possibles assert (false) report "Unsupported state"severity failure ;-- au cas ou il y aurait un bug qq part cela remonte en simulation end case; end if; end if; end process etat_suivant; SPI_SCK<=cpt_spi; SPI_CS<=CS_reg; SPI_MOSI<=MOSI_reg; ------------------------------------------------------------------------------------ -- Creating SPI_clk (ici c'est le clk /2) compteur: process(clk) begin if rst = '1' then cpt_spi <= '0'; else if rising_edge(clk) then if CS_reg = '0' then if cpt_spi='1' then cpt_spi <='0'; else cpt_spi <= '1'; end if; else --CS_reg=1 cpt_spi <='0'; end if ; end if; end if; end process compteur; end Behavioral;
Merci
-----