⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fifo.v

📁 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 + -