📄 fifo.v
字号:
module fifo_ctrl(
clk_rd,
rd_en,
rd_data,
rempty,
clk_wr,
wr_en,
wr_data,
wfull,
rst_n
);
parameter SIZE = 8; //fifo depth = SIZE-1 and a bit direction flag
parameter WIDTH = 32;
input clk_rd; //read clock
input rd_en ; //read enable
input clk_wr; //write clock
input wr_en ; //write enable
input rst_n; //reset signal
output rempty;
output wfull;
output [WIDTH-1:0] rd_data,wr_data;
//empty
reg [1:0] empty;
//full
reg [1:0] full;
wire rd_allow = rd_en && (!empty[1]); //read allow when read enable and not empty
wire wr_allow = wr_en && (!full[1]); //write allow when write enable and not full
//write addr
reg [SIZE:0] wptr_bin;
wire [SIZE:0] wptr_next_bin;
reg [SIZE:0] wptr_gray;
wire [SIZE:0] wptr_next_gray;
assign wptr_next_bin = wptr_bin + 1'b1;
assign wptr_next_gray = wptr_next_bin ^ {1'b0,wptr_next_bin[SIZE:1]};
always@(posedge clk_wr or negedge rst_n)
if(!rst_n) begin
wptr_bin <= 0;
wptr_gray <= 0;
end
else if(wr_allow) begin
wptr_bin <= wptr_next_bin;
wptr_gray <= wptr_next_gray;
end
//read addr
reg [SIZE:0] rptr_bin;
wire [SIZE:0] rptr_next_bin;
reg [SIZE:0] rptr_gray;
wire [SIZE:0] rptr_next_gray;
assign rptr_next_bin = rptr_bin + 1'b1;
assign rptr_next_gray = rptr_next_bin ^ {1'b0,rptr_next_bin[SIZE:1]};
always@(posedge clk_rd or negedge rst_n)
if(!rst_n) begin
rptr_bin <= 0;
rptr_gray <= 0;
end
else if(rd_allow) begin
rptr_bin <= rptr_next_bin;
rptr_gray <= rptr_next_gray;
end
//direction
reg dir;
wire dir_set = ~((wptr_gray[SIZE] ^ rptr_gray[SIZE-1])&(~(wptr_gray[SIZE-1] ^ rptr_gray[SIZE])));
wire dir_rst = ~((~(wptr_gray[SIZE] ^ rptr_gray[SIZE-1]))&(wptr_gray[SIZE-1] ^ rptr_gray[SIZE]));
always@(negedge rst_n or negedge dir_set or negedge dir_rst)
if(!dir_rst)
dir <= 0;
else if(!dir_set)
dir <= 1'b1;
else
dir <= rst_n;
//compare write address to read address
wire cmp = (wptr_bin == rptr_bin);
//asynchronous empty
wire aempty = ~((!dir) & cmp);
//asynchronous full
wire afull = ~(dir & cmp);
always@(posedge clk_rd or negedge aempty)
if(!aempty)
empty <= 2'b11;
else
empty[1:0] <= {empty[0],~aempty};
always@(posedge clk_wr or negedge afull)
if(!afull)
full[1:0] <= 2'b11;
else
full[1:0] <= {full[0],~afull};
//output
assign rempty = empty[1];
assign wfull = full[1];
//ram ram_inst (
// .clka(clk_rd),
// .clkb(clk_wr),
// .adda(rptr_bin),
// .addb(wptr_bin),
// .dataa(rd_data),
// .datab(wr_data),
// .wr(wr_allow),
// .rd(rd_allow),
// .rst(rst_n)
// );
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -