有一段verilog代码我是这样写的:
always @ ( posedge clk_125mhz or negedge rst_n)
begin
if(!rst_n)
begin
tx_data <= {tx_rst,TDATA0};
tx_cnt <= 'b0;
tx_sync_s <= 'b0;
end
else
begin
vivado综合的时候就会报critical warning:
[Netlist 29-358] Reg 'pio_tx_ins0/tx_data_reg[98]' of type 'FDCP' cannot be timed accurately. Hardware behavior may be unpredictable. Use check_timing command for more information. ["E:/vivado_wsp/pio_verify/pio_verify.srcs/sources_1/new/pio_tx.v":174]
参考连接:
https://forums.xilinx.com/t5/Versal-and-UltraScale/FDCP-cannot-be-timed-accurately/m-p/693321#M2854
推断大概是因为跨时钟域的问题(异步时钟问题)导致:
尝试在寄存器定义前增加vivado的命令看看:(* ASYNC_REG = "TRUE", SHIFT_EXTRACT = "NO" *)
再次综合问题还是一样:仔细看警告提示就定位在那一行,分析可以发现,由于rst_n是个异步信号,而在异步信号的驱动下去采样另一个寄存器是有可能导致时序不满足的,就是可能发生亚稳态。这个很好理解,只要对异步信号多打几拍就可以解决这个问题。现在把rst_n信号触发的执行语句改为赋值一个固定初始值,再次综合问题就解决啦。
always @ ( posedge clk_125mhz or negedge rst_n)
begin
if(!rst_n)
begin
tx_data <= 0;//{tx_rst,TDATA0};
tx_cnt <= 'b0;
tx_sync_s <= 'b0;
end
else
begin
总结:
FDCP警告一般就是异步时序问题,往这方面去想应该就对了。
错误情况二:下图中faddr_iod信号,看上去并没有在rst_i赋给一个可变的值,但实际也会触发该错误“netlist29-358”
有always语法可以,只要rst_i上升沿就会触发这个电路(这个触发是异步触发),可以推断上面的代码相当于存在一个隐式的异步赋值,可做如下修改:将代码拆开即可
参考:
http://xilinx.eetrend.com/d6-xilinx/article/2018-02/12599.html