异步fifo设计及时序约束设置
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一、前言
跨时钟域的同步处理,使用异步FIFO是常用的方式之一,对于异步FIFO的设计,网上的大部分资料来源于《Simulation and Synthesis Techniques for Asynchronous FIFO Design》一文
其异步FIFO的结构如下图所示
本文不是介绍上图描述的设计。
我从基本的数字电路时序开始,介绍异步FIFO的相关问题。
最后介绍如何用时序约束保证设计的正确性
二、数字电路时序
对于数字电路来讲,我们的信号在时钟边沿发生变化,Dat1信号是一种理想情况,而Dat2是实际情况,其特点是
一、相对时钟边沿有延时
二、信号变化有一段时间(电平转换时间),在这段时间就是亚稳态
在亚稳态期间进行数据采样,不能获得稳定的值。
数字电路中经过时序约束,在T1产生的信号,在T2一定稳定(否则就是不满足时序),所以对于只有一个时钟的数字电路来说,它在T1和T2都能获得稳定的信号(T1时刻的值为0、T2时刻的值为1)
三、跨时钟域时序问题
对于异步时钟而言(相位不同),对于CLK1产生的信号,CLK2有可能在任意时刻进行数据采样
在FIFO的设计中,将会产生2种信号,一种是数据本身(用Data表示),另外一种是指示数据是否有效(用valid表示),注意(valid不一定是一个比特的寄存器,可以是由FIFO中的读写指针产生而来,例如fifo的full或empty状态)
异步FIFO的问题在于,如果CLK2在时钟T2进行采样,那么有可能得到valid有效,而数据无效的情况。
这样在CLK2采样取得的设计就是错误的数据。
四、处理异步FIFO的valid和data(理论基础)
我们假设valid为低电平表示没有数据,高电平为有数据,解决的办法就是,当CLK对valid进行采样时,即使valid处于亚稳态期间,数据信号也是稳定的
如上图所以,在T1时刻进行上升沿采样,虽然valid是一个亚稳态状态,但是此时Data 是一个稳定的值,如果在T1时刻采样的valid为1,那么可以得到稳定的Data信号,如果在T1时刻采样的valid为0,那么控制逻辑认为在T1无法获得数据,从而在下一个时钟获取
注意:T2时刻是在下降沿进行采样,而此时的Data信号也是稳定的
五、如何实现
为了让valid和Data处于上面的状态,我们可以对valid进行延时处理,即使用时钟对其进行采样,必须使用2个寄存器依次采样,才能保证至少有一个时钟的延时
valid1是CLK2对valid进行采样产生的,如果采样的时机不好,那么valid1相对valid只有一点点延时,valid2是CLK2对valid1的采样,这样valid2相对于valid至少有CLK2一个周期的延时,也就满足了第二节的条件。
所以在《Simulation and Synthesis Techniques for Asynchronous FIFO Design》的设计中,将写时钟域写指针使用2级寄存器同步到读时钟域,然后使用该同步后的写指针和读时钟域读指针产生valid状态,(备注:写时钟域写指针发生改变就和上图中valid发生变化是一个道理,代表数据写入,使用读时钟域同步后想当于产生valid2信号,相信不难理解),写指针是多比特数据,无法在亚稳态获取数据,必须使用一次只有一个比特变化的格雷码,然后再使用格雷码产生valid状态(即FIFO中的full或者empty),
同样的道理,将读时钟域的读指针使用2级寄存器同步写时钟域。
其目的是判断数据是否已经被读取。
这就是《Simulation and Synthesis Techniques for Asynchronous FIFO Design》中的理论支持,其它的逻辑就是格雷码的设计、FIFO的状态产生等逻辑,本文不再进行详细说明。
六、问题产生
《Simulation and Synthesis Techniques for Asynchronous FIFO Design》的设计中是否能绝对保证异步FIFO的正确性?
如上图所示,在T1时刻CLK1产生了valid和Data信号,它是满足时序要求的,在T2时刻是稳定的,只是valid比Data先稳定。
我们对valid进行采样延时,产生的valid1是可以出现上面的状态,但此时valid1和Data都是亚稳态,不满足关系
需要说明的是
1、上述出现的概率较小,取决数字后端布局
2、如果进行采样的同步时钟比CLK1慢(即写时钟快于读时钟),不会出现问题
3、后端布局后,还可以进行多时钟时序仿真,也可以发现问题
七、改进设计
在异步FIFO设计中,我们必须要保证valid和data的相对关系。
我们可以通过下面的逻辑设计再加上时序约束来保证这一点。
一、逻辑设计
控制逻辑,在T1时刻准备好数据,在T2时刻产生valid
二、时序约束
将读写2个时钟设置为同一个时钟,频率设置使用最高频率的那个时钟。
(可以单独将这个FIFO做块,或者和高频率的那个模块一起做块)
经过上面的逻辑设计和时序约束,对于要采样valid和data的异步时钟而言:
1、由于是采用最高频率的时钟进行约束,即使采样时钟频率低,也能满足时序要求
2、通过逻辑设计和时序约束,对于采样时钟而言,valid和Data也一定是满足相对关系
八、参考代码
module Mfifo(
input rst_n,
input wr_clk,
input wr_req,
input[7:0]wr_data,
output wr_ready,
input rd_clk,
input rd_req,
output[7:0]rd_data,
output rd_ready
);
reg[7:0]fifo_r[3:0];
reg[1:0]wp_r;
reg wp_valid_r;
reg[3:0]wp_flag_r;
reg[1:0]rp_r;
reg rp_valid_r;
reg[3:0]rp_flag_r;
//=================================================================== //WR CLK
//=================================================================== always@(posedge wr_clk)begin
if(~rst_n)
wp_r<=2'b00;
else if(wr_req&wr_ready)
wp_r<=wp_r+2'b01;
end
always@(posedge wr_clk)begin
if(wr_req&wr_ready)
fifo_r[wp_r]<=wr_data;
end
always@(posedge wr_clk)begin
if(~rst_n)
wp_valid_r<=1'b0;
else if(wr_req&wr_ready)
wp_valid_r<=1'b1;
else if(wp_valid_r)
wp_valid_r<=1'b0;
end
always@(posedge wr_clk)begin
if(~rst_n)
wp_flag_r<=4'b0000;
else if(wp_valid_r)
wp_flag_r[wp_r-2'b01]<=~wp_flag_r[wp_r-2'b01];
end
//=================================================================== //RD CLK
//=================================================================== always@(posedge rd_clk)begin
if(~rst_n)
rp_r<=2'b00;
else if(rd_req&rd_ready)
rp_r<=rp_r+2'b01;
end
always@(posedge rd_clk)begin
if(~rst_n)
rp_valid_r<=1'b0;
else if(rd_req&rd_ready)
rp_valid_r<=1'b1;
else if(rp_valid_r)
rp_valid_r<=1'b0;
end
always@(posedge rd_clk)begin
if(~rst_n)
rp_flag_r<=4'b0000;
else if(rp_valid_r)
rp_flag_r[rp_r-2'b01]<=~rp_flag_r[rp_r-2'b01];
end
//=================================================================== //FIFO STATE
//=================================================================== assign wr_ready=wp_flag_r[wp_r]==rp_flag_r[wp_r];
assign rd_ready=wp_flag_r[rp_r]!=rp_flag_r[rp_r];
assign rd_data=fifo_r[rp_r];
endmodule
九、其它补充
1、异步fifo的主要目的是跨时钟同步,不应该有复杂的控制逻辑和fifo深度,(复杂的控制逻辑可以放在其它地方实现,如果实在需要深度较大fifo来缓冲数据,可以用同步fifo接在异步fifo的输入或输出端,以此达到目的)
2、不管异步FIFO如何设计,一定要做时序仿真(下图是在fpga上的布局后的时序仿真)。