关于FIFO memory buffer模块的设计
FIFO memory
`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: chensimin // // Create Date: 2018/10/26 13:28:35 // Design Name: // Module Name: fifomem // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// `include "block_define.v" module fifomem #( parameter DATASIZE = 8, //Memory data word width parameter ADDRSIZE = 4 ) //Number of mem address bits depth = 16 ( input [DATASIZE-1 : 0] wdata, input [ADDRSIZE-1 : 0] waddr, input wclken, input wfull, input wclk, input [ADDRSIZE-1 : 0] raddr, output [DATASIZE-1 : 0] rdata ); //------------------------------------------------------------------------ `ifdef VENDORRAM // instantiation of a vendor's dual-port RAM blk_mem_gen_0 mem ( .clka(wclk), // input wire clka .ena(wclken), // input wire ena .wea(~wfull), // input wire [0 : 0] wea .addra(waddr), // input wire [3 : 0] addra .dina(wdata), // input wire [7 : 0] dina .clkb(wclk), // input wire clkb .addrb(raddr), // input wire [3 : 0] addrb .doutb(rdata) // output wire [7 : 0] doutb ); `else // RTL Verilog memory model localparam DEPTH = 1<<ADDRSIZE; reg [DATASIZE-1 : 0] mem[0 : DEPTH-1]; assign rdata = mem[raddr]; always @(posedge wclk) if(wclken && !wfull) mem[waddr] <= wdata; `endif endmodule
IP 核配置
测试及仿真:
`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: chensimin // // Create Date: 2018/10/26 16:34:06 // Design Name: // Module Name: testbench // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module testbench #( parameter DATASIZE = 8, //Memory data word width parameter ADDRSIZE = 4 ) //Number of mem address bits depth = 16 ( input wire clk, input wire rst, output [DATASIZE-1 : 0] rdata ); //------------------------------------------------------------ reg [4:0] i = 0; reg [DATASIZE-1 : 0] wdata = 0; reg [ADDRSIZE-1 : 0] waddr = 0; reg wclken = 0; reg [ADDRSIZE-1 : 0] raddr = 0; always @(posedge clk or posedge rst) begin if(rst) begin i <= 0; wdata <= 0; waddr <= 0; wclken <= 1'b0; raddr <= 0; end else begin case(i) 0: begin wdata <= 0; waddr <= 0; i <= i + 1 ; wclken <= 1'b1; raddr <= 0; end 1: begin wdata <= 1; waddr <= 1; i <= i + 1 ; wclken <= 1'b1; raddr <= 0; end 2: begin wdata <= 2; waddr <= 2; i <= i + 1 ; wclken <= 1'b1; raddr <= 0; end 3: begin wdata <= 3; waddr <= 3; i <= i + 1 ; wclken <= 1'b1; raddr <= 0; end 4: begin wdata <= 4; waddr <= 4; i <= i + 1 ; wclken <= 1'b1; raddr <= 1; end 5: begin wdata <= 5; waddr <= 5; i <= i + 1 ; wclken <= 1'b1; raddr <= 2; end 6: begin wdata <= 6; waddr <= 6; i <= i + 1 ; wclken <= 1'b1; raddr <= 3; end 7: begin wdata <= 7; waddr <= 7; i <= i + 1 ; wclken <= 1'b1; raddr <= 4; end 8: begin wdata <= 8; waddr <= 8; i <= i + 1 ; wclken <= 1'b1; raddr <= 5; end 9: begin wdata <= 9; waddr <= 9; i <= i + 1 ; wclken <= 1'b1; raddr <= 6; end 10: begin wdata <= 10; waddr <= 10; i <= i + 1 ; wclken <= 1'b1; raddr <= 7; end 11: begin wdata <= 11; waddr <= 11; i <= i + 1 ; wclken <= 1'b1; raddr <= 8; end 12: begin wdata <= 12; waddr <= 12; i <= i + 1 ; wclken <= 1'b1; raddr <= 9; end 13: begin wdata <= 13; waddr <= 13; i <= i + 1 ; wclken <= 1'b1; raddr <= 10; end 14: begin wdata <= 14; waddr <= 14; i <= i + 1 ; wclken <= 1'b1; raddr <= 11; end 15: begin wdata <= 15; waddr <= 15; i <= i + 1 ; wclken <= 1'b1; raddr <= 12; end 16: begin wdata <= 0; waddr <= 0; i <= i + 1 ; wclken <= 1'b0; raddr <= 13; end 17: begin wdata <= 0; waddr <= 0; i <= i + 1 ; wclken <= 1'b0; raddr <= 14; end 18: begin wdata <= 0; waddr <= 0; i <= i ; wclken <= 1'b0; raddr <= 15; end endcase end end //------------------------------------------------------------ wire wfull ; assign wfull = 0; //------------------------------------------------------------ wire [DATASIZE-1 : 0] rdata; fifomem #( .DATASIZE (8), //Memory data word width .ADDRSIZE (4)) //Number of mem address bits depth = 16 U0 ( .wdata(wdata), .waddr(waddr), .wclken(wclken), .wfull(wfull), .wclk(clk), .raddr(raddr), .rdata(rdata) ); endmodule /* add_force {/testbench/clk} -radix hex {1 0ns} {0 50000ps} -repeat_every 100000ps add_force {/testbench/rst} -radix hex {1 0ns} {0 200ns} */
仿真波形图:
从RAM读出来的数据会比给定的地址晚两拍。
使用仿顺序操作来写testbench也是极好的。