题解 | 同步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 ); reg [$clog2(DEPTH):0] waddr; reg [$clog2(DEPTH):0] raddr; always @(posedge clk or negedge rst_n)begin if(!rst_n)begin waddr <= 'd0; end else if(winc && !wfull)begin waddr <= waddr + 1; end end always @(posedge clk or negedge rst_n)begin if(!rst_n)begin raddr <= 'd0; end else if(rinc && !rempty)begin raddr <= raddr + 1; end end always @(posedge clk or negedge rst_n)begin if(!rst_n)begin wfull <= 'd0; end else if((waddr[$clog2(DEPTH)] != raddr[$clog2(DEPTH)]) && (waddr[$clog2(DEPTH)-1:0] == raddr[$clog2(DEPTH)-1:0]))begin wfull <= 1; end else begin wfull <= 0; end end always @(posedge clk or negedge rst_n)begin if(!rst_n)begin rempty <= 'd0; end else if((waddr[$clog2(DEPTH):0] == raddr[$clog2(DEPTH):0]))begin rempty <= 1; end else begin rempty <= 0; end end dual_port_RAM #( .WIDTH (WIDTH), .DEPTH (DEPTH) ) dual_port_RAM_u( .wclk (clk), .wenc (winc), .waddr (waddr[$clog2(DEPTH)-1:0]), .wdata (wdata), .rclk (clk), .renc (rinc), .raddr (raddr[$clog2(DEPTH)-1:0]), .rdata (rdata) ); endmodule