I2C Verification IP

The I2C Verification IP is a solution for verification of I2C master and slave devices. The provided I2C verification package includes master and slave verification IPs and examples. It will help engineers to quickly create verification environment end test their I2C master and slave devices.

You can download the I2C Verification IP from Downloads page.

Features

  1. Free SystemVerilog source code
  2. Easy integration and usage
  3. Supports I2C bus specification Rev. 03 – 19 June 2007
  4. Supports standard, fast, and fast plus speed modes
  5. Operates as a Master or Slave
  6. Supports multiple slaves
  7. Supports 7 and 10 bit addressing
  8. Fully custom and accurate bus timing
  9. Random delay insertion
  10. Detects not acknowledge errors

Limitations

  1. Does not support Multi-master
  2. Does not support Clock stretching
  3. Does not support General Call address

Installation

  1. Download I2C Verification IP and unpack it.
  2. If you want to run examples
    1. Go to the following folder: <unpack_dir>/i2c_vip/examples/sim
    2. For VCS type the following command: vcs -f file_list.f -sverilog
    3. For QuestaSim6.4 type the following command: qverilog -f file_list.f
  3. Please read the I2C Serial Bus Verification IP User Manual.

Support

If you have any questions please don’t hesitate to contact me.

You can also use article comments below to ask your questions, to report about bugs or to tell some ideas for future improvement. Your comments are always welcome!

17 Responses to “I2C Verification IP”

  • ms1961 says:

    hello
    i am trying to use the verifcation IP with cadence IUS08.20.001 and i am facing some issues:
    i2c_vip/verification_ip/master/i2c_m.sv byte

    - i had to comment lines 489, getting

    dataOutBuff = {};
    |
    ncvlog: *E,ILLPRI (…/i2c_vip/verification_ip/master/i2c_m.sv,489|19): illegal expression primary [4.2(IEEE)].

    - as well as lines 128 and 135

    this.rand_mode(1);
    |
    ncvlog: *E,INAPFS (…/i2c_vip/verification_ip/master/i2c_m.sv,128|17): Inappropriate prefix for the specified built-in task/function.
    this.rand_mode(0);
    |
    ncvlog: *E,INAPFS (/i2c_vip/verification_ip/master/i2c_m.sv,135|17): Inappropriate prefix for the specified built-in task/function.

    After that i got a crash

    ../scripts/cmp_tb i2c_bfm
    file: /prj/vdt/USERS/stanzani/SN/TCR1/design/top/validation/hdl/i2c_vip/verification_ip/master/i2c_m.sv
    ncvlog: *F,INTERR: INTERNAL ERROR
    —————————————————————–
    The tool has encountered an unexpected condition and must exit.
    Contact Cadence Design Systems customer support about this
    problem and provide enough information to help us reproduce it,
    including the logfile that contains this error message.
    TOOL: ncvlog 08.20-p001
    HOSTNAME: bigshow
    OPERATING SYSTEM: Linux 2.6.9-55.ELsmp #1 SMP Fri Apr 20 16:36:54 EDT 2007 x86_64
    MESSAGE: vst_identifier () – bad class, class 581

    Did you tried cadence tools before? unfortunately i cannot switch to VCS since i am in a mixed verilog-vhdl environment

    thanks

  • ms1961 says:

    i had to comment out this.constraint_mode(0) to avoid the crash with ncvlog

    /////////////////////////////////////////////////////////////////////////////
    /*- setRndDelay(): Enable random delays and set random constraints.*/
    /////////////////////////////////////////////////////////////////////////////
    task setRndDelay(int t_max, rndLevel);
    this.t_max = t_max;
    this.rndLevel = rndLevel;
    this.c_timing.constraint_mode(1);
    //MS this.rand_mode(1);
    endtask
    /////////////////////////////////////////////////////////////////////////////
    /*- setTiming(): Set I2C bus custom timing.*/
    /////////////////////////////////////////////////////////////////////////////
    task setTiming(time t_Low, t_High, t_HoldStart, t_SetupStart,
    t_HoldData, t_SetupData, t_Buff, t_Valid, t_SetupStop);
    //MS this.rand_mode(0);
    //MS this.constraint_mode(0);
    this.t_Low = t_Low;
    this.t_High = t_High;
    this.t_HoldStart = t_HoldStart;
    this.t_SetupStart = t_SetupStart;
    this.t_HoldData = t_HoldData;
    this.t_SetupData = t_SetupData;
    this.t_Buff = t_Buff;
    this.t_Valid = t_Valid;
    this.t_SetupStop = t_SetupStop;
    endtask

    i then get the following errors due to the expected type of 2nd param of weiteData

    —————————————————————————–
    this.writeData({6′b011110, address[9:8]}, {address[7:0]}, 0);
    |
    ncvlog: *E,TYCMPAT (…/i2c_vip/verification_ip/master/i2c_m.sv,475|48): formal and actual do not have assignment compatible data types (expecting datatype compatible with ‘queue of bit8′ but found ‘logic’ instead).
    —————————————————————————–
    this.writeData(7′d0, {8′h06});
    |
    ncvlog: *E,TYCMPAT (…./i2c_vip/verification_ip/master/i2c_m.sv,513|25): formal and actual do not have assignment compatible data types (expecting datatype compatible with ‘queue of bit8′ but found ‘packed array’ instead).

    package tbench.I2C_M
    errors: 2, warnings: 0

    hope parsing with ncvlog help to improve you VIP

    regards

  • Tiksan says:

    Hi ms1961,

    Thank you very much for your response.
    Unfortunately I didn’t verify this VIP with ncvlog. I’ll find a way to do that and will fix the problems in the next release.
    If you find any other issues or want to have some new features just let me know.
    Your feedback is appreciated very much.

  • ms1961 says:

    thanks tiksan
    i’ll try to make the IP up and running with ncvolog. do you expect it will work if i comment out the rand_mode(1/0) statements?

    what is of concvern is the other errors (TYCMPAT) which lead me to suppose ncvlog makes a stricter control on types than VCS, maybe hiding a real issue

    i’ll let you know what my findings are (i am a SV starter, though)

    thanks anyway for your great (and oper source) job!

  • Tiksan says:

    Hi ms1961,

    You can comment out all rand_mode(1/0) and constraint_mode(1/0) statements. I expect it will work but you will not be able to stop random timings as you started once.
    Anyway you can do it.
    Change dataOutBuff = {}; statement (line 489) with this one dataOutBuff.delete();
    Comment out this.writeData(7′d0, {8′h06}); (line 512) and this.writeData({6′b011110, address[9:8]}, {address[7:0]}, 0); (line 474) statements. But you will not be able to use 10 bit addressing.
    I hope this will help you.
    If you find any other issues please let me know.
    Best Regards,
    Tiksan

  • ms1961 says:

    Thanks a lot!

  • Tiksan says:

    You are always welcome!

  • ms1961 says:

    one more IUS compile issue i found in the program test

    I2C_m_env i2c_m = new(i2c_ifc_m, “Standart”);
    |
    ncvlog: *E,VARIST (…/rests/RX_ISM_test.v,23|20): Local static variable with initializer requires ’static’ keyword.

    This fix the problem
    static I2C_m_env i2c_m = new(i2c_ifc_m, “Standart”);

    regards

  • Tiksan says:

    Hi ms1961,

    If you split up the handle declaration and object creation into 2 part it should solve the problem. Do it like this:

    I2C_m_env i2c_m;
    i2c_m = new(i2c_ifc_m, “Standart”);

    Could you please do it and let me know about the results.

    Bests regards.

  • ms1961 says:

    hello tiksan
    a happy new year first!

    your suggestion works fine

    a quick question

    what is underneath this conditional compile of the mailbox?

    `ifdef VCS
    typedef mailbox TransMBox;
    `else
    typedef mailbox #(I2C_m_busTrans) TransMBox;
    `endif
    i am trying both with IUS simulator

    i am now trying the VIP at run time and it doesn’t work so i am investigating here

    i feel the issue i am experiencing is in the put stament of the write function

    this.trInBox.put(this.tr);

    which cannot trigger a write transcation

    i’ll keep you posted

  • ms1961 says:

    The unit started working: i was expecting to see the simulation working just after writing

    i2c_m.writeData(address, dataIn, stop);

    but i docovered that i needed to read as well. here is the sample code for write followed by read. is there a smarter way to one-shot access the I2C?

    import I2C_M::*;

    // define a list-queue of bytes!
    typedef bit [7:0] bit8;
    typedef bit8 packet[$];

    program RX_ISM_test (i2c_m_if i2c_ifc_m);
    initial begin
    packet dataIn, expData, dataOut;
    bit8 address;
    int stop, dataSize;
    int trErrors, expError;
    I2C_m_env i2c_m;
    i2c_m = new(i2c_ifc_m, “FastPlus”);
    trErrors= 0;
    expError= 0;
    dataIn.push_back(255); //0xff
    dataIn.push_back(222); // 0xde
    // Start master and slave vip
    // wait (tb.sys_rst_n) i2c_m.startEnv();
    @tb.sys_rst_n;
    i2c_m.startEnv();
    address = 253; // 0xfd device ID
    dataSize = dataIn.size();
    $display (“Slave address is 0x%h”, address);
    $display (“Data Length is %d bytes”, dataIn.size());
    stop = 1;
    // Write data to slave
    i2c_m.writeData(address, dataIn, stop);
    for (int i = 0; i < dataIn.size(); i++) begin
    $display ("Data %d", dataIn[i]);
    end
    #1000;
    // Read data from slave
    i2c_m.readData(address, dataOut, dataSize, stop);
    end
    endprogram

    so far this works fine with IUS simulator

    many thanks

  • Tiksan says:

    Hi ms1961,

    Thank you very much and Happy New Year!
    As the current version of VCS which I’m using doesn’t support the Parameterized Mailboxes, I’m using `ifdef to declare non Parameterized Mailboxes when VCS is used.
    I don’t know does IUS simulator support the Parameterized Mailboxes but if there are not any errors or warnings I guess it supported by IUS.
    It’s always better to use the Parameterized Mailboxes instead of usual.

    Best Regards,
    Tiksan.

  • Tiksan says:

    Hi ms1961,

    The simulation must work just after writing: i2c_m.writeData(address, dataIn, stop);
    The problem is that writeData is non blocking task. When you call this task it puts the command to the buffer and returns without blocking code execution in the Program block.
    #1000; time unit is too less. The simulation is finishing before any timing generation. That’s why you don’t see any activity on the waves.
    Use #5s instead of #1000 and you will see I2C timing on the waves.
    To have a write timing you don’t need to activate read transaction.

    I hope this will help you.
    Best Regards,
    Tiksan.

  • ms1961 says:

    hello tiksan
    quick question, more related to system verilog methodology. what about using multiple test program? i.e. istantiating two programs
    T1_test u_RX_ISM_test(.i2c_ifc_m(i2c_m_if_0));
    T2_test u_DONKEY_test(.i2c_ifc_m(i2c_m_if_0));
    in the exampletest bench?
    my concern is that the every program create a new I2CM object which never get destroyed (so i may run in unefficient memory usage in case of MANY tests)
    thanks much

  • Tiksan says:

    Hi ms1961,

    I don’t think it’s a good idea to instantiate two program blocks in the testbench. All program blocks in you environment will run in parallel and you must to control each program execution. The 2nd should wait until 1st is done. To be honest I never did it and can not help you here.
    If you want to run regression you need to write makefile for it.

    About unefficient memory usage… If you set object to null like this
    object = null;
    SystemVerilog garbage collector will destroy the object.

    Try to find more answers in the http://www.verificationguild.org forum.

    Sorry for miserable help.
    Bests Regards,
    Tiksan.

  • marco stanzani says:

    hello tiksan
    i need a hint from you: how can i make shure a write has been completed over the I2C bus without monitoring a stop condition inside the I2C slave? i actually use a signal in my unit under test which i poll until a stop is detected. is there a way to get the same from your BFM?
    many thanks

  • Tiksan says:

    Hi Marco Stanzani,

    You can use the “waitCommandDone()” instruction in the master Verification IP. This instruction will wait until all instructions in the buffer are finished.
    If you call “waitCommandDone()” after “writeData()” you can be sure that write is completed over the I2C bus.
    I hope it will help you.
    Best Regards,
    Tiksan.

Leave a Reply