FPGA之RAM Control

RAM简介:

  RAM 的英文全称是 Random Access Memory,即随机存取存储器, 它可以随时把数据写入任一指定地址的存储单元,也可以随时从任一指定地址中读出数据, 其读写速度是由时钟频率决定的。 RAM 主要用来存放程序及程序执行过程中产生的中间数据、 运算结果等。

RAM分类:

RAM分类

RAM分类

  这里我们使用最简单的单端口RAM:
单口RAM数据线

  • DINA:RAM 端口 A 写数据信号。
  • ADDRA:RAM 端口 A 读写地址信号,对于单端口 RAM 来说,读地址和写地址共用同该地址线。
  • WEA:RAM 端口 A 写使能信号,高电平表示向 RAM 中写入数据,低电平表示从 RAM 中读出数据。
  • ENA:端口 A 的使能信号,高电平表示使能端口 A,低电平表示端口 A 被禁止,禁止后端口 A 上的读写操作都会变成无效。另外 ENA信号是可选的,当取消该使能信号后, RAM 会一直处于有效状态。
  • RSTA:RAM 端口 A 复位信号,可配置成高电平或者低电平复位,该复位信号是一个可选信号。
  • REGCEA: RAM 端口 A 输出寄存器使能信号,当 REGCEA 为高电平时, DOUTA 保持最后一次输出的数据, REGCEA
    同样是一个可选信号。
  • CLKA:RAM 端口 A 的时钟信号
  • DOUTA:RAM 端口 A 读出的数据

本次实验的RAM由Vivado里面自带的BRAM生成而来,位宽为8位,深度为32。

实验代码

ram_rw control代码:

module ram_rw(
    input  wire   clk_50m,
    input  wire   rstn,
    
    output wire       ram_en,         //RAM使能信号
    output wire       ram_wea,        //RAM读写选择
    output reg [4:0] ram_addr,        //RAM读写地址
    output reg [7:0] ram_wr_data,     //RAM写数据
    input  wire [7:0] ram_rd_data     //RAM读数据
    );
    
    reg [5:0]   rw_cnt;       //读写控制计数器
    
    
//控制RAM使能信号
assign ram_en = rstn;

//rw_cnt 计数范围,在0-31向RAM中写入数据,32-63中读出数据
assign ram_wea = ((rw_cnt <= 6'd31)&&(ram_en ==1'b1))? 1'b1 : 1'b0;

//读写控制计数器,计数范围0-63
always@(posedge clk_50m or negedge rstn) begin
    if(!rstn) begin
        rw_cnt <= 6'd0;
    end
    else if(rw_cnt == 6'd63) begin
        rw_cnt <= 6'd0;
    end
    else begin
        rw_cnt <= rw_cnt + 6'd1;
    end
end    

//读写地址
always@(posedge clk_50m or negedge rstn) begin
    if(!rstn) begin
        ram_addr <= 5'd0;
    end
    else if(ram_addr == 5'd31) begin
        ram_addr <= 5'd0;
    end
    else begin
        ram_addr <= ram_addr + 5'd1;
    end
end

//产生写入的数据
always@(posedge clk_50m or negedge rstn) begin
    if(!rstn) begin
        ram_wr_data <= 8'd63;
    end
    else if(rw_cnt < 6'd31) begin
        ram_wr_data <= ram_wr_data - 8'd1;
    end
    else begin
        ram_wr_data <= 8'd63;
    end
end

endmodule

ram_top代码:

module ip_ram(
    input  wire   clk_50m,
    input  wire   rstn
    );

    wire       ram_en;         //RAM使能信号
    wire       ram_wea;        //RAM读写选择
    wire [4:0] ram_addr;       //RAM读写地址
    wire [7:0] ram_wr_data;    //RAM写数据
    wire [7:0] ram_rd_data;    //RAM读数据    

//ram contral
    ram_rw
    u_ram_rw (
    .clk_50m        (clk_50m),
    .rstn           (rstn),    
    .ram_en         (ram_en),         //RAM使能信号
    .ram_wea        (ram_wea),        //RAM读写选择
    .ram_addr       (ram_addr),       //RAM读写地址
    .ram_wr_data    (ram_wr_data),    //RAM写数据
    .ram_rd_data    (ram_rd_data)     //RAM读数据
    );

//例化生成的RAM
    blk_mem_gen_0 
    u_blk_mem_gen_0 (
    .clka    (clk_50m),     // input wire clka
    .ena     (ram_en),      // input wire ena
    .wea     (ram_wea),     // input wire [0 : 0] wea
    .addra   (ram_addr),    // input wire [4 : 0] addra
    .dina    (ram_wr_data), // input wire [7 : 0] dina
    .douta   (ram_rd_data)  // output wire [7 : 0] douta
);      
    
endmodule

Testbench验证代码:

`timescale 1ns / 1ps

module tb_ram();

reg sys_clock;
reg sys_rstn;

always #10 sys_clock = ~sys_clock;

initial begin
    sys_clock = 1'b0;
    sys_rstn = 1'b0;
    #500
    sys_rstn = 1'b1;
end 

    ip_ram
    u_ip_ram(
    .clk_50m    (sys_clock),
    .rstn       (sys_rstn)
    );
    
endmodule

仿真波形:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值