# How to verify a VHDL I2C master?

Once an I2C master has been written, the next step is verification. Provided that a BFM for the slave does not exist, how should one go about doing this? Also seeing how I2C is open collector in nature.

Of course in any I2C transaction, the master would transmit the start condition, address, r/w bit and slave would transfer an ACK and so on and so forth. Is there a "standard" testbench for this? I would expect there to be code with flexibility to create BFM for our slave with some modification and then do self checks to verify if our master is working correctly.

Please don't tell me to use an open source I2C master. The purpose of this question is to understand how to do this.

• Do you have the NXP/Philips standard document in hand? You could start writing your testbench by simulating all of the scenarios described therein. Also, what is a BFM? – Elliot Alderson May 12 at 11:18
• @ElliotAlderson Bus Functional Model. But that does not apply here as a bus funtional model is normally a behavioral bus master which the mods code is. You would need an I2C protocol analyser here. – Oldfart May 12 at 11:23
• Of course you can't use an open-source I2C master. It has to be open-drain... Basically, start by writing a BFM for the slave. Then a stimulus generator/checker to exercise the master and compare the stimulus with the response. Testbench to wrap all these up will then be simple. – Brian Drummond May 12 at 12:52

You need to start by determining exactly what it is you want to "verify".

Obviously, I2C is a simple protocol, and writing a monitor that verifies that the protocol is not being violated (including timing measurements, if desired1) is a relatively straightforward matter.

But anything beyond that — including whether the master is accessing the correct addresses, writing the correct data, responding correctly to the data it reads and handling any exceptions that occur — is all very much application-dependent, and generally requires a BFM for the specific slave device(s) in your system.

For example, I once needed to verify a system that included a soft-core CPU, in which I needed to allow it to execute the code that initialized a TI C1101 radio chip (through its SPI interface) in order to get to the message-processing code. I wrote a bare-bones ad-hoc BFM for the C1101 slave interface that implemented just enough functionality to accomplish that.

1 The VHDL function now (returning type time) gives the current simulation time. You can use this to directly measure the time between important events. For example, you keep one variable that gets set to now on every data edge, and when you get a clock edge, the difference between now and that variable is the setup time. A similar technique measures hold time. Here is some sample code relating to now.

• Do you have a reference that I can use to check how to check the timings in the testbench? How do I model open drain output in a VHDL testbench? – quantum231 May 12 at 21:36
• For the first, see the footnote above. But again, I2C is a synchronous protocol -- the actual timing requirements will depend on the specific devices you're using. For the second, see Weak 'H', Pullup on inout bidirectional signal in simulation – Dave Tweed May 12 at 22:40
• NOW is an impure function without any parameters found in package std.standard. A variable is an object, a function call is an expression. NOW returns the current value of simulation time when called. The return value is of a subtype of TIME. The scope of a variable declared in the conceptual kernel process holding the current simulation time wouldn't extend to other processes. The type of the value is necessary to use the value as a parameter, operand or prefix in an expression. – user8352 May 12 at 23:57

I think you searching for this (old question of mine):

Is there a general I2C command to see if a device is still present on the bus?

The solution at this answer shows you how to check the device exists before doing/sending commands/data.