📄 fifo_status.v
字号:
module fifo_status(rd_clk, wr_clk, reset, pn_lock, wr_addr_srst, rd_addr, wr_addr, wr, rd,
full, empty, almost_full, half_full, almost_empty, pn_lock_rd_clk);
input rd_clk, wr_clk, reset, rd, wr, pn_lock, wr_addr_srst;
output [10:0] rd_addr, wr_addr;
reg [10:0] rd_addr, wr_addr;
output full, empty, almost_full, half_full, almost_empty;
reg full, empty, almost_full, half_full, almost_empty;
output pn_lock_rd_clk;
reg pn_lock_rd_clk_p0, pn_lock_rd_clk;
reg [3:0] wr_dtct;
reg [10:0] flag_wr_addr;
reg [10:0] flag_cnt;
//_____________________________________________________________________________________
// Cross clock domains for pn_lock from wr_clk to rd_clk
//_____________________________________________________________________________________
always @ (posedge rd_clk or posedge reset)
begin
if (reset)
begin
pn_lock_rd_clk_p0 <= 0;
pn_lock_rd_clk <= 0;
end
else
begin
pn_lock_rd_clk_p0 <= pn_lock; // gaurds agains metastability
pn_lock_rd_clk <= pn_lock_rd_clk_p0;
end
end // always @ (posedge clk or posedge reset)
//_____________________________________________________________________________________
// Create read address (counter)
//_____________________________________________________________________________________
always @ (posedge rd_clk or posedge reset)
begin: create_read_addr
if (reset)
rd_addr <= 0;
else
begin
if (rd & pn_lock_rd_clk)
rd_addr <= rd_addr + 1;
else if (~pn_lock_rd_clk)
rd_addr <= 0;
end // else: !if(reset)
end // block: create_read_addr
//_____________________________________________________________________________________
// Create write address (counter)
//_____________________________________________________________________________________
always @ (posedge wr_clk or posedge reset)
begin: create_wr_addr
if (reset)
wr_addr <= 0;
else
if (wr_addr_srst)// synchronous reset for wr_addr when pn_lock is lost
wr_addr <= 0;
else if (wr)
wr_addr <= wr_addr + 1;
end // block: create_wr_addr
// write detection circuit synchronized to faster rd_clk
always @ (posedge rd_clk or posedge reset)
begin: write_detect
if (reset)
begin
wr_dtct <= 0;
flag_wr_addr <= 0;
end
else
begin
if (wr_dtct[0]) // synchronous reset. This will work for rd_clk upto 4x faster than wr_clk
begin
wr_dtct <= 0;
flag_wr_addr <= wr_addr;// cross domains with stable wr_addr
end
else
wr_dtct <= {wr, wr_dtct[3:1]};
end // else: !if(reset)
end // block: write_detect
// Create counter used to create full/empty signals
always @ (posedge rd_clk or posedge reset)
begin: create_flag_count
if (reset)
flag_cnt <= 0;
else
begin
// default value
flag_cnt <= 0;
if (pn_lock_rd_clk) // create the flag_cnt if this channel has a lock, otherwise assume data is empty
flag_cnt <= flag_wr_addr - rd_addr;
end // else: !if(reset)
end // block: create_flag_count
// Create full/empty flag signals
always @ (posedge rd_clk or posedge reset)
begin: create_full_empty_flags
if (reset)
begin
full <= 0;
almost_full <= 0;
half_full <= 0;
empty <= 0;
almost_empty <= 0;
end // if (reset)
else
begin
// set default values (infers gates rather than latches or clk enables)
full <= 0;
almost_full <= 0;
half_full <= 0;
empty <= 0;
almost_empty <= 0;
if (flag_cnt == 0)
empty <= 1;
if (flag_cnt >= 1024)
half_full <= 1;
if (flag_cnt >= 2040)
almost_full <= 1;
if (flag_cnt == 2047)
full <= 1;
if (flag_cnt <= 8)
almost_empty <= 1;
end // else: !if(reset)
end // block: create_full_empty_flags
endmodule // fifo_status
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -