實驗環境
軟體:
ModelSim - Intel FPGA Starter Edition 10.5b (Quartus Prime 18.0)
Micron 的 MT41K512M16HA-125:A
----------------------------------------------------------------------
Memory Model 使用
本文所使用 Memory Model 的為 Micron 的 MT41K512M16HA-125:A
點連結進入官網
從官網下載 Verilog Model 後
就會得到整包的 Memory Model
連 testbench 也幫你寫好了
readme.txt 裡頭也大概有描述該怎麼使用這包程式
不過自己在使用上還是有遇到一些問題
所以記錄下來
下載完並解壓縮後
會得到這包檔案
首先文件裡面提到的 do tb.do
我在 modelsim 的命令列執行後沒辦法使用
所以還是不要偷懶
直接自己寫 .do 檔案
請直接在該目錄底下新增 ddr3.do
ddr3.do
vlib work
vmap work work
vlog -work work -sv +define+den4096Mb ddr3.v
vlog -work work -sv +define+den4096Mb tb.v
vsim -t ps work.tb
view wave
add wave -binary /tb/rst_n
add wave -binary /tb/ck
add wave -binary /tb/ck_n
add wave -binary /tb/cke
add wave -binary /tb/cs_n
add wave -binary /tb/ras_n
add wave -binary /tb/cas_n
add wave -binary /tb/we_n
add wave -unsigned /tb/ba
add wave -unsigned /tb/a
add wave -binary /tb/dm
add wave -hexadecimal /tb/dq
add wave -hexadecimal /tb/dq0
add wave -hexadecimal /tb/dq1
add wave -binary /tb/dqs
add wave -binary /tb/dqs_n
add wave -binary /tb/tdqs_n
add wave -binary /tb/odt
run 40000ns
wave zoomrange 0ns 100ns
然後把上面內容複製到裡面
然後在 modelsim 下方的命令列
先切換資料夾到這個目錄 (跟 linux 很像,用 cd)
然後打上 do ddr3.do 即可
DDR3 Memory Waveform
就可以得到這個 Waveform!
下面也有一些訊息告訴你什麼時刻發生什麼事情
在 Cursor 1 右邊的秒數上點右鍵
就可以把秒數直接指到你想要看的地方
就可以看讀寫操作發生時
在 Waveform 上的行為
----------------------------------------------------------------------
記憶體指令
主要有
power_up
load_mode
Refresh
Precharge
Activate
Write
Read
Ze_calibration
Nop
Deselect
Power_down
Self_refresh
Pd_change_period
Sr_change_period
Read_verify
而這些 task 詳細在做什麼
8Gb: x4, x8, x16 DDR3L SDRAM 都有很詳細的紀載
這邊就不做說明了
而上面紅色字體的則是在記憶體讀寫主要會用到的指令
例如下面 code 為 Memory Model 的檔案夾裡面的 tb.v 擷取出來的部分
用 task 來定義 read command 的行為
// read without data verification
task read;
input [BA_BITS-1:0] bank;
input [COL_BITS-1:0] col;
input ap; //Auto Precharge
input bc; //Burst Chop
reg [ADDR_BITS-1:0] atemp [2:0];
integer i;
begin
cke <= 1'b1;
cs_n <= 1'b0;
ras_n <= 1'b1;
cas_n <= 1'b0;
we_n <= 1'b1;
ba <= bank;
atemp[0] = col & 10'h3ff; //a[ 9: 0] = COL[ 9: 0]
atemp[1] = ((col>>10) & 1'h1)<<11;//a[ 11] = COL[ 10]
atemp[2] = (col>>11)<<13; //a[ N:13] = COL[ N:11]
a <= atemp[0] | atemp[1] | atemp[2] | (ap<<10) | (bc<<12);
casex ({bc, mode_reg0[1:0]})
3'bx00, 3'b101:bl=8;
3'bx1x, 3'b001:bl=4;
endcase
for (i=0; i<(bl/2 + 2); i=i+1) begin
odt_fifo[rl-wl + i] = 1'b1;
end
@(negedge ck);
end
endtask
下面 code 為 Memory Model 的檔案夾裡面的 subtest.sh 擷取出來
// Random Act -> Write -> Read -> Precharge
for (r_i = 0; r_i < 2048; r_i = r_i + 1) begin
r_bank = $urandom_range (8);
r_row = $urandom_range (1<<ROW_BITS);
r_col = $urandom_range (1<<COL_BITS);
r_data = {$urandom,$urandom,$urandom,$urandom,$urandom,$urandom,$urandom,$urandom};
activate (r_bank, r_row);
nop (trcd);
write (r_bank, r_col, 0, 0, 0, r_data);
nop (wl + bl/2 + twtr);
read (r_bank, r_col, 0, 0);
nop (rl + bl/2);
precharge (r_bank, 0);
nop (trp);
end
nop (20);
所以主要就是透過將每個指令在 tb.v 裡面定義成 task
(Verilog task 語法不熟的可以稍微 Google 一下)
然後將 subtest.vh include 在 tb.v 裡頭
然後在 subtest.vh 裡頭去呼叫這些 task
因而產生了上面的 waveform
所以仔細看 waveform 下面的訊息
可以發現一直都在重複 activate -> write -> read - precharge 的工作
所以照理來說
如果想要自己測試記憶體讀寫的話
就照類似方式 call 這些 task
然後自己定義 Data 和 Address
----------------------------------------------------------------------
Memory 相關資料
我們所使用的 Memory 裡頭的詳細數據
都有記載在這個 Datasheet 裡面
Datasheet: 8Gb: x4, x8, x16 DDR3L SDRAM
裝置號碼對照表
我們的是 MT41K 512M16 HA -125 :A
Addressing 參數
我們的是 MT41K512M16HA-125
所以要看最右邊的參數
----------------------------------------------------------------------
參考資料
Unable to compile Micron's DDR3 memory model in Modelsim
8Gb: x4, x8, x16 DDR3L SDRAM
留言
張貼留言