Xilinx RAM IP核的使用

背景

RAM和ROM也是类似的,由于这也是常用的IP核,所有完全有必要在这里记录一下,以后用到了实际后,再补充到实际工程中。随机存储器(RAM),它可以随时从任一指定地址读出数据,也可以随时把数据写入任何指定的存储单元,且读写的速度与存储单元在存储芯片的位置无关。RAM主要用来存放程序及程序执行过程中产生的中间数据、运算结果等。RAM按照存储单元的工作原理可以分为静态RAM和动态RAM,也就是常说的SRAM和DRAM。

SRAM速度非常快,是目前读写最快的存储设备,比如CPU的一级缓冲,二级缓冲。而计算机内存就是DRAM,比SRAM便宜。这里要说明的是,DRAM与SRAM相比较速度慢,但是它与ROM相比较速度还是很快的。

RAM IP核同ROM IP核一样,xilinx也提供了两种:一种是单端口的RAM IP,另一种是双端口的RAM IP。

IP核之RAM的配置







在这个页面中,有3个可供修改的标签“option output resisters”(可选输出寄存器)的“portA”(端口A)、“memory Initialization”(存储器初始化)和“File Remaining Memory Locations”(填补剩余的内存位置)。

在“port A”(端口A)栏有两个可修改项:
“register port A output of memory primitives”:表示源于的输出端口A处增加寄存器级。
“Register port A output of memory core”:表示在IP核的输出端口A处增加寄存器级。
在“memory Initialization”(存储器初始化)栏中,我们可以载入coe文件对ROM IP核进行初始化。在“Fiie Remaining Memory Locations”(填补剩余的内存位置)栏中,我们可以将剩余内存填充上我们指定的数值。


在这个页面中,有2个可供修改的标签,“power estimate options”(功耗估计选项)的“output reset options”(输出复位选项)的“port A”(端口A)可以选择是否添加一个“RSTA”引脚。“output reset valure(Hex)”设置复位输出值(十六进制)。




创建好了RAM 后,进行例化。

代码:

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    09:44:24 05/23/2019 
// Design Name: 
// Module Name:    RAM_top 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//下述功能描述了写入一个地址为0~511的地址,从512~1023 不写入数据
//////////////////////////////////////////////////////////////////////////////////
module RAM_top(
input clk,
input rst,
output reg ram_en,   //RAM IP核的使能信号
output reg wren,		//RAM IP核的写使能信号
                		//RAM IP核的地址信号
output reg [7 : 0] wrdata,		//RAM IP核的写数据信号
output  [7 : 0] rddata		//RAM IP核的读数据信号
		//用来产生地址和数据的计数器
);
reg [8 : 0] addr=0;
reg [7 : 0] time_cnt=0;

always @ (posedge clk or negedge rst)
begin
	if(!rst)
	  time_cnt<=0;
	else if(time_cnt=='d1023)
	  time_cnt<=1'd0;
	else 
	  time_cnt<=time_cnt+1;
end


//用来产生RAM IP核的写使能信号
always @ (posedge clk or negedge rst)
begin
	if(!rst)
	wren<=0;
	else if (time_cnt<='d511)
	wren<=1'b1;
	else
	wren<=0;
end
//用来产生RAM IP核的地址信号
always @ (posedge clk or negedge rst)
begin
	if(!rst)
	addr<=0;
	else if (time_cnt<='d511)
	addr<=time_cnt;
	else
	addr<=time_cnt-'d512;
end

//用来产生RAM IP核的写数据信号
always @ (posedge clk or negedge rst)
begin
	if(!rst)
	wrdata<=0;
	else if (time_cnt<='d511)
	wrdata<=time_cnt;
	else
	wrdata<=wrdata;
end

//例化RAM模块
 RAM_IP   RAM_IP_inst(
  .clka(clk),		//50M时钟输入
  .wea(wren),		//写使能信号
  .addra(addr),   //地址信号
  .dina(wrdata),	//写数据信号
  .douta(rddata)		//读数据信号
);

endmodule

下面来说一下该代码主要实现了什么功能,该代码主要实现了先往RAM IP核中的0 ~ 511地址写入0 ~511 数据,每个地址对应一个数据,比如0地址对应0数据,1地址对应1数据,以此类推。写完了512个数据之后,读数据时,我们需要将写使能拉低,而ram_en信号在操作RAM的过程中需要一直拉高。(虽然在这里,我们没有设置ranm_en)。再写完512个数据后,然后进行读数据,此时,输入一个地址,读取一个对应地址的数据,此时将wren保持为低,这样就没法写入数据,只能读取数据了。给一个地址,读取一个对应地址的数据。

仿真


采用modelsim SE 10.4 进行仿真,一看上去波形正确。


我们放大来看看,也可以看到,在地址为0,读取数据为0,然后地址为1,读取数据为1.以此类推。

note:仿真失败的,要注意添加ISE的库到modelsim中,或者编译库文件,再调用modelsim。
https://blog.csdn.net/ciscomonkey/article/details/90343303
工程链接:https://download.csdn.net/download/ciscomonkey/11199757

版权声明:本文为CSDN博主「ciscomonkey」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/ciscomonkey/article/details/90453592

最新文章