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链接已复制
4 回复数
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.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)
--- 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 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.
