Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.

I2C inout simulation

Altera_Forum
Honored Contributor II
4,181 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,176 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,176 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,175 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,175 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