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