IP核之单端口RAM实验

一、简介  

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

二、实验任务

本节的实验任务是使用Vivado软件生成一个单端口的RAM并对其进行读写操作,然后通过仿真观察波形是否正确,最后通过在线调试工具对实验结果进行验证。如:将RAM设置的深度和宽度分别为32和8进行读写测试。

三、创建单端口RAM IP核

1.波形图

2.在vivado中创建工程

在ip目录找到ram下的 Block Memory

 配置好后点OK

3.编写代码

ram_rw模块

module ram_rw(
    input                    clk,
    input                    rst_n,
                        
    input         [7:0]      ram_rd_data,  //RAM读出的数据
    output  reg              ram_en,       //RAM使能信号,高电平有效
    output                   ram_we,       //RAM写使能 1:写 0:读
    output  reg   [4:0]      ram_addr,     //RAM读写地址
    output  reg   [7:0]      ram_wr_data   //RAM写入的数据 
    );

reg  [5:0] rw_cnt;

assign ram_we = (rw_cnt <= 6'd31 && ram_en == 1'b1) ? 1'b1 : 1'b0;
    
//对RAM使能信后赋值,结束复位后拉高   
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        ram_en <= 1'b0;
    else
        ram_en <= 1'b1;
end   
    
//对re_cnt进行赋值,变化范围0~63
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        rw_cnt <= 6'b0;
    else if(ram_en && rw_cnt == 6'd63)
        rw_cnt <= 6'b0;
    else if(ram_en)
        rw_cnt <= rw_cnt + 6'b1;
    else
        rw_cnt <= 6'b0;
end    

//对RAM地址进行赋值,地址0~31
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        ram_addr <= 5'b0;
    else if(ram_en && ram_addr == 5'd31)
        ram_addr <= 5'b0;
    else if(ram_en)
        ram_addr <= ram_addr + 5'b1;
    else
        ram_addr <= 5'b0;
end     

//对RAM写数据进行赋值,在WE拉高期间地址0~31
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        ram_wr_data <= 8'b0;
    else if(ram_we && ram_wr_data < 8'd31)
        ram_wr_data <= ram_wr_data + 8'b1;
    else
        ram_wr_data <= 8'b0;
end    
    
endmodule
    

顶层模块

module ip_1port_ram(
    input        sys_clk,
    input        sys_rst_n  
    );

wire  [7:0]          ram_rd_data ;
wire                 ram_en;     
wire                 ram_we;    
wire  [4:0]          ram_addr;  
wire  [7:0]          ram_wr_data; 

    
    
ram_rw u_ram_rw(
    .clk               (sys_clk  ),
    .rst_n             (sys_rst_n),
                       
    .ram_rd_data       (ram_rd_data ),
    .ram_en            (ram_en      ),
    .ram_we            (ram_we      ),
    .ram_addr          (ram_addr    ),
    .ram_wr_data       (ram_wr_data )
    );    
    
blk_mem_gen_0 u_blk_mem_gen_0(
  .clka    (sys_clk),   
  .ena     (ram_en),    
  .wea     (ram_we),     
  .addra   (ram_addr),
  .dina    (ram_wr_data),  
  .douta   (ram_rd_data)  
);    
    
    
endmodule

4.仿真验证

编写tb文件

`timescale  1ns/1ns  //仿真单位/仿真精度

module tb_ip_1port_ram();

parameter CLK_PERIOD = 20;

reg        sys_clk;   //周期20ns
reg        sys_rst_n;



initial begin
    sys_clk <= 1'b0;
    sys_rst_n <= 1'b0;   
    #200
    sys_rst_n <= 1'b1;
    
end

always #(CLK_PERIOD/2) sys_clk = ~sys_clk;

ip_1port_ram  u_ip_1port_ram(
    .sys_clk        (sys_clk  ),
    .sys_rst_n      (sys_rst_n)
    );

endmodule

在design sources中添加例化代码和tb文件

运行功能仿真后

5.联合仿真

vivado编译仿真库

在vivado中运行仿真之后自动同步到modulesim中 

输出波形与预计波形相同。

 四、下载验证

生成约束文件。

 

编译出现问题

 原因是顶层模块里没有输出端口定义,所以需要在线调试助手。

在网表里面添加Set Up Debug

保存后重新编译,再连接开发板。

可以看出与预计波形相符。

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值