起初是在一个寄存器模块中对一个寄存器值回读时一直不正确,把寄存器和读信号、读地址、读数据都抓到stp,可以看到寄存器一直是1,但读数据一直是0,确认读地址和读信号都没有问题,其他寄存器的读数据都正确,编译过几次,其中有一个版本的寄存器偶发可以读正确,百思不得其解,实际像这种情况大概率就是时序的问题了。
经大佬指点,此寄存器模块有跨时钟域信号(ddr3_status),时序约束文件中未该跨时钟域信号做处理造成的,解决过程如下:
工程编译完后看时序报告中有时序违例情况
Report timing后可看到具体是违例路径
原因是从ddr3_ctrl_inst|emif_0_phy_clk_l_0、ddr3_ctrl_inst|emif_0_phy_clk_0、bf_pll_inst|iopll_0|outclk2时钟域的信号跨到了xcvr_link_inst|pcc_phy_inst|xcvr_native_a10_0|rx_clkout时钟域,综合工具为了满足这些信号的时序情况一直在布线,布出来的走线指不定绕多远,导致后面这个avm_06_addr这个信号在同一个时钟域的时序都不满足了
对于ddr3_status这样常态的状态信号,也需要在sdc中将它们之间的跨时钟域约束成false path;
修改后的sdc文件要把它放到最下面,以免sdc中定义的时钟名后续调用的其他sdc文件(像ddr3 ip会自带sdc文件)定义的时钟名覆盖,导致时序约束未起效的情况。
还有stp里用的时钟域也要严格注意,被抓的信号最好要用对应的时钟触发,否则时序违例也会影响其他信号
时序约束真的很重要!