Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)

I2C inout simulation

Altera_Forum
Honored Contributor II
4,169 Views

I am using VHDL to try and simulate an I2C master and slave. 

 

My slave has an inout port named i2c_sda. 

 

My master has a in port named i2c_sda_in and a output port named i2c_sda_out. 

 

In actual hardware, this assignment is very easy to do. All that needs to be done is the following: 

 

i2c_sda <= '0' when i2c_sda_out = '0' else 'Z'; 

 

i2c_master_instance : i2c 

port map 

master_sda_in => i2c_sda, 

master_sda_out => i2c_sda_out 

 

This does not work however for simulations. What is the work around for this? I have attempted to "switch" between the assignments using a mux but have not found a working solution yet.  

 

Thanks
0 Kudos
4 Replies
Altera_Forum
Honored Contributor II
3,164 Views

Here is a great example for that w/ a block diagram: http://electronics.stackexchange.com/questions/33144/birectional-i-o-pin-in-verilog 

 

It's in verilog but I'm sure you can translate to VHDL. I used this example before, it works well.
0 Kudos
Altera_Forum
Honored Contributor II
3,164 Views

Hi, 

 

what exactly does not work? I also had difficulties with I2C in the beginning, maybe these hints can help: 

  • assigning '0' and 'Z' for 0 and 1 is correct, go on with that 

  • keep in mind that a real I2C bus has pull-ups, so probably your master has difficulties to detect 'Z' as a logic 1 

  • you can model pull-ups by assigning 'H' to both signals (SDA and SCL) in your test-bench ('H' is a weak logic 1 driver; this will make sure your signal will go to 'H' when all drivers are 'Z'); this trick of course only works if your signals are std_logic, not with std_ulogic 

  • don't put the pull-ups in your synthesis code, it's only supposed to be in the testbench! 

  • in both devices (master and slave) detect a logic 1 by using the statement "if(signal = '1' or signal='H')", instead of just saying "if(signal = '1')"; this will make sure you detect a logic 1 regardless of how you drive it 

  • note that this works both for simulation and for synthesis (the synthesized design can only distinguish 0 and 1 anyway) 

 

 

Hope that helps :) 

 

 

Best regards, 

GooGooCluster
0 Kudos
Altera_Forum
Honored Contributor II
3,163 Views

 

--- Quote Start ---  

  • in both devices (master and slave) detect a logic 1 by using the statement "if(signal = '1' or signal='H')", instead of just saying "if(signal = '1')"; this will make sure you detect a logic 1 regardless of how you drive it 

 

 

--- Quote End ---  

 

Alternatively you can use the To_X01() function from std_logic_1164. I think it makes it easier to read and maintain than having to double all the ifs in the code. This function converts a 'H' to a '1' and a 'L' to a '0'. It is also recognized in the synthesizer so it can be kept in the final code.
0 Kudos
Altera_Forum
Honored Contributor II
3,163 Views

 

--- Quote Start ---  

Alternatively you can use the To_X01() function from std_logic_1164 

--- Quote End ---  

 

Cool, thanks, I did not know the standard libraries provide that function :-) makes my I2C code much more readable.
0 Kudos
Reply