I2C controller coreUsing prescale formular ((sysclk/(5 x scl)))-1 with sysclk = 16000 (for 16Mhz) and scl = 100 (for 100kbit target i2c clock) generates 90kbit i2c clock instead of 100kbit.
By the way, the latest documentation v0.9 (in the trunk/doc folder)is dated from 2003, is that the latest? Rev. 0.3 March 6, 2001 Rev. 0.9 July 3, 2003 Might be there a new formular for calculating scl?
Lutz
?ause of this effect is slave_wait signal in i2c_master_bit_ctrl block. Though slave clock stretching is absent, slave_wait is active some periods of system clock.
?ause of this effect is slave_wait signal in i2c_master_bit_ctrl block. Though slave clock stretching is absent, slave_wait is active some periods of system clock.
Did you find a workaround for this? I have a similar but slightly weirder issue: with a 100MHz sysclk, in simulation I get a 90kbit clock just as you did; but with actual implementation I'm only getting a 58kbit clock. The device I'm talking to is an EEPROM rated to 400kbit, so I don't think it's doing any clock stretching.
I ran this in both the Xilinx simulator and in actual HW. It appears to wait for clock sync on every cycle. For me this adds approximately 27 extra dead clock cycles per I2C clock. If I account for this extra dead time when calculating the prescaler, then the clock rate is pretty good. My system clock is 33MHZ. Below is my C code calculation.
fModSMBUS_Period = (1.0f/nDesiredClkRate) - (27.5f/33000000.0f);
nPrescaler = (u_int32_t)(( 33000000.0f / (5.0f * (1/fModSMBUS_Period)))) - 1;Hey guys, just connect to slave_wait ground and it works! Below is my change to i2c_master_bit_ctrl.v:
// slave_wait is asserted when master wants to drive SCL high, but the slave pulls it low
// slave_wait remains asserted until the slave releases SCL
always @(posedge clk or negedge nReset)
if (!nReset) slave_wait <= 1'b0;
// else slave_wait <= (scl_oen & ~dscl_oen & ~sSCL) | (slave_wait & ~sSCL); // Not work!Now the frequency of SCL can be calculated by: f_scl = f_clk/(5 * (clk_cnt + 1)); If frequency of clk is 100MHz, then set prescaler(clk_cnt) to 49 for 400kHz and 199 for 100kHz. I've simulated the code on Vivado2025.2 and get verified. Not only that, after making a few minor adjustments(change reg data bits: 8 to 16bits), I tested this code on the DAC53401, and it worked.