如何调用IP核?
新建工程后打开IP核搜RAM并双击
下面解释每个选项的含义
对IP核进行命名
选择存储器类型
single:一个地址,只能进行一组读写,不能同时读写
simpel:两个地址,一组读一组写
true:两个地址,每组都可以分别读写
选择位数和深度(有多少个)
存储器深度(Memory Depth)是指存储器中可以存储数据的地址数量,或者说存储器能够存储的数据元素的个数。它是描述存储器容量的一个方面,通常用于说明存储器的大小。
深度需要根据芯片类型进行计算,在setting中找到自己的芯片型号,看block rams,这个表示有多少个ram
在xlink手册中说明了每个RAM最多36kb,可以划分为32K×1位,16K×2位等
我们是32位即1K×32位,那么一共有1K×50=50K个存储器单元,所以深度最高50×1024=51200
接下来选择写优先和使用使能
有没有勾选 Primitives output Register区别在于给了addr后,多少个时钟出来数据
没有勾选一个时钟后读出,勾选了两个时钟后读取
到这里就可以了,接下来需要写一个顶层的模块ram_top来使用生成的ip核
ram_top包含哪些输入输出呢?
先观察ip的输入输出如下:
可以再ip自动产生的实例化v文件中找
接下来分析每个模块的输入输出类型和位宽,在这个文件中都有写:
改下名称编写ram_top:
module ram_top (
input clk ,
input [15:0] ram_addr ,
input [31:0] ram_wdata,
input ram_wen ,
output [31:0] ram_rdata
);
block_ram block_ram (
.clka (clk ),
.wea (ram_wen ),
.addra(ram_addr ),
.dina (ram_wdata ),
.douta(ram_rdata )
);
endmodule
接下来是重点,需要编写仿真文件来看我们的ram的读写时序具体是怎么样的:
复习一下tb文件的整体格式:
1.命名module
2.重新写一遍输入输出信号,这里主要给信号类型作说明,输入是reg输出是wire
在 Verilog 中的仿真文件中,
reg
通常用于表示存储元素,而wire
通常用于表示组合逻辑的输出或信号连接。这是一种符合硬件描述语言中的建模实践的方式。
3.把信号连接到顶层模块中也就是实例化
4.接下来就是具体的仿真测试
顶层模块中的实例化是使用ip核,仿真文件的实例化是将仿真文件里的信号连接到顶层模块
`timescale 1ns / 1ps
module tb_top();
reg clk;
reg ram_wen;
reg [15:0] ram_addr;
reg [31:0] ram_wdata;
wire [31:0] ram_rdata;
reg [3 :0] task_phase;
ram_top u_ram_top(
.clk (clk ),
.ram_wen (ram_wen ),
.ram_addr (ram_addr ),
.ram_wdata(ram_wdata ),
.ram_rdata(ram_rdata )
);
//clk
initial
begin
clk = 1'b1;
end
always #5 clk = ~clk;
initial
begin
ram_addr = 16'd0;
ram_wdata = 32'd0;
ram_wen = 1'd0;
task_phase = 4'd0;
#2000;
$display("=============================");
$display("Test Begin");
#1;
// Part 0 Begin
#10;
task_phase = 4'd0;
ram_wen = 1'b0;
ram_addr = 16'hf0;
ram_wdata = 32'hffffffff;
#10;
ram_wen = 1'b1;
ram_addr = 16'hf0;
ram_wdata = 32'h11223344;
#10;
ram_wen = 1'b0;
ram_addr = 16'hf1;
#10;
ram_wen = 1'b0;
ram_addr = 16'hf0;
#200;
// Part 1 Begin
#10;
task_phase = 4'd1;
ram_wen = 1'b1;
ram_wdata = 32'hff00;
ram_addr = 16'hf0;
#10;
ram_wdata = 32'hff11;
ram_addr = 16'hf1;
#10;
ram_wdata = 32'hff22;
ram_addr = 16'hf2;
#10;
ram_wdata = 32'hff33;
ram_addr = 16'hf3;
#10;
ram_wdata = 32'hff44;
ram_addr = 16'hf4;
#10;
#200;
// Part 2 Begin
#10;
task_phase = 4'd2;
ram_wen = 1'b0;
ram_addr = 16'hf0;
ram_wdata = 32'hffffffff;
#10;
ram_addr = 16'hf1;
#10;
ram_addr = 16'hf2;
#10;
ram_addr = 16'hf3;
#10;
ram_addr = 16'hf4;
#10;
#50;
$display("TEST END");
$finish;
end
endmodule
观察波形查看读写逻辑
因为之前没有勾选 Primitives output Register所以在写入数据后的下一个时钟周期就可以读到数据
使能信号正常运行,仿真结束