题解 | #同步FIFO#
同步FIFO
https://www.nowcoder.com/practice/e5e86054a0ce4355b9dfc08238f25f5f
`timescale 1ns/1ns /**********************************RAM************************************/ module dual_port_RAM #(parameter DEPTH = 16, parameter WIDTH = 8)( input wclk ,input wenc ,input [$clog2(DEPTH)-1:0] waddr ,input [WIDTH-1:0] wdata ,input rclk ,input renc ,input [$clog2(DEPTH)-1:0] raddr ,output reg [WIDTH-1:0] rdata ); reg [WIDTH-1:0] RAM_MEM [0:DEPTH-1]; always @(posedge wclk) begin if(wenc) RAM_MEM[waddr] <= wdata; end always @(posedge rclk) begin if(renc) rdata <= RAM_MEM[raddr]; end endmodule /**********************************SFIFO************************************/ module sfifo#( parameter WIDTH = 8, parameter DEPTH = 16 )( input clk , input rst_n , input winc , input rinc , input [WIDTH-1:0] wdata , output reg wfull , output reg rempty , output wire [WIDTH-1:0] rdata ); //gne addr reg [$clog2(DEPTH):0] raddr_ext, waddr_ext; wire [$clog2(DEPTH)-1:0] raddr, waddr; always@(posedge clk or negedge rst_n) begin if(!rst_n) raddr_ext<=0; else if(rinc && !rempty) raddr_ext<=raddr_ext+1; else raddr_ext<=raddr_ext; end always@(posedge clk or negedge rst_n) begin if(!rst_n) waddr_ext<=0; else if(winc && !wfull) waddr_ext<=waddr_ext+1; else waddr_ext<=waddr_ext; end assign raddr=raddr_ext[$clog2(DEPTH)-1:0]; assign waddr=waddr_ext[$clog2(DEPTH)-1:0]; // //gen full and empty always@(posedge clk or negedge rst_n) begin if(!rst_n) wfull<=0; else if(raddr_ext[$clog2(DEPTH)]^waddr_ext[$clog2(DEPTH)] && raddr==waddr ) wfull<=1; else wfull<=0; end always@(posedge clk or negedge rst_n) begin if(!rst_n) rempty<=0; else if(raddr_ext==waddr_ext) rempty<=1; else rempty<=0; end // //instation dual_port_RAM #( .WIDTH(WIDTH), .DEPTH(DEPTH) ) u ( .wclk(clk), .wenc(winc && !wfull), .waddr(waddr), .wdata(wdata), .rclk(clk), .renc(rinc && !rempty), .raddr(raddr), .rdata(rdata) ); endmodule