OpenCores
no use no use 1/1 no use no use
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 .
no use no use 1/1 no use no use
© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.