专栏前言
本专栏的内容主要是记录本人学习Verilog过程中的一些知识点,刷题网站用的是牛客网
`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) beginif(wenc)RAM_MEM[waddr] <= wdata;
end always @(posedge rclk) beginif(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
);localparam ADDR_WIDTH = $clog2(DEPTH) ;reg [ADDR_WIDTH:0] waddr, raddr ; always @ (posedge clk or negedge rst_n) begin if (~rst_n) waddr <= 'b0 ; else if (winc && ~wfull) waddr <= waddr + 1'b1 ; // 当写使能且未写满时 写地址+1else waddr <= waddr ; endalways @ (posedge clk or negedge rst_n) begin if (~rst_n) raddr <= 'b0 ; else if (rinc && ~rempty) raddr <= raddr + 1'b1 ; // 当读使能且未空时 读地址+1else raddr <= raddr ; endalways @ (posedge clk or negedge rst_n) begin if (~rst_n) begin wfull <= 'b0 ; rempty <= 'b0 ; endelse begin wfull <= (raddr == {~waddr[ADDR_WIDTH], waddr[ADDR_WIDTH - 1:0]}) ; //第n位相反 后n-1位相同rempty <= (raddr == waddr) ; // 读地址追上写地址endenddual_port_RAM #(.DEPTH(DEPTH), .WIDTH(WIDTH)) dual_port_RAM_U0 (.wclk(clk),.wenc(winc),.waddr(waddr[ADDR_WIDTH - 1:0]),.wdata(wdata),.rclk(clk),.renc(rinc),.raddr(raddr[ADDR_WIDTH - 1:0]),.rdata(rdata));endmodule
参考资料:FPGA数字IC笔试面试013—同步FIFO详解及代码分享_牛客网