参考了两篇文章
(12条消息) Vivado综合属性系列之一 ASYNC_REG_知识充实人生的博客-CSDN博客
VIVADO中ASYNC_REG指令 - 知乎 (zhihu.com)
一、属性简介
1、ASYNC_REG属性一般用于跨时钟域的数据同步上,该属性指定:寄存器可以接受异步数据或者该寄存器是一个位于同步链上的同步寄存器。
2、ASYNEC_REG的值为布尔型,即只能为TRUE或FALSE,默认值为FALSE,即默认所有寄存器都是同步的。
3、代码文件使用模板: (* ASYNC_REG="true" *) reg sync_regs;
XDC使用模板:set_property ASYNC_REG TRUE [get_cells sync_regs]
4、在仿真过程中,当发生时序违例时,寄存器默认行为会输出X或不定态,从而进可能在多个路径上传输不定态。ASYNC_REG能够使得在发生时许违例时输出上次已知值。
5、在附加了ASYNCREG属性后,在综合的过程中将不会优化该寄存器及其周边逻辑。
6、在附加了ASYNCREG属性后,同时也影响optimization,place&routing以提高MTBF(mean time between failure)。在布局时,将会确保同步链上的寄存器摆放尽可能接近一最大化MTBF,直接相连的带有该属性的寄存器将会直接放进单个SLICE/CLB(如果寄存器同时带有ASYNC_REG和IOB属性,IOB将优先于ASYNC_REG,寄存器将会被存放至ILOGIC block)。
二、示例
2.1 工程说明
设计工程中有三个寄存器reg1,reg2,Q。reg2和Q具有相同的时钟。reg1和reg2时钟来源不同。reg1的输出到reg2,reg2输出到Q,即reg1->reg2->Q,对reg2和Q设置ASYNC_REG。
2.2 工程代码
module async_reg(src_clk,des_clk,ce,d,Q);
input src_clk, des_clk,ce,d;
output Q;
reg reg1; //ASYNC_REG的值默认为false
(*ASYNC_REG="true"*)reg Q,reg2; //true表示寄存器 Q和reg2是同一个时钟控制的寄存器
always@(posedge src_clk)
begin
if(!ce)
reg1<=0;
else
reg1<=d;
end
always@(posedge des_clk)
begin
if(!ce)
reg2<=0;
else
reg2<=reg1;
end
always@(posedge des_clk)
begin
if(!ce)
Q<=0;
else
Q<=reg2;
end
endmodule
2.3 生效确认
在TCL console中使用tcl命令验证属性是否标记,执行如下两条命令
set register [get_cells -hierarchical -filter "REF_NAME==FDRE"] //获取所有的寄存器
get_property ASYNC_REG $register //获取具有属性ASYNC_REG的寄存器,
结果如下图,
第一条命令执行后得到三个寄存器Q_reg reg1_reg reg2_reg,
第二条命令执行后可知只有第1、3个寄存器Q_reg,reg2_reg具有属性ASYNC_REG,符合设计要求。
三、电路
1、RTL电路 两者一模一样
2、综合后电路 两者有差异
加了(*ASYNC_REG="true"*)。在综合的过程中将不会优化该寄存器及其周边逻辑。
不加(*ASYNC_REG="true"*)。
3、实现后的电路
①三个寄存器都不加(*ASYNC_REG="true"*),则三个寄存器分别放在不同的SLICE
② (*ASYNC_REG="true"*)reg Q,reg2; 有两个寄存器加了后,则它们放在同一个SLICE,另外的那个寄存器放在独自一个SLICE。