热度 1| ||
今天作i2c模块master模式下的后仿真,明明是之前大佬们写好的已经量产的芯片代码,但是却出现了setup time violation,将网表对应的波形抓出来分析下,确实是setup time时间不满足,这就有点奇怪了。分析了一下,发现是i2c_reg模块中ahb_rdata_reg_[23:16]_违例了。将AHB总线信号抓出来查看波形,发现时序违例的点AHB并没有发起对i2c模块的读操作,通过查看源码发现i2c_reg模块中ahb_rdata的逻辑是这样描述的:
always@(posedge hclk or negedge rst_n)
if(!rst_n)
ahb_rdata <= 32'h0;
else
case(ahb_addr[7:2])
6'd00:ahb_rdata <= #DLY regs_0x00 ;
6'd01:ahb_rdata <= #DLY regs_0x04 ;
6'd02:ahb_rdata <= #DLY regs_0x08 ;
...
endcase
ahb读数据的逻辑是只要ahb_addr地址满足译码的要求就更新ahb_rdata的数据,发现时序违例点的ahb_addr地址是6‘d00,也就是说和regs_0x00这个变量有关,继续追踪发现信号ahb_rdata[23:16]违例来自于i2c_rdata,i2c_rdata来自于i2c_shift_buff,i2c_shift_buff的时钟域是i2c协议子模块i2c_master的时钟clk_8m,该时钟与i2c_reg的时钟hclk是异步的,也就是说clk_8m时钟域的数据未经过同步就直接由另一个时钟采样,这样真的不会有问题吗?
后面仔细分析了一下,i2c_shift_buff是master模块的移位寄存器,如果其数据还在发生变化则说明i2c还处在工作中,而本身电路的设计就是不允许软件在i2c还未完成传输前就去读取i2c_shift_buff的数据的,所以会在寄存器中定义pengding位,该位拉高则表示i2c完成了传输,随后还需要软件清除该pending,所以此处的数据虽然是跨时钟域传输,但在软件上的操作流程保证了其数据传输的稳定与安全。至于后仿真中出现的时序违例,在那些违例的时间点根本就没有ahb的读请求,所以总线上的数据是什么就无关紧要了。