Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Altera_Forum
Honored Contributor I
769 Views

Simulating the I2C Controller

Hello Everyone,  

 

I am trying to simulate the I2C controller, but have problem as there is no slave to generate the acknowlege back. 

 

Can Anyone tell me how to get around this.  

 

Thanks in advance, and sorry if my question is a bit silly.  

 

thanks in advance.
0 Kudos
8 Replies
Altera_Forum
Honored Contributor I
42 Views

It's not clear if "the I2C controller" refers to a particular example design. But for a full simulation, you should add a slave model to your testbench.

Altera_Forum
Honored Contributor I
42 Views

hello sir, and thanks for your quick response. 

 

Yes I am trying to use the microphone to speak into the de2 board. so i need to create a controller(Master) in VHDL to control the slave(wm8731).  

 

Accordings the latter's data sheet, using a two wire transfer i need to send 3 bytes of codes, starting by: a start condition --> address of the slave --> ack(from the slave) --> register address --> ack (from the slave)--> data control--> ack(from the slave)-->stop condition.  

 

To do this i developed and FSM, that is going generates the proper clk and data signals. 

--> it specifies the start and stop conditions 

--> i created to counters to keep track of teh number of bits and bytes sent, and another one to divide the clk. 

--> to meet the timing requirements I divided cetain states to 2/3 states.  

--> since the sdin is bidirectional and open drain, to output logic one on the line it needs to be set to high impedence as follows 

sdin <= ‘z’ when sdin01 =’1’ else ‘0’ 

 

I think my code is okay, but i don't know how to simulate the acknowledgement from the slave.  

 

Should you be familiar with this protocol, please kindly advice me.  

 

Best Regards.
Altera_Forum
Honored Contributor I
42 Views

Here is the result of my simulation.  

 

thanks
Altera_Forum
Honored Contributor I
42 Views

Of course noone will know, what is causing the shown waveforms without seeing the code. 

 

Apparently you are simulating in Quartus built-in simulator. This means, that a testbench with I2C slave model isn't an option. In this case, driving the SDA line low at a precalculated time and releasing it afterwards is the only way to simulate the slave's ACK response.  

 

Seriously speaking, this kind of simulations demands for a full-featured simulator like Modelsim.
Altera_Forum
Honored Contributor I
42 Views

Definately doable in Modelsim. It can run Testbed scripts, which is where you bring in the entity that needs testing - then simulate whatever response the I2C would give. 

 

In my case I needed some MDIO response at 38527 ns. 

 

 

Here's one I just used myself: 

library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_UNSIGNED.all; entity device_testbench is end; architecture test of device_testbench is component device is PORT ( CLOCK_50 : IN STD_LOGIC; -- 50 MHz KEY : IN STD_LOGIC_VECTOR(3 downto 0); SW : IN STD_LOGIC_VECTOR(17 downto 0); LEDG : OUT STD_LOGIC_VECTOR(7 downto 0); LEDR : OUT STD_LOGIC_VECTOR(17 downto 0); LCD_RS, LCD_EN : OUT STD_LOGIC; LCD_RW : OUT STD_LOGIC; LCD_ON : OUT STD_LOGIC; LCD_DATA : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0); ENET0_RST_N : OUT STD_LOGIC; ENET0_MDC : OUT STD_LOGIC; ENET0_MDIO : INOUT STD_LOGIC; ENET0_RX_CLK : IN STD_LOGIC; ENET0_RX_DV : IN STD_LOGIC; ENET0_RX_ER : IN STD_LOGIC; ENET0_RX_CRS : IN STD_LOGIC; ENET0_RX_COL : IN STD_LOGIC; ENET0_RX_DATA : IN STD_LOGIC_VECTOR(3 DOWNTO 0); ENET0_INT_N : IN STD_LOGIC ); end component; SIGNAL CLOCK_50 : STD_LOGIC; -- 50 MHz SIGNAL KEY : STD_LOGIC_VECTOR(3 downto 0); SIGNAL SW : STD_LOGIC_VECTOR(17 downto 0); SIGNAL LEDG : STD_LOGIC_VECTOR(7 downto 0); SIGNAL LEDR : STD_LOGIC_VECTOR(17 downto 0); SIGNAL LCD_RS, LCD_EN : STD_LOGIC; SIGNAL LCD_RW : STD_LOGIC; SIGNAL LCD_ON : STD_LOGIC; SIGNAL LCD_DATA : STD_LOGIC_VECTOR(7 DOWNTO 0); SIGNAL ENET0_RST_N : STD_LOGIC; SIGNAL ENET0_MDC : STD_LOGIC; SIGNAL ENET0_MDIO : STD_LOGIC; SIGNAL ENET0_RX_CLK : STD_LOGIC; SIGNAL ENET0_RX_DV : STD_LOGIC; SIGNAL ENET0_RX_ER : STD_LOGIC; SIGNAL ENET0_RX_CRS : STD_LOGIC; SIGNAL ENET0_RX_COL : STD_LOGIC; SIGNAL ENET0_RX_DATA : STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL ENET0_INT_N : STD_LOGIC; begin -- instantiate device to be tested device0: device port map(CLOCK_50, KEY, SW, LEDG, LEDR, LCD_RS, LCD_EN, LCD_RW, LCD_ON, LCD_DATA, ENET0_RST_N, ENET0_MDC, ENET0_MDIO, ENET0_RX_CLK, ENET0_RX_DV, ENET0_RX_ER, ENET0_RX_CRS, ENET0_RX_COL, ENET0_RX_DATA, ENET0_INT_N); -- Generate 50 MHz clock, 20 ns cycle process begin CLOCK_50 <= '1'; wait for 10 ns; CLOCK_50 <= '0'; wait for 10 ns; end process; -- Operate switch process begin sw(17) <= '1'; wait for 100 ns; sw(17) <= '0'; wait; end process; -- MDIO Output from PHY chip process begin ENET0_MDIO <= 'Z'; wait for 38527 ns; -- This is where we simulate response from the PHY report ("Faking PHY response"); ENET0_MDIO <= '0'; wait for 400 ns; ENET0_MDIO <= '1'; wait for 400 ns; ENET0_MDIO <= '0'; wait for 400 ns; ENET0_MDIO <= '0'; wait for 400 ns; ENET0_MDIO <= '1'; wait for 400 ns; ENET0_MDIO <= '0'; wait for 400 ns; ENET0_MDIO <= '0'; wait for 400 ns; ENET0_MDIO <= '0'; wait for 400 ns; ENET0_MDIO <= '1'; wait for 400 ns; ENET0_MDIO <= '0'; wait for 400 ns; ENET0_MDIO <= '1'; wait for 400 ns; ENET0_MDIO <= '0'; wait for 400 ns; ENET0_MDIO <= '0'; wait for 400 ns; ENET0_MDIO <= '0'; wait for 400 ns; ENET0_MDIO <= '0'; wait for 400 ns; ENET0_MDIO <= '1'; wait for 400 ns; ENET0_MDIO <= 'Z'; report ("Done faking PHY response"); wait; end process; end;
Altera_Forum
Honored Contributor I
42 Views

Thank you very much for you answers, they were definitly helpful.  

 

I tried driving the sda line low, at the required time, and the controller seems to work fine.  

I am not familiar with testbenches however, and I am running out of time. could you please guide me to a good and quick tutorial. 

 

Thanks you for you help and time.
Altera_Forum
Honored Contributor I
42 Views

Thank you very much, I appreciate you help.  

 

 

Regards.
Reply