FPGA zybo开发 vivado 调用ram ip核

RAM

1、ram三种模式

单端口:一个端口 用于读写 不能同时进行
伪双端口(SDP):两个端口 一个用于读 一个用于写
双端口:两个端口 都可以用于读写
当要同时读写一个地址时 应提前配置读优先/写优先
当然要尽量避免同时访问一个地址
配置成:单端口只读模式 则相当于 ROM(可以调用coe文件提前写入)

2、工程源码、仿真效果

添加ip核并配置:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

ram ip核 数据和地址 以及使能、读写信号的产生(generate the data)

`timescale 1ns / 1ps


module ram_rw(
    input               clk,
    input               rst_n,
    
    output reg          ram_en,//ram enable high level is useful
    output reg          rw, //Determines whether to be in write mode or read mode
    output reg[4:0]     ram_addr,
    output reg [7:0]    ram_wr_data
    );
reg [5:0] rw_cnt; 

// prepare for the read/write mode
always@(posedge clk or negedge rst_n)begin
    if (!rst_n)     
         rw_cnt <= 6'd0;
    else if(rw_cnt==6'd63)
         rw_cnt <= 0;
    else
        rw_cnt <= rw_cnt +6'd1;
end

// rw at high level,the ram is in write mode 
always@(posedge clk or negedge rst_n)begin
    if (!rst_n)  
        rw <= 1'b1; 
    else if(rw_cnt<=6'd31)
        rw <= 1'b1;
    else
         rw <= 1'b0;
 end
              
always@(posedge clk or negedge rst_n)begin
    if (!rst_n)     
         ram_en = 1'b0;
    else            
         ram_en = 1'b1;
end
 
//prepare the data   
always@(posedge clk or negedge rst_n)begin
    if (!rst_n)   
        ram_wr_data <= 8'd0;
    else if((rw_cnt<6'd31)&&ram_en)
        ram_wr_data <= ram_wr_data + 1'b1;
    else
        ram_wr_data <= ram_wr_data;
end

always@(posedge clk or negedge rst_n)begin
    if (!rst_n)  
        ram_addr <= 5'd0;
    else 
        ram_addr <= rw_cnt[4:0];//0-31
    end

endmodule

信号如下:
在这里插入图片描述
对module的例化 类似c语言中的 main.c文件

`timescale 1ns / 1ps

module ip_ram_test(
input sys_clk,
input sys_rst_n
//output [7:0] douta
    );
    
wire ram_en;
wire rw;
wire[4:0] ram_addr;
wire[7:0]ram_wr_data;
wire [7:0] douta;
ram_rw ram_rw_u(
.clk        (sys_clk),       
.rst_n      (sys_rst_n),     
.ram_en     (ram_en),
.rw         (rw),
.ram_addr   (ram_addr),  
.ram_wr_data(ram_wr_data)
);
blk_mem_gen_0 blk_mem_gen_0_u
(
  .clka(sys_clk),    // input wire clka
  .ena(ram_en),      // input wire ena
  .wea(rw),      // input wire [0 : 0] wea read/wirte change
  .addra(ram_addr),  // input wire [4 : 0] addra
  .dina(ram_wr_data),    // input wire [7 : 0] dina
  .douta(douta)  // output wire [7 : 0] douta
);

ila_0 ila_0_u (
.clk(sys_clk), // input wire clk
	
	.probe0(ram_en), // input wire [0:0]  probe0  
	.probe1(rw), // input wire [0:0]  probe1 
	.probe2(ram_addr), // input wire [4:0]  probe2 
	.probe3(ram_wr_data), // input wire [7:0]  probe3 
	.probe4(douta) // input wire [7:0]  probe4
);

endmodule 

添加tb仿真文件

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

//本实验我们只有系统时钟和系统复位这两个输入信号,
//所以仿真文件也只需要编写这两个信号的激励即可。
module tb_ram();
 
//parameter define
parameter CLK_PERIOD = 20; //50MHz系统时钟(一个周期是20ns:1/50MHz=0.02us=20ns)
                            //200MHz系统时钟(一个周期是5ns:1/200MHz=0.005us=5ns)
 
//reg define
reg sys_clk;
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_ram_test u_ip_ram_test(
    .sys_clk      (sys_clk      ),
    .sys_rst_n    (sys_rst_n    )
    );
endmodule

整个工程就算完成
进行仿真:
在这里插入图片描述

3、心得体会

1、由于以前都是利用block_design 进行 也是跟着视频来 对于module、例化、仿真文件这些文件的关系没多想 以下是我的一些理解:
关于module: 类似特别编写一个文件 作为一个函数 供例化使用
关于例化: 类似c语言的主函数 其中利用各个编写好的module、ip核等(可以查看上面代码)
关于仿真:最重要的就是提供一个时钟 也是编写一个module 提供一些最底层的节拍(时钟),接着接入例化的module

2、对于ip核的调用 可以看 ip source 的.evo文件 里面提供例化的模板 并且有一些说明 很像stm32hal库开发的库函数说明;(工程开发还是有很多相似之处的)

4、剩余问题

在开发过程本来不想软件仿真 想直接上板测试 所以添加了ila逻辑分析仪 但是上板不出波形
sys_clk没接上还是啥问题 没有找到解决方案(很烦)
下面是约束文件 按理说不应该有问题

create_clock -period 20 [get_ports sys_clk]
set_property IOSTANDARD LVCMOS33 [get_ports {sys_clk}]
set_property PACKAGE_PIN K17 [get_ports {sys_clk}]
set_property IOSTANDARD LVCMOS33 [get_ports {sys_rst_n}]
set_property PACKAGE_PIN K18 [get_ports {sys_rst_n}]

逻辑没问题的话 估计是晶振时钟没有产生 继续学 学到后面向下兼容 估计就能找到这个可恶的问题;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值