用Verilog实现一个同步FIFO,深度16,数据位宽8bit

module syn_fifo(
    input clk,
    input rst_n,
    input [7:0] din,
    input wr_en,
    input rd_en,
    output [7:0] dout,
    output full,
    output empty
    );
    
    reg wr_en_r;
    reg rd_en_r;
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n) wr_en_r <= 0;
        else wr_en_r <= wr_en;
    end
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n) rd_en_r <= 0;
        else rd_en_r <= rd_en;
    end    
    reg [3:0] status_cnt;
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n) status_cnt <= 0;
        else if(wr_en_r && !rd_en && status_cnt != 4'd15 )
            status_cnt <= status_cnt + 1'b1;
        else if(rd_en_r && !wr_en && status_cnt != 0 )
            status_cnt <= status_cnt - 1'b1;
         else status_cnt <= status_cnt;
    end
    wire full_r1;
    reg full_r2;
    assign full_r1 = (status_cnt == 15)?1'b1:1'b0;
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n) full_r2 <= 0;
        else full_r2 <= full_r1;
    end
    assign full = full_r1 && full_r2;    
        
    wire empty_r1;
    reg empty_r2;
    assign empty_r1 = (status_cnt == 0)?1'b1:1'b0;
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n) empty_r2 <= 1;
        else empty_r2 <= empty_r1;
    end
    assign empty = empty_r1 && empty_r2;
            
    reg [3:0] wr_cnt;
    reg [3:0] rd_cnt;
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n) wr_cnt <= 0;
        else if (wr_en && !full)begin
            if(wr_cnt < 15) wr_cnt <= wr_cnt + 1'b1;
            else wr_cnt <= 0;
        end
        else wr_cnt <= wr_cnt;
    end   
    
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n) rd_cnt <= 0;
        else if (rd_en && !empty)begin
            if(rd_cnt < 15) rd_cnt <= rd_cnt + 1'b1;
            else rd_cnt <= 0;
        end
        else rd_cnt <= rd_cnt;
    end
//write    
    reg [7:0] DATA [15:0];
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n) begin
            DATA[0] <= 0;
            DATA[1] <= 0;
            DATA[2] <= 0;
            DATA[3] <= 0;
            DATA[4] <= 0;
            DATA[5] <= 0;
            DATA[6] <= 0;
            DATA[7] <= 0;
            DATA[8] <= 0;
            DATA[9] <= 0;
            DATA[10] <= 0;
            DATA[11] <= 0;
            DATA[12] <= 0;
            DATA[13] <= 0;
            DATA[14] <= 0;
            DATA[15] <= 0;
        end
        else if(wr_en && !full)
            DATA[wr_cnt] <= din;
    end
//READ
    reg [7:0] data_r;
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n) data_r <= 0;
        else if(rd_en_r && !empty)
            data_r <= DATA[rd_cnt];
//        else data_r <= 0;
        else data_r <= data_r;
    end
    assign dout = data_r;
endmodule

你可能感兴趣的:(用Verilog实现一个同步FIFO,深度16,数据位宽8bit)