Forum Discussion

lipingx's avatar
lipingx
Icon for Occasional Contributor rankOccasional Contributor
3 years ago
Solved

how do timing constraint for I2c bus

In my design, I used system clk = 3.125MHz to realize I2c SCL,SDA 200K i2c bus.

I used counter in the verilog, so both SCL and SDA are treated as data line.

Then, how to do timing contraint?

assign eeprom_scl = (eeprom_current_state == EEPROM_STATE_I2C_STAR && stsp_timer[7:0] < 8'd12)? 1'bz :
(eeprom_current_state == EEPROM_STATE_I2C_STAR && stsp_timer[7:0] > 8'd11)? 1'b0 :
(eeprom_current_state == EEPROM_STATE_I2C_SLAW && data_timer[3:0] < 4'd4 )? 1'b0 :
(eeprom_current_state == EEPROM_STATE_I2C_SLAW && data_timer[3:0] < 4'd12)? 1'bz :
(eeprom_current_state == EEPROM_STATE_I2C_SLAW && data_timer[3:0] > 4'd11)? 1'b0 :
(eeprom_current_state == EEPROM_STATE_I2C_ACK0 && ackx_timer[7:0] < 8'd4 )? 1'b0 :
(eeprom_current_state == EEPROM_STATE_I2C_ACK0 && ackx_timer[7:0] < 8'd12)? 1'bz :
(eeprom_current_state == EEPROM_STATE_I2C_ACK0 && ackx_timer[7:0] > 8'd11)? 1'b0 :
(eeprom_current_state == EEPROM_STATE_I2C_REGR && data_timer[3:0] < 4'd4 )? 1'b0 :
(eeprom_current_state == EEPROM_STATE_I2C_REGR && data_timer[3:0] < 4'd12)? 1'bz :
(eeprom_current_state == EEPROM_STATE_I2C_REGR && data_timer[3:0] > 4'd11)? 1'b0 :
(eeprom_current_state == EEPROM_STATE_I2C_ACK1 && ackx_timer[7:0] < 8'd4 )? 1'b0 :
(eeprom_current_state == EEPROM_STATE_I2C_ACK1 && ackx_timer[7:0] < 8'd12)? 1'bz :
(eeprom_current_state == EEPROM_STATE_I2C_ACK1 && ackx_timer[7:0] > 8'd11)? 1'b0 :
(eeprom_current_state == EEPROM_STATE_I2C_DATW && data_timer[3:0] < 4'd4 )? 1'b0 :
(eeprom_current_state == EEPROM_STATE_I2C_DATW && data_timer[3:0] < 4'd12)? 1'bz :
(eeprom_current_state == EEPROM_STATE_I2C_DATW && data_timer[3:0] > 4'd11)? 1'b0 :
(eeprom_current_state == EEPROM_STATE_I2C_ACK2 && ackx_timer[7:0] < 8'd4 )? 1'b0 :
(eeprom_current_state == EEPROM_STATE_I2C_ACK2 && ackx_timer[7:0] < 8'd12)? 1'bz :
(eeprom_current_state == EEPROM_STATE_I2C_ACK2 && ackx_timer[7:0] > 8'd11)? 1'b0 :
(eeprom_current_state == EEPROM_STATE_I2C_STA2 && stsp_timer[7:0] < 8'd12)? 1'bz :
(eeprom_current_state == EEPROM_STATE_I2C_STA2 && stsp_timer[7:0] > 8'd11)? 1'b0 :
(eeprom_current_state == EEPROM_STATE_I2C_SLAR && data_timer[3:0] < 4'd4 )? 1'b0 :
(eeprom_current_state == EEPROM_STATE_I2C_SLAR && data_timer[3:0] < 4'd12)? 1'bz :
(eeprom_current_state == EEPROM_STATE_I2C_SLAR && data_timer[3:0] > 4'd11)? 1'b0 :
(eeprom_current_state == EEPROM_STATE_I2C_ACK3 && ackx_timer[7:0] < 8'd4 )? 1'b0 :
(eeprom_current_state == EEPROM_STATE_I2C_ACK3 && ackx_timer[7:0] < 8'd12)? 1'bz :
(eeprom_current_state == EEPROM_STATE_I2C_ACK3 && ackx_timer[7:0] > 8'd11)? 1'b0 :
(eeprom_current_state == EEPROM_STATE_I2C_DATR && data_timer[3:0] < 4'd4 )? 1'b0 :
(eeprom_current_state == EEPROM_STATE_I2C_DATR && data_timer[3:0] < 4'd12)? 1'bz :
(eeprom_current_state == EEPROM_STATE_I2C_DATR && data_timer[3:0] > 4'd11)? 1'b0 :
(eeprom_current_state == EEPROM_STATE_I2C_ACK4 && ackx_timer[7:0] < 8'd4 )? 1'b0 :
(eeprom_current_state == EEPROM_STATE_I2C_ACK4 && ackx_timer[7:0] < 8'd12)? 1'bz :
(eeprom_current_state == EEPROM_STATE_I2C_ACK4 && ackx_timer[7:0] > 8'd11)? 1'b0 :
(eeprom_current_state == EEPROM_STATE_I2C_STOP && stsp_timer[7:0] < 8'd4 )? 1'b0 :
(eeprom_current_state == EEPROM_STATE_I2C_STOP && stsp_timer[7:0] > 8'd3 )? 1'bz : 1'bz;


assign eeprom_sda = (eeprom_current_state == EEPROM_STATE_I2C_STAR && stsp_timer[7:0] < 8'd8)? 1'bz :
(eeprom_current_state == EEPROM_STATE_I2C_STAR && stsp_timer[7:0] > 8'd7)? 1'b0 :
(eeprom_current_state == EEPROM_STATE_I2C_SLAW && i2c_send[7] == 1'b1 )? 1'bz :
(eeprom_current_state == EEPROM_STATE_I2C_SLAW && i2c_send[7] == 1'b0 )? 1'b0 :
(eeprom_current_state == EEPROM_STATE_I2C_ACK0 )? 1'bz :
(eeprom_current_state == EEPROM_STATE_I2C_REGR && i2c_send[7] == 1'b1 )? 1'bz :
(eeprom_current_state == EEPROM_STATE_I2C_REGR && i2c_send[7] == 1'b0 )? 1'b0 :
(eeprom_current_state == EEPROM_STATE_I2C_ACK1 )? 1'bz :
(eeprom_current_state == EEPROM_STATE_I2C_DATW && i2c_send[7] == 1'b1 )? 1'bz :
(eeprom_current_state == EEPROM_STATE_I2C_DATW && i2c_send[7] == 1'b0 )? 1'b0 :
(eeprom_current_state == EEPROM_STATE_I2C_ACK2 )? 1'bz :
(eeprom_current_state == EEPROM_STATE_I2C_STA2 && stsp_timer[7:0] < 8'd8)? 1'bz :
(eeprom_current_state == EEPROM_STATE_I2C_STA2 && stsp_timer[7:0] > 8'd7)? 1'b0 :
(eeprom_current_state == EEPROM_STATE_I2C_SLAR && i2c_send[7] == 1'b1 )? 1'bz :
(eeprom_current_state == EEPROM_STATE_I2C_SLAR && i2c_send[7] == 1'b0 )? 1'b0 :
(eeprom_current_state == EEPROM_STATE_I2C_ACK3 )? 1'bz :
(eeprom_current_state == EEPROM_STATE_I2C_DATR && i2c_send[7] == 1'b1 )? 1'bz :
(eeprom_current_state == EEPROM_STATE_I2C_DATR && i2c_send[7] == 1'b0 )? 1'b0 :
(eeprom_current_state == EEPROM_STATE_I2C_ACK4 )? 1'bz :
(eeprom_current_state == EEPROM_STATE_I2C_STOP && stsp_timer[7:0] < 8'd8)? 1'b0 :
(eeprom_current_state == EEPROM_STATE_I2C_STOP && stsp_timer[7:0] > 8'd7)? 1'bz : 1'bz;




  • Hello,


    Sorry for the late response. You may use set_max_delay instead of set_input_delay since the I2C is pretty slow. You may use below constraint, this is the typical values used.


    set_max_delay -from [get_ports {eeprom_scl}] 50

    set_min_delay -from [get_ports {eeprom_scl}] 0

    set_max_delay -from [get_ports {eeprom_sda}] 50

    set_min_delay -from [get_ports {eeprom_sda}] 0



    Regards,

    Nurina


10 Replies

  • Nurina's avatar
    Nurina
    Icon for Regular Contributor rankRegular Contributor

    Hello,


    Are you using any IP for this I2C (e.g. HPS)? If no, you will have to apply timing constraints based on the timing violations reported by Timing Analyzer.


    Regards,

    Nurina


    • lipingx's avatar
      lipingx
      Icon for Occasional Contributor rankOccasional Contributor

      No IP was used.

      Could you give suggestion based on my attached code?

      Both SDA and SCL are handled by system clock.

  • Nurina's avatar
    Nurina
    Icon for Regular Contributor rankRegular Contributor

    Hi,


    I don't think you need to add any constraints, unless Timing Analyzer is reporting unconstrained paths/timing violation.

    Can you check for unconstrained paths & timing violation and share here?


    Regards,

    Nurina



  • Nurina's avatar
    Nurina
    Icon for Regular Contributor rankRegular Contributor

    Hi,


    In this case you just need to add set_input_delay to the eeprom_scl & eeprom_sda ports.

    You also need a virtual clock to describe the eeprom_scl (I'm assuming this is a clock): https://www.intel.com/content/www/us/en/docs/programmable/683243/22-3/creating-virtual-clocks.html


    You may find below documents useful:

    https://www.intel.com/content/www/us/en/docs/programmable/683243/22-3/input-constraints-set-input-delay.html

    https://www.intel.com/content/www/us/en/docs/programmable/683103/21-3/generating-initial-i-o-timing-data-for-fpgas.html


    Regards,

    Nurina


    • lipingx's avatar
      lipingx
      Icon for Occasional Contributor rankOccasional Contributor

      why use virtual clock?

      why not use system clk = 3.125MHz?

  • Nurina's avatar
    Nurina
    Icon for Regular Contributor rankRegular Contributor

    Hi,


    Missed your comment that mention the scl is running on system clock. I thought this scl pin is the clock signal coming from external device.

    You don't need a virtual clock in this case. Just use the system clock.


    Regards,

    Nurina


  • lipingx's avatar
    lipingx
    Icon for Occasional Contributor rankOccasional Contributor

    could you write an example of by case? thanks!

  • Nurina's avatar
    Nurina
    Icon for Regular Contributor rankRegular Contributor

    Hello,


    Sorry for the late response. You may use set_max_delay instead of set_input_delay since the I2C is pretty slow. You may use below constraint, this is the typical values used.


    set_max_delay -from [get_ports {eeprom_scl}] 50

    set_min_delay -from [get_ports {eeprom_scl}] 0

    set_max_delay -from [get_ports {eeprom_sda}] 50

    set_min_delay -from [get_ports {eeprom_sda}] 0



    Regards,

    Nurina


  • Nurina's avatar
    Nurina
    Icon for Regular Contributor rankRegular Contributor

    Hello,


    I’m glad that your question has been addressed, I now transition this thread to community support. If you have a new question, Please login to https://supporttickets.intel.com , view details of the desire request, and post a feed/response within the next 15 days to allow me to continue to support you. After 15 days, this thread will be transitioned to community support. The community users will be able to help you on your follow-up questions.


    p/s: If any answer from community or Intel support are helpful, please feel free to mark as solution, give Kudos and rate 4/5 survey


    Regards,

    Nurina