关于异步FIFO设计的一些问题,求高手解读
module fifo1(rdata, wfull, rempty, wdata, winc, wclk,wrst_n,rinc, rclk, rrst_n);
parameter DSIZE = 8; parameter ASIZE = 4;
output [DSIZE-1:0] rdata;
output wfull;
output rempty;
input [DSIZE-1:0] wdata;
input winc, wclk, wrst_n;
input rinc, rclk, rrst_n;
reg wfull,rempty;
reg [ASIZE:0] wptr, rptr, wq2_rptr, rq2_wptr, wq1_rptr,rq1_wptr;
reg [ASIZE:0] rbin, wbin;
reg [DSIZE-1:0] mem[0:(1<<ASIZE)-1]; //?这为什么左移一位啊
wire [ASIZE-1:0] waddr, raddr;
wire [ASIZE:0] rgraynext, rbinnext,wgraynext,wbinnext;
wire rempty_val,wfull_val;
//-----------------双口RAM存储器--------------------
assign rdata=mem[raddr];
always@(posedge wclk)
if (winc && !wfull) mem[waddr] <= wdata;
//-------------同步rptr 指针-------------------------
always @(posedge wclk or negedge wrst_n)
if (!wrst_n)
{wq2_rptr,wq1_rptr} <= 0;
else
{wq2_rptr,wq1_rptr} <= {wq1_rptr,rptr};
//-------------同步wptr指针---------------------------
always @(posedge rclk or negedge rrst_n)
if (!rrst_n)
{rq2_wptr,rq1_wptr} <= 0;
else
{rq2_wptr,rq1_wptr} <= {rq1_wptr,wptr};
//-------------rempty产生与raddr产生-------------------
always @(posedge rclk or negedge rrst_n) // GRAYSTYLE2 pointer
begin
if (!rrst_n)
{rbin, rptr} <= 0;
else
{rbin, rptr} <= {rbinnext, rgraynext};
end
// Memory read-address pointer (okay to use binary to address memory)
assign raddr = rbin[ASIZE-1:0];
assign rbinnext = rbin + (rinc & ~rempty);
assign rgraynext = (rbinnext>>1) ^ rbinnext;
// FIFO empty when the next rptr == synchronized wptr or on reset
assign rempty_val = (rgraynext== rq2_wptr);
always @(posedgerclk or negedge rrst_n)
begin
if (!rrst_n)
rempty <= 1'b1; // ?这写错了吧,应该是=0吧
else
rempty <= rempty_val;
end
//---------------wfull产生与waddr产生------------------------------
always @(posedge wclk or negedge wrst_n) // GRAYSTYLE2 pointer
if (!wrst_n)
{wbin, wptr} <= 0;
else
{wbin, wptr} <= {wbinnext, wgraynext};
// Memory write-address pointer (okay to use binary to address memory)
assign waddr = wbin[ASIZE-1:0];
assign wbinnext = wbin + (winc & ~wfull);
assign wgraynext = (wbinnext>>1) ^ wbinnext;
assign wfull_val = (wgraynext=={~wq2_rptr[ASIZE:ASIZE-1],wq2_rptr[ASIZE-2:0]}); //:ASIZE-1] // 一位不行吗?{~wq2_rptr[ASIZE],wq2_rptr[ASIZE-1:0]} 这样行吗?
always @(posedge wclk or negedge wrst_n)
if (!wrst_n)
wfull <= 1'b0;
else
wfull <= wfull_val;
endmodule
1:左移一位是设置ram大小啊!8*8; 2:应该是写错了;
3:一位肯定不行,好好分析一下,我晓得你看的是什么资料了,那个讲得挺好的,你自己研究一下就明白了。
1)请看清楚,是1<<ASIZE,而不是ASIZE<<1。1<<ASIZE-1其实就是2^ASIZE-1。
2)没错啊,reset刚解除时,fifo当然是空的,既然是空的当然rempty=1。
3)一眼看不出来了,lz自己仿一下分析一下吧。
额。楼上说的是对的。
第三个问题:
1.我们要得到是自然码下的 A[SIZE:0] = {~B[SIZE],B[SIZE-1:0]};
但是在 gray 码下就是两位取反,这个自己推导一下就知道了。
谢谢你们啊~受益了
