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

📄 fifo.v

📁 异步FIFO的实现
💻 V
字号:



`define  WIDTH     32           // Width of the FIFO.
`define  DEPTH     8            // Depth of the FIFO.
`define  DWIDTH    3            // Counter Width of the FIFO 2 to power
                                 // FCWIDTH = FDEPTH.

module FIFO
(
    //INPUTS
    clk,
    rst_n,
    wr_en,
    rd_en,
    data_in,
    
    //OUTPUTS
    data_out,
    almost_full,
    full,
    almost_empty,
    empty
);

input                       clk;
input                       rst_n;
input                       wr_en;
input                       rd_en;
input   [(`WIDTH-1):0]      data_in;

output                      almost_full;
output                      full;
output                      almost_empty;
output                      empty;
output  [(`WIDTH-1):0]      data_out;

reg                         almost_full;
reg                         full;   
reg                         almost_empty;
reg                         empty;

reg     [(`DWIDTH):0]     cnt;
reg     [(`DWIDTH-1):0]     rd_ptr;
reg     [(`DWIDTH-1):0]     wr_ptr;

wire    [(`DWIDTH-1):0]     rd_ptr_g;
wire    [(`DWIDTH-1):0]     wr_ptr_g;

B2G U1_B2G(
          .in(rd_ptr),  
          .out(rd_ptr_g)  
);

B2G U2_B2G(
          .in(wr_ptr),  
          .out(wr_ptr_g)  
);



FIFO_MEM U_FIFO_MEM(
                    .clk(clk),
                    .wr_en(wr_en),
                    .wr_addr(wr_ptr_g),
                    .rd_addr(rd_ptr_g),
                    .data_in(data_in),
                    .data_out(data_out)                    
);

always @(posedge clk or negedge rst_n)
begin
    if(rst_n==1'b0)
        begin
            wr_ptr<=1'b0;
        end
    else begin
        if(wr_en==1'b1 && full==1'b0)
            begin
                wr_ptr<=wr_ptr+1'b1;
            end
         end
end



always @(posedge clk or negedge rst_n)
begin
    if(rst_n==1'b0)
        begin
            rd_ptr<=1'b0;
        end
    else begin
        if(empty==1'b0 && rd_en==1'b1)
            begin
                rd_ptr<=rd_ptr+1'b1;
            end
        end
end
    

always @(posedge clk or negedge rst_n)
begin
    if(rst_n==1'b0)
        begin
            cnt<=3'b0;
        end
    else begin
        if(wr_en==1'b1 && rd_en==1'b0 && full==1'b0)
            begin
                cnt<=cnt+1'b1;
            end
        else if(wr_en==1'b0 && rd_en==1'b1 && empty==1'b0)
            begin
                cnt<=cnt-1'b1;
            end
        end
end

               
always @(posedge clk or negedge rst_n)
begin
    if(rst_n==1'b0)
        begin
            almost_full<=1'b0;
        end
    else begin
        if((full==1'b1 && rd_en==1'b1 && wr_en==1'b0)||
        (wr_en==1'b1 && cnt==(`DEPTH-2) &&rd_en==1'b0))
            begin
                almost_full<=1'b1;
            end
        else
            begin
                almost_full<=1'b0;
            end
         end
end
           
always @(posedge clk or negedge rst_n)
begin
    if(rst_n==1'b0)
        begin
            full<=1'b0;
        end
    else if(almost_full==1'b1 && wr_en==1'b1 && rd_en==1'b0)
        begin
            full<=1'b1;
        end
    else 
        begin
            full<=1'b0;
        end 
end
        
always @(posedge clk or negedge rst_n)
begin
    if(rst_n==1'b0)
        begin
            almost_empty<=1'b0;
        end
    else if((empty==1'b1 && wr_en==1'b1 && rd_en==1'b0)||
            cnt==2 && wr_en==1'b0 && rd_en==1'b1)
        begin
            almost_empty<=1'b1;
        end
    else
        begin
            almost_empty<=1'b0;
        end
end

always @(posedge clk or negedge rst_n)
begin
    if(rst_n==1'b0)
        begin
            empty<=1'b0;
        end
    else if(almost_empty==1'b1 && wr_en==1'b0 && rd_en==1'b1)
        begin
            empty<=1'b1;
        end
    else
        begin   
            empty<=1'b0;
        end
end
endmodule



module FIFO_MEM
(
    //Inputs
    clk,
    wr_en,
    rd_addr,
    wr_addr,
    data_in,
    //Outputs
    data_out
);

input                       clk;
input                       wr_en;
input   [(`DWIDTH-1):0]     rd_addr;
input   [(`DWIDTH-1):0]     wr_addr;
input   [(`WIDTH-1):0]      data_in;

output  [(`WIDTH-1):0]      data_out;

reg     [(`WIDTH-1):0]      FIFO [(`DEPTH-1):0];

assign data_out = FIFO[rd_addr];

always @(posedge clk)
begin
    if(wr_en==1'b1)
        begin
            FIFO[wr_addr]<=data_in;
        end
end
endmodule




module B2G
(
        in,
        out
);
input   [(`DWIDTH-1):0]     in;
output  [(`DWIDTH-1):0]     out;

assign  out[2]=in[2];
assign  out[1]=in[2]^in[1];
assign  out[0]=in[1]^in[0];

endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -