题解 | #同步FIFO#
同步FIFO
https://www.nowcoder.com/practice/3ece2bed6f044ceebd172a7bf5cfb416
`timescale 1ns/1ns /**********************************RAM************************************/ module dual_port_RAM #(parameter DEPTH = 16, parameter WIDTH = 8)( input wclk ,input wenc ,input [$clog2(DEPTH)-1:0] waddr //深度对2取对数,得到地址的位宽。 ,input [WIDTH-1:0] wdata //数据写入 ,input rclk ,input renc ,input [$clog2(DEPTH)-1:0] raddr //深度对2取对数,得到地址的位宽。 ,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 [WIDTH-1:0] rdata ); reg [WIDTH-1:0]RAM[DEPTH-1:0]; reg [DEPTH-1:0]w_ptr,r_ptr; reg [DEPTH:0]NUM; reg [WIDTH-1:0] rdata; always@(posedge clk or negedge rst_n) begin if(!rst_n) wfull<=0; else if(NUM==DEPTH) wfull<=1; else wfull<=0; end always@(posedge clk or negedge rst_n) begin if(!rst_n) rempty<=0; else if(NUM==0) rempty<=1; else rempty<=0; end always@(posedge clk or negedge rst_n) begin if(!rst_n) begin NUM<=0; w_ptr<=0; end else if(winc&(!wfull)) begin NUM<=NUM+1; w_ptr<=w_ptr+1; RAM[w_ptr]<=wdata; end end always@(posedge clk or negedge rst_n) begin if(!rst_n) begin NUM<=0; r_ptr<=0; end else if(rinc&(!rempty)) begin NUM<=NUM-1; r_ptr<=r_ptr+1; rdata<=RAM[r_ptr]; end end endmodule