格雷码设计异步FIFO,读快写慢,读时钟会出现漏采样的情况,漏采的数据留在FIFO中,导致满信号间断分布。
源文件:
module dual_clk_fifo
#(parameter DATESIZE = 8,
parameter ADDRSIZE = 4,
parameter ALMOST_GAP = 3
)
(
input [DATESIZE-1:0] wdata,
input winc, wclk, wrst_n,
input rinc, rclk, rrst_n,
output wire [DATESIZE-1:0] rdata,
output reg wfull,
output reg rempty,
output reg almost_full,
output reg almost_empty
);
wire [ADDRSIZE-1:0] waddr, raddr;
reg [ADDRSIZE:0] wptr, rptr;
wire rempty_val,wfull_val;
//--------------------------------
// RTL Verilog memory model
//--------------------------------
localparam DEPTH = 1<<ADDRSIZE;
reg [DATESIZE-1:0] mem [0:DEPTH-1];
assign rdata = mem[raddr];
always @(posedge wclk)
if (winc && !wfull) mem[waddr] <= wdata;
//--------------------------------
// read-domain to write-domain synchronizer
//--------------------------------
reg [ADDRSIZE:0] wq1_rptr,wq2_rptr;
always @(posedge wclk or negedge wrst_n)
if (!wrst_n) {wq2_rptr,wq1_rptr} <= 0;
else {wq2_rptr,wq1_rptr} <= {wq1_rptr,rptr};
//--------------------------------
// Write-domain to read-domain synchronizer
//--------------------------------
reg [ADDRSIZE:0] rq1_wptr,rq2_wptr;
always @(posedge rclk or negedge rrst_n)
if (!rrst_n) {rq2_wptr,rq1_wptr} <= 0;
else {rq2_wptr,rq1_wptr} <= {rq1_wptr,wptr};
//--------------------------------
//Read pointer & empty generation log