fpga 单口ram读写操作(block memroy generator)

单口RAM读写测试

硬件资源

IP核:block memory generator

IP核主要设置

  • Interface Type:Native

  • Memory Type:单口ram,双端口ram,真双端口ram

  • Memory Size:按照项目进行设置

  • 对于Primitives output registor 如果勾选会导致时钟落后两个个周期,否则若后一个周期,详见这篇文章

单端口ram接口介绍

  • addra: 读写地址
  • clka:读写时钟
  • dina:写入数据
  • douta:读出数据
  • ena:总使能
  • wea:读写使能(1读使能,0写使能)

模块介绍

  • 测试模块:sim_rw_ram
    • 用于激发时钟与rst_n
  • v_rw_ram
  • 用于实例ram_gen与blk_mem_gen_0两个模块
  • ram_gen
    • 内部激发din,dout,addr
  • blk_mem_gen_0
    • IP核

测试模块(sim_rw_ram)

`timescale 1ns / 1ps

module sim_rw_ram();
    
    reg clk,rst_n;
    
    initial begin
        clk      <= 1;
        rst_n    <= 0;
        #5 rst_n <= 1;
    end
    
    always#5 clk <= ~clk;
    
    v_rw_ram v1(
    .clk(clk),
    .rst_n(rst_n));
    
endmodule

v_rw_ram

`timescale 1ns / 1ps

module v_rw_ram(input clk,
                input rst_n);
    
    wire[31:0] dout,din;
    wire en,we;
    wire [4:0]addr;

    ram_gen v_ram_gen(
    .clk(clk),
    .rst_n(rst_n),
    .dout(dout),
    .en(en),
    .we(we),
    .addr(addr),
    .din(din)
    );
    
    blk_mem_gen_0 ip_ram (
    .clka(clk),    // input wire clka
    .ena(en),      // input wire ena
    .wea(we),      // input wire [0 : 0] wea
    .addra(addr),  // input wire [4 : 0] addra
    .dina(din),    // input wire [31 : 0] dina
    .douta(dout)  // output wire [31 : 0] douta
    );
endmodule

ram_gen

`timescale 1ns / 1ps

module ram_gen(input clk,
               input rst_n,
               input [31:0]dout,
               output en,
               output we,
               output reg [4:0]addr,
               output reg [31:0]din);
    
    assign en = rst_n;
    reg [4:0]cnt;
    assign we = (en == 1&&cnt< 16)?1'b1:1'b0;
    
    always @(posedge clk or negedge rst_n) begin
        if (~rst_n)begin
            cnt <= 0;
        end
        else if (cnt<31) begin
            cnt <= cnt+1;
        end
        else begin
            cnt <= 0;
        end
    end
    
    always @(posedge clk or negedge rst_n) begin
        if (~rst_n)begin
            din <= 0;
        end
        else if (cnt<16)begin
            din <= din+1;
        end
        else begin
            din <= 0;
        end
    end
    always @(posedge clk or negedge rst_n) begin
        if (~rst_n)begin
            addr <= 0;
        end
        else if (cnt<31) begin
            addr <= cnt==15?0:addr+1;
        end
        else begin
            addr <= 0;
        end
    end
    
endmodule

波形显示

  • 整体波形
posted @ 2022-09-03 15:40  JunjueShu  阅读(832)  评论(0编辑  收藏  举报