Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
19670 Discussions

how do timing constraint for I2c bus

lipingx
Beginner
329 Views

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;




0 Kudos
1 Solution
Nurina
Employee
63 Views

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


View solution in original post

10 Replies
Nurina
Employee
277 Views

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
Beginner
239 Views

No IP was used.

Could you give suggestion based on my attached code?

Both SDA and SCL are handled by system clock.

Nurina
Employee
228 Views

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
Employee
172 Views

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

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


Regards,

Nurina


lipingx
Beginner
165 Views

why use virtual clock?

why not use system clk = 3.125MHz?

Nurina
Employee
130 Views

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
Beginner
107 Views

could you write an example of by case? thanks!

Nurina
Employee
64 Views

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
Employee
34 Views

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


Reply