CPU设计实战-基于IP核的RAM实现

如何调用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所以在写入数据后的下一个时钟周期就可以读到数据

 使能信号正常运行,仿真结束

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值