1/1
i2c project
by cobmetal on Jan 18, 2015 |
cobmetal
Posts: 1 Joined: Jan 9, 2015 Last seen: Jun 9, 2020 |
||
hi ,
i'm now taking a course in VHDL , i have an project which i had to execute , the project is i2c master transmitter , i have already write a code , but im having issues to write the test bench for it . i dont know how to simulate an ACKNOWLEDGE from the slave . my code is : library ieee; use ieee.std_logic_1164.all; use work.Tc_Ctrl_Pack.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all; entity Tr_Ctrl is port ( Sys_Clk : in std_logic; Reset : in std_logic; Start_Tr : in std_logic ; Data_Out : in std_logic_vector ( 7 DOWNTO 0 ) ; DR : in std_logic ; -- Data from the keyboard ended Usedw : in std_logic_vector ( 3 DOWNTO 0 ) ; SCL : out std_logic ; Rd_Rq : buffer std_logic ; SDA : inout std_logic ; Empty : in std_logic ); end Tr_Ctrl; architecture behave of Tr_Ctrl is type state_type is ( Idle , Start , Zeroes , SND_A_D_0 , SND_A_D_1 , ACK_AD_T , ACK_AD , RD_Rq_Strobe ) ; Constant FF_Stream : std_logic_vector := "11111111" ; Constant CNT_100K : integer := 135 ; Signal Start_Strobe : std_logic ; Signal ACK : std_logic ; Signal Wr_En : std_logic ; Signal SCL_CLK_100K : std_logic ; signal Smpl_Start_Tr : std_logic := '1'; Signal Not_Smpl_Start_Tr : std_logic ; Signal Rd_Rq_Out : std_logic ; SIgnal Not_Rd_Rq_Out : std_logic ; SIgnal Rd_Req_Flag : std_logic := '0' ; Signal To_SDA : std_logic ; Signal state : state_type ; Signal B_Cnt : integer range 0 to 7 ; Signal C_Tick : integer range 0 TO CNT_100K ; Signal AD_Flag : std_logic := '1' ; Begin Start_Strobe Tr_Ctrl : Process ( SCL_CLK_100K , Reset ) variable ADR : std_logic_vector ( 7 DOWNTO 0 ) ; Begin if ( Reset = '1' ) then -- Idle Mode Wr_En To_SDA SCL state elsif ( SCL_CLK_100K'event and SCL_CLK_100K = '1' ) then Smpl_Start_Tr Not_Smpl_Start_Tr Case state is When Idle => -- Idle Wr_En SCL To_SDA if DR = '1' and Start_Strobe = '1' then state else state end if ; When Start => --Start SCL To_SDA state When Zeroes => SCL To_SDA state When RD_Rq_Strobe => -- Send request to fifo to read data Rd_Req_Flag B_Cnt state When SND_A_D_0 => Rd_Req_Flag SCL if AD_Flag = '1' then ADR(7) := Data_Out(6) ; ADR(6) := Data_Out(5) ; ADR(5) := Data_Out(4) ; ADR(4) := Data_Out(3) ; ADR(3) := Data_Out(2) ; ADR(2) := Data_Out(1) ; ADR(1) := Data_Out(0) ; ADR(0) := '0' ; To_SDA state else if empty /= '1' then To_SDA else To_SDA end if ; state end if ; When SND_A_D_1 => SCL if AD_Flag = '1' then if B_Cnt B_Cnt state else B_Cnt AD_Flag state end if ; else if B_Cnt B_Cnt state else B_Cnt state end if ; end if ; ---------------------------------------------------------------------- --When SND_A_D_0 => -- -- Rd_Req_Flag -- SCL -- if empty /= '1' then -- To_SDA -- else To_SDA -- end if ; -- state -- -- When SND_A_D_1 => -- SCL -- if B_Cnt -- B_Cnt -- state -- else B_Cnt -- state -- end if ; ---------------------------------------------------------------------- When ACK_AD_T => --Temporrary Acknowledge state SCL To_SDA state When ACK_AD => -- Wait for Acknowledge Wr_En SCL if ACK = '1' then state elsif ( ACK = '0' AND empty /= '1' ) then Wr_En state elsif ( ACK = '0' AND empty = '1' ) then Wr_En B_Cnt state end if ; end case ; end if ; end Process ; Process ( Sys_Clk ) begin if SYS_Clk'event and SYS_Clk = '1' then Rd_Rq_Out Not_Rd_Rq_Out Rd_Rq end if ; end process ; SCL_CLOCK : Process Begin Wait Until Sys_Clk'event and Sys_Clk = '1' ; if C_Tick C_Tick else C_Tick end if ; if C_Tick SCL_CLK_100K else SCL_CLK_100K end if ; End Process ; -------------Bidirectional Control------------------------- SDA ACK ----------------------------------------------------------- End behave ; at first it looks like its ok , it send the address , but then i dont know how to simulate the ACK , for the test . this is my TEST_BENCH: library ieee; use ieee.std_logic_1164.all; entity Tr_Ctrl_TB is end; architecture simple_test of Tr_Ctrl_TB is ---------------DUT Component Declaration-------------------- component Tr_Ctrl is port ( Sys_Clk : in std_logic; Reset : in std_logic; Start_Tr : in std_logic ; Data_Out : in std_logic_vector ( 7 DOWNTO 0 ) ; DR : inout std_logic ; Usedw : in std_logic_vector ( 3 DOWNTO 0 ) ; SCL : out std_logic ; Rd_Rq : out std_logic ; SDA : INOUT std_logic ; Empty : in std_logic ); end component; Signal S_Sys_Clk : std_logic := '1' ; Signal S_Reset : std_logic ; Signal S_Start_Tr : std_logic ; Signal S_Data_Out : std_logic_vector ( 7 DOWNTO 0 ) ; Signal S_DR : std_logic ; Signal S_SCL : std_logic ; Signal S_Rd_Rq : std_logic ; Signal S_SDA : std_logic ; Signal S_Run : std_logic:= '1' ; Signal S_Empty : std_logic ; Signal S_Usedw : std_logic_vector ( 3 DOWNTO 0 ) ; Constant Clk_Period :time := 37 ns; Begin -----------------DUT instatiation---------------------------- DUT : Tr_Ctrl port map ( Sys_Clk => S_Sys_Clk , Reset => S_Reset , Start_Tr => S_Start_Tr , Data_Out => S_Data_Out , DR => S_DR , SCL => S_SCL , Rd_Rq => S_Rd_Rq , SDA => S_SDA , Usedw => S_Usedw , Empty => S_Empty ) ; ---------------Signal's Waves Creation------------------------ S_Reset S_Run S_Start_Tr S_DR S_Empty S_Data_Out "00011000" after 330 us , "10001000" after 420 us ; CLK_GNR: PROCESS begin While S_Run = '1' loop S_Sys_Clk wait for Clk_Period; end loop; S_Sys_Clk wait; end process; end simple_test; thank you in advance . |
1/1