DDR3 Vivado 仿真测试成功
DDR MIG IP 設(shè)置
1.默認(rèn)就好了,不需要選擇AXI4 Interface ,除非你想用這個(gè)接口。
2.Clock Period:你想讓DDR3跑的時(shí)鐘,這里是400M,由于DDR3是在上升沿和下降沿都寫數(shù)據(jù),那么我們可以知道DDR3的帶寬為:400M*2*64bit=51200Mbit。
下面的PHY to Controller Clock Ratie 4:1 ,表示用戶時(shí)鐘是400M/4=100M,這個(gè)用戶時(shí)鐘,是IP核自動(dòng)生成的(ui_clk)。后期的用戶接口寫數(shù)據(jù)和讀數(shù)據(jù)都是按照這個(gè)時(shí)鐘去操作。
用戶的接口數(shù)據(jù)位寬為=51200Mbit/100M=512bit
其中Memory Type 要特別的留意,DDR3有插座式的,還有貼片的。要根據(jù)不同型號(hào)的去選擇
3.這個(gè)時(shí)鐘是給DDR的參考輸入時(shí)鐘200M,其他的時(shí)鐘,都是根據(jù)這個(gè)時(shí)鐘產(chǎn)生的。(后面有一個(gè)界面設(shè)置這個(gè)時(shí)鐘的管腳位置)
4. system clock是差分時(shí)鐘
? Reference clk 直接使用 system clk
4.讀寫速率只有800M,50即可
只有超過1333M ,才使用40
一般設(shè)計(jì)DDR都會(huì)有一個(gè)ucf文件,里面包含設(shè)計(jì)DDR3的管腳約束,加載進(jìn)來就可以了。
這個(gè)時(shí)鐘就是剛才說的那個(gè)200M時(shí)鐘
DDR MIG IP 接口信號(hào)
下一步之后,就生成了MIG IP接口,如下圖所示
mig_7series_0 u_mig_7series_0 (
// Memory interface ports
??? .ddr3_addr??????????? (ddr3_addr),? // output [15:0]? 行列地址,其中行地址線和列地址線是分時(shí)復(fù)用的,即地址要分兩次送出,先送出行地址,再送出列地址。
??? .ddr3_ba????????????? (ddr3_ba),? // output [2:0]? ? bank地址
??? .ddr3_cas_n?????????? (ddr3_cas_n),? // output? ?? 列地址選通????
??? .ddr3_ck_n??????????? (ddr3_ck_n),? // output [0:0]? 差分時(shí)鐘p端?????
??? .ddr3_ck_p??????????? (ddr3_ck_p),? // output [0:0]? 差分時(shí)鐘n端
??? .ddr3_cke???????????? (ddr3_cke),? // output [0:0]????? 時(shí)鐘有效信號(hào),高電平有效
??? .ddr3_ras_n?????????? (ddr3_ras_n),? // output?? 行地址選通信號(hào),低電平有效?????????
??? .ddr3_reset_n???????? (ddr3_reset_n),? // output???????? 復(fù)位信號(hào),低電平有效????? ??????
??? .ddr3_we_n??????????? (ddr3_we_n),? // output 0-寫允許? 1-讀允許?
??? .ddr3_dq????????????? (ddr3_dq),? // inout [63:0] 數(shù)據(jù)????????????
??? .ddr3_dqs_n?????????? (ddr3_dqs_n),? // inout [7:0]? 數(shù)據(jù)選取脈沖??????
??? .ddr3_dqs_p?????????? (ddr3_dqs_p),? // inout [7:0]? 數(shù)據(jù)選取脈沖??????
??? .init_calib_complete? (init_calib_complete),? // output 初始化完成信號(hào)? ,高電平有效
?.ddr3_cs_n?????????(ddr3_cs_n),? // output [0:0]?? 片選信號(hào),低表示命令有效,否則命令屏蔽???????
??? .ddr3_dm????????????? (ddr3_dm), ?// output [7:0]??? 數(shù)據(jù)掩碼 一位控制一個(gè)字節(jié)
??? .ddr3_odt???????????? (ddr3_odt),? // output [0:0] 片上終端使能,高電平有效???????
// Application interface ports
??? .app_addr???????????? (app_addr),? // input [29:0] 訪問的DDR3地址?
??? .app_cmd????????????? (app_cmd),? // input [2:0]?????? 000 寫命令? 001 讀命令??
??? .app_en?????????????? (app_en),? // input?? 命令路徑:的使能信號(hào),該信號(hào)有效時(shí),app_cmd、app_addr信號(hào)才有效,其余的時(shí)刻信號(hào)無效???????????????????????
??? .app_wdf_data???????? (app_wdf_data),? // input [511:0]? 寫數(shù)據(jù)路徑數(shù)據(jù)信號(hào)?
??? .app_wdf_end????????? (app_wdf_end),? // input 4:1模式下與app_wdf_wren相同,2:1模式下每?jī)蓚€(gè)app_wdf_wren,使能一次 app_wdf_en。這個(gè)可以理解可參考UG586數(shù)據(jù)手冊(cè)P169 ?????? Figure 1-78/ Figure 1-79???????
??? .app_wdf_wren???????? (app_wdf_wren),? // input????? 寫數(shù)據(jù)的有效信號(hào)???????????????
??? .app_rd_data????????? (app_rd_data),? // output [511:0] ????????? 讀數(shù)據(jù)信號(hào)
??? .app_rd_data_end????? (app_rd_data_end),? // output?????? DDR3給用戶讀命令結(jié)束信號(hào)
??? .app_rd_data_valid??? (app_rd_data_valid),? // output????????????????? 讀數(shù)據(jù)有效信號(hào)?
??? .app_rdy????????????? (app_rdy),? // output???????????????? 命令路徑準(zhǔn)備好接受用戶的命令信號(hào),與app_en有效時(shí)命令有效???
??? .app_wdf_rdy????????? (app_wdf_rdy),? // output?????? MIG信號(hào)給用戶的信號(hào),在該信號(hào)與app_wdf_wren信號(hào)同時(shí)有效時(shí),數(shù)據(jù)被寫入DDR芯片????????????
??? .app_sr_req?????????? (1'b0),? // input?????????? 一般為0
??? .app_ref_req????????? (1'b0),? // input??????????? 一般為0?????????
??? .app_zq_req?????????? (1'b0),? // input????????? 一般為0?????????
??? .app_sr_active?????? ??(),? // output??????????????? 上面請(qǐng)求的響應(yīng)信號(hào)?
??? .app_ref_ack????????? (),? // output???????????????? 上面請(qǐng)求的響應(yīng)信號(hào)?
??? .app_zq_ack?????????? (),? // output?????????????? 上面請(qǐng)求的響應(yīng)信號(hào)?
??? .ui_clk?????????????? (clk),? // output?? MIG給用戶使用的時(shí)鐘,用戶對(duì)MIG IP核的操作必須使用該時(shí)鐘?????????
??? .ui_clk_sync_rst????? (rst),? // output???? MIG給用戶使用的復(fù)位信號(hào),用戶對(duì)MIG IP核的操作必須使用該復(fù)位信號(hào)?????????????
??? .app_wdf_mask???????? (64'd0),? // input [63:0]?? 寫數(shù)據(jù)的掩碼?????? ,一般為0
??? // System Clock Ports
??? .sys_clk_p???????????? (sys_clk_p),? // input???????? MIG的系統(tǒng)時(shí)鐘,在MIG的選項(xiàng)中選擇
??? .sys_clk_n???????????? (sys_clk_n),? // input????????????????????????????????????
??? .sys_rst?????????????? (sys_rst) // input sys_rst MIG IP核的復(fù)位信號(hào),與系統(tǒng)時(shí)鐘相關(guān)聯(lián)
);
需要對(duì)接口信號(hào)做一個(gè)了解,包括DDR3的管腳接口,MIG 用戶接口,只需要了解 Application interface ports 接口就可以了,看懂DDR3的讀寫時(shí)序圖,這樣就可以完成對(duì)于DDR3的讀寫。
Application interface ports 接口主要包括:
控制命令接口信號(hào)app_addr,app_cmd,app_en, app_rdy
寫通道接口信號(hào): ?app_wdf_data, .app_wdf_end, app_wdf_wren, app_wdf_rdy
讀通道接口信號(hào):? app_rd_data, app_rd_data_end, app_rd_data_valid
DDR3 的接口信號(hào)讀寫時(shí)序
按照UG586的說明,當(dāng)app_rdy為高時(shí),將app_cmd,app_addr以及app_en拉高,此時(shí),寫命令發(fā)出。在寫命令發(fā)出之前周期、當(dāng)前周期或者之后3個(gè)周期之內(nèi),用戶可以進(jìn)行寫操作。寫操作執(zhí)行過程同樣是:當(dāng)app_wdf_rdy為高時(shí),將app_wdf_data,app_wdf_wren以及app_wdf_end拉高,此時(shí)寫操作成功。
圖1寫時(shí)序
如下圖所示為讀操作的具體時(shí)序,同樣的先進(jìn)行寫命令操作,時(shí)序同寫命令操作一樣。寫命令完成后的若干個(gè)周期,app_rd_data、app_rd_data_valid以及app_rd_data_end出現(xiàn)。當(dāng)app_rd_data_valid為高時(shí),用戶取數(shù)即可
圖2讀時(shí)序
DDR3讀寫的地址偏移?
做讀寫測(cè)試時(shí)一直困擾我的問題.上面說給DDR3指定一個(gè)地址,可以往這個(gè)地址里讀或?qū)?/span>8*n bits的數(shù)據(jù).按理說我要讀寫下一地址,只要地址加1就可以.但仿真時(shí)地址加1得到的數(shù)據(jù)都是亂的.要想正常讀寫數(shù)據(jù),需要每次地址加8,這是為什么呢?
我們可以看一下這個(gè)DDR3的內(nèi)部結(jié)構(gòu)圖,從這個(gè)圖中我們可以看出10bit的Column Address的尋址能力只有128,只有7bits用于列地址譯碼!列地址0,1,2并沒有用,而這列地址的低三位被用于確定Burst Length 與Burst Order了.見下圖:
所以列地址的低三位并沒有用于尋址,所以如果我們想要訪問下一存儲(chǔ)單元的話,地址需要加8而不是加1
DDR3 的仿真驗(yàn)證
.在我們上板子之前,最好可以通過仿真,先驗(yàn)證自己的讀寫控制時(shí)序是否正確,如果沒有仿真,就直接上板,可能后期調(diào)試起來也比較麻煩。關(guān)于如何在Vivado中建立一個(gè)DDR3的仿真工程,可以參考特權(quán)同學(xué)2020版《深入淺出玩轉(zhuǎn)FPGA視頻教程》?中的DDR3 IP仿真的章節(jié)。嗶哩嗶哩上有這個(gè)課程。
在建立完工程后,我們可以把工程中example_top 文件下的
mig_7series_v4_0_traffic_gen_top 文件注釋掉,添加我們自己的讀寫控制文件,完成DDR3的仿真。本次仿真結(jié)構(gòu)如下,主要想完成對(duì)于DDR3全部地址的讀寫測(cè)試。
整體設(shè)計(jì)思路如下:突發(fā)傳輸寫數(shù)據(jù)一次,然后突發(fā)讀出來,校驗(yàn)數(shù)據(jù)是否正確。如果出錯(cuò),會(huì)有指示信號(hào)。
mig_ctrl #
?(
???? .DATA_WIDTH????????? (APP_DATA_WIDTH),
???? .ADDR_WIDTH????????? (ADDR_WIDTH)
?)
?mig_ctrl_inst(
// Application interface ports
?????? .clk? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (clk),
?????? .rst? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(rst),
?????? .app_addr?????????????????????? (app_addr),//output [29:0]
?????? .app_cmd??????????????????????? (app_cmd), //output [2:0]
?????? .app_en????????????????? ???????(app_en),? //output
?????? .app_wdf_data?????????????????? (app_wdf_data),//output [511:0]
?????? .app_wdf_end??????????????????? (app_wdf_end),// output
?????? .app_wdf_wren?????????????????? (app_wdf_wren),//output
?????? .app_rd_data?????????? ?????????(app_rd_data),// input [511:0]
?????? .app_rd_data_end??????????????? (app_rd_data_end),//input
?????? .app_rd_data_valid????????????? (app_rd_data_valid),//input
?????? .app_rdy??????????????????????? (app_rdy),? //input
?????? .app_wdf_rdy??? ????????????????(app_wdf_rdy), //input
?????? .init_calib_complete??????????? (init_calib_complete),
??? // user interface
?????? .wr_request???????????????????? (wr_request), //突發(fā)寫請(qǐng)求
?????? .wr_start_addr????????????????? (wr_start_addr),//突發(fā)寫首地址
?????? .wr_len???????????????????????? (wr_len), //突發(fā)寫長(zhǎng)度
?????? .wr_data??????????????????????? (512'd0),//寫數(shù)據(jù),本次仿真未使用
?????? .wr_data_valid????????????????? (1'b0), //寫數(shù)據(jù)有效,本次仿真未使用
?????? .wr_finish????????????????????? (wr_finish),//一次突發(fā)完成結(jié)束信號(hào)
?????? .rd_request???????????????????? (rd_request),
?????? .rd_start_addr????????????????? (rd_start_addr),
?????? .rd_len???????????????????????? (rd_len),
?????? .rd_data??????????????????????? (rd_data),
?????? .rd_data_valid????????????????? (rd_data_valid),
?????? .rd_finish????????????????????? (rd_finish),
?????? .check_error??????????????????? (check_error)
);
test_ddr test_ddr(
???????? .clk??????????????????????????? (clk),
???????? .rst??????????????????????????? (rst),
???????? //mig_ctrl? interface
???????? .init_calib_complete?????????(init_calib_complete),
???????? .wr_request???????????????????? (wr_request),
???????? .wr_start_addr??????????????? (wr_start_addr),
???????? .wr_len? ? ? ? ? ? ? ? ? ? ? ? ? ?(wr_len),
???????? .wr_finish? ? ? ? ? ? ? ? ? ? ? ?(wr_finish),
???????? .rd_request???????????????????? (rd_request),
???????? .rd_start_addr?????????????????(rd_start_addr),
???????? .rd_len? ? ? ? ? ? ? ? ? ? ? ? ? ? (rd_len),
???????? .rd_finish? ? ? ? ? ? ? ? ? ? ? ? ?(rd_finish),
???????? .start_test_pulse?????????????? (start_test_pulse)???? //測(cè)試開始信號(hào)
);
?圖1寫時(shí)序
寫時(shí)序仿真
?
讀時(shí)序仿真結(jié)果
DDR3 仿真工程百度云盤:
鏈接:https://pan.baidu.com/s/19vtorLOS4zQPDnqX4Yzd0A
提取碼:53iz
希望可以對(duì)初學(xué)者有一定的用處,加油!FPGA一定可以學(xué)好的。
總結(jié)
以上是生活随笔為你收集整理的DDR3 Vivado 仿真测试成功的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: javascript 快速入门
- 下一篇: 近世代数:群论