背景
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
