Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
11 years ago

I2C inout simulation

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 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- 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.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- 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.