异步FIFO Verilog
异步FIFO:
整体的电路及逻辑设计:
讲解链接:异步FIFO及其他跨时钟域信号传输方法讲解.
异步FIFO主要涉及的知识:
空、将空、满、将满信号的判断;
格雷码作为异步传输地址指针的使用;
两级D触发器同步异步信号;
FIFO深度、宽度、吞吐量的选择和计算。
具体地文字分析在CDC篇详细说吧,这里存代码。
写数据代码:
module write_data #(
parameter FIFO_WIDTH = 4'd8,
parameter FIFO_DEEP = 8'd64,
parameter GAP_DEEP = 3'd5
)(
input w_clk, //写时钟
input w_rst_n,
input w_en, //外部输入的写使能信号
input [FIFO_WIDTH:0] rptr2_wclk, //同步到写时钟下的读指针
output wfull, //写满信号
output wclken, //输出给RAM的允许写信号
output reg wfull_almost, //将满信号
output [FIFO_WIDTH:0] wptr, //输出的写指针
output [FIFO_WIDTH-1:0] waddr //输出的写地址
);
reg [FIFO_WIDTH:0] waddr_tmp;
reg [FIFO_WIDTH:0] w_gap;
wire [FIFO_WIDTH:0] rptr_bin;
assign wclken = w_en &(!wfull);//输出给RAM的允许写信号
//写地址、写指针产生
always @(posedge w_clk or negedge w_rst_n)begin
if(!w_rst_n)
waddr_tmp <= 9'd0;
else if(wclken)
waddr_tmp <= waddr_tmp + 1'd1;
else
waddr_tmp <= waddr_tmp;
end
assign waddr = waddr_tmp[7:0]; //写地址产生
assign wptr = waddr_tmp^(waddr_tmp>>1'd1);//写指针转格雷码
//同步到写时钟下的读指针(格雷码) 转二进制
assign rptr_bin[8]=rptr2_wclk[8];
assign rptr_bin[7]=rptr_bin[8]^rptr2_wclk[7];
assign rptr_bin[6]=rptr_bin[7]^rptr2_wclk[6];
assign rptr_bin[5]=rptr_bin[6]^rptr2_wclk[5];
assign rptr_bin[4]=rptr_bin[5]^rptr2_wclk[4];
assign rptr_bin[3]=rptr_bin[4]^rptr2_wclk[3];
assign rptr_bin[2]=rptr_bin[3]^rptr2_wclk[2];
assign rptr_bin[1]=rptr_bin[2]^rptr2_wclk[1];
assign rptr_bin[0]=rptr_bin[1]^rptr2_wclk[0];
//写指针与读指针之间的间隔
always @(*)begin
if(rptr_bin[8] == waddr_tmp[8])
w_gap = FIFO_DEEP + rptr_bin[7:0] - waddr_tmp[7:0];
else
w_gap = rptr_bin[7:0] - waddr_tmp[7:0];
end
//将满信号
always @(posedge w_clk or negedge w_rst_n)begin
if(!w_rst_n)
wfull_almost = 1'd0;
else if(w_gap < GAP_DEEP)
wfull_almost = 1'd1;
else
wfull_almost = 1'd0;
end
//满信号
assign wfull = (!w_gap)||