引言:本文我們介紹下Xilinx DDR3 IP核的重要架構(gòu)、IP核信號(hào)管腳定義、讀寫(xiě)操作時(shí)序、IP核詳細(xì)配置以及簡(jiǎn)單的讀寫(xiě)測(cè)試。
01、DDR3 IP核概述
7系列FPGA DDR接口解決方案如圖1所示。
圖1、7系列FPGA DDR3解決方案
1.1 用戶FPGA邏輯(User FPGA Logic)
如圖1中①所示,用戶FPGA邏輯塊是任何需要連接到外部DDR2或DDR3 SDRAM的FPGA設(shè)計(jì)。用戶FPGA邏輯通過(guò)用戶接口連接到內(nèi)存控制器。
1.2 用戶接口(User Interface,UI)
如圖1中②和③所示,用于連接用戶FPGA邏輯資源和用戶接口塊,它提供了一個(gè)簡(jiǎn)單的本地接口,用于實(shí)現(xiàn)緩沖讀寫(xiě)數(shù)據(jù),這也是DDR3 IP核對(duì)外接口,是編寫(xiě)FPGA讀寫(xiě)邏輯需要操作的接口。
1.3 內(nèi)存控制器和本地接口
如圖1中④和⑤所示,內(nèi)存控制器(MC)的前端向UI塊顯示本機(jī)接口。本機(jī)接口允許用戶設(shè)計(jì)提交內(nèi)存讀寫(xiě)請(qǐng)求,并提供將數(shù)據(jù)從用戶設(shè)計(jì)移動(dòng)到外部?jī)?nèi)存設(shè)備的機(jī)制,反之亦然。內(nèi)存控制器的后端連接到物理接口,并處理該模塊的所有接口要求。內(nèi)存控制器還提供了一個(gè)重新排序選項(xiàng),可以重新排序接收到的請(qǐng)求,以優(yōu)化數(shù)據(jù)吞吐量和延遲。
1.4 物理層和物理接口
如圖1中⑥所示,PHY的前端連接到內(nèi)存控制器。PHY的后端連接到外部存儲(chǔ)設(shè)備。PHY處理存儲(chǔ)器件信號(hào)所有的排序和時(shí)序。
02、DDR3 IP核時(shí)鐘架構(gòu)
DDR3 PHY設(shè)計(jì)要求使用PLL模塊生成各種時(shí)鐘,并使用全局和本地時(shí)鐘網(wǎng)絡(luò)在整個(gè)設(shè)計(jì)中分配時(shí)鐘。PHY還需要在PLL所在的同一組中例化一個(gè)MMCM。該MMCM補(bǔ)償BUFG到PHY的插入延遲。
圖2、DDR3時(shí)鐘架構(gòu)
PHY內(nèi)的時(shí)鐘生成和分配電路及網(wǎng)絡(luò)驅(qū)動(dòng)塊大致用于四個(gè)獨(dú)立的通用功能:
- 內(nèi)部(FPGA)邏輯寫(xiě)入路徑(輸出)I/O邏輯讀取路徑(輸入)和延遲I/O邏輯IDELAY參考時(shí)鐘
對(duì)于DDR3設(shè)計(jì),IDELAY參考時(shí)鐘生成需要一個(gè)MMCM。如果設(shè)計(jì)頻率>667 MHz,則IDELAY參考時(shí)鐘為300 MHz或400 MHz(取決于FPGA速度等級(jí))。MIG IP核為300 MHz和400 MHz時(shí)鐘生成實(shí)例化了一個(gè)MMCM。
PHY需要一個(gè)MMCM和一個(gè)PLL。PLL用于生成大多數(shù)內(nèi)部邏輯的時(shí)鐘、相位器的頻率參考時(shí)鐘,以及在多I/O Bank實(shí)現(xiàn)中保持PHY控制塊同步所需的同步脈沖。
2.1 內(nèi)部(FPGA)邏輯時(shí)鐘
內(nèi)部FPGA邏輯由全局時(shí)鐘資源以DDR2或DDR3 SDRAM時(shí)鐘頻率的一半或四分之一的頻率工作,這取決于MIG工具中選擇的4:1或2:1模式。該P(yáng)LL還輸出高速DDR2或DDR3內(nèi)存時(shí)鐘。
2.2 寫(xiě)路徑(輸出)I/O邏輯時(shí)鐘
圖3、控制/地址路徑時(shí)鐘路徑框圖
由數(shù)據(jù)和控制組成的輸出路徑由PHASER_OUT時(shí)鐘觸發(fā)。PHASER_OUT為OUT_FIFO和OSERDES/ODDR的每個(gè)字節(jié)組提供同步時(shí)鐘。PHASER_OUT為其相關(guān)字節(jié)組生成字節(jié)時(shí)鐘(OCLK)、分字節(jié)時(shí)鐘(OCLKDIV)和延遲字節(jié)時(shí)鐘(OCLK_DELAYED)。這些時(shí)鐘直接從頻率基準(zhǔn)時(shí)鐘生成,并且彼此同相。字節(jié)時(shí)鐘的頻率與頻率參考時(shí)鐘的頻率相同,分字節(jié)時(shí)鐘的頻率為頻率參考時(shí)鐘頻率的一半。OCLK_DELAYED用于對(duì)DQS ODDR進(jìn)行時(shí)鐘設(shè)置,以實(shí)現(xiàn)寫(xiě)入DQS及其相關(guān)DQ位之間所需的90°相位偏移。PHASER_OUT還驅(qū)動(dòng)寫(xiě)入期間生成DQ所需的信號(hào)、與數(shù)據(jù)字節(jié)組相關(guān)的DQ和DQ 三態(tài),以及字節(jié)組OUT_FIFO的讀取使能。圖3和圖4顯示了地址/控制的時(shí)鐘細(xì)節(jié)以及使用PHASER_OUT的寫(xiě)入路徑。
2.3 讀路徑(輸入)I/O邏輯時(shí)鐘
圖4、讀寫(xiě)數(shù)據(jù)時(shí)鐘路徑框圖
輸入讀取數(shù)據(jù)路徑由PHASER_IN塊觸發(fā)。PHASER_IN塊為IN_FIFO和IDDR/ISERDES的每個(gè)字節(jié)組提供同步時(shí)鐘。PHASER_IN塊接收相關(guān)字節(jié)組的DQS信號(hào),并為DDR2或DDR3 SDRAM數(shù)據(jù)捕獲生成兩個(gè)延遲時(shí)鐘:讀取字節(jié)時(shí)鐘(ICLK)和讀取分字節(jié)時(shí)鐘(ICLKDIV)。ICLK是頻率基準(zhǔn)時(shí)鐘的延遲版本,其相位與其相關(guān)的DQ對(duì)齊。ICLKDIV用于將數(shù)據(jù)捕獲到ISERDES中的第一級(jí)觸發(fā)器中。ICLKDIV與ICLK對(duì)齊,是ISERDES中最后一列觸發(fā)器的并行傳輸時(shí)鐘。ICLKDIV還用作與字節(jié)組關(guān)聯(lián)的IN_FIFO的寫(xiě)入時(shí)鐘。移相器輸入塊還驅(qū)動(dòng)字節(jié)組輸入FIFO的寫(xiě)入啟用(可寫(xiě)入)。圖4顯示了使用PHASER_IN讀取路徑的時(shí)鐘細(xì)節(jié)。
2.4 延遲參考時(shí)鐘
您需要始終提供200 MHz參考時(shí)鐘,然后MIG使用額外的MMCM創(chuàng)建適當(dāng)?shù)腎DELAYCTRL頻率。IDELAYCTRL模塊持續(xù)校準(zhǔn)I/O區(qū)域中的IDELAY組件,以適應(yīng)不同的環(huán)境條件。IP核需要外部時(shí)鐘信號(hào)驅(qū)動(dòng)IDELAYCTRL模塊。如果PLL時(shí)鐘驅(qū)動(dòng)IDELAYCTRL輸入時(shí)鐘,則PLL鎖定信號(hào)需要包含在IODELAY_CTRL.v內(nèi)的rst_tmp_idelay信號(hào),這確保了時(shí)鐘在使用前是穩(wěn)定的。
03、DDR3 IP核用戶接口
用戶接口定義如表1所示,允許通過(guò)DDR3控制器訪問(wèn)外部DDR3芯片。
表1、DDR3用戶接口定義
04、DDR3 IP核讀寫(xiě)時(shí)序
4.1命令地址時(shí)序
圖5、用戶接口命令時(shí)序
當(dāng)用戶邏輯app_en信號(hào)被插入時(shí),且app_rdy信號(hào)從用戶接口(UI)被插入時(shí),用戶接口接受命令并將其寫(xiě)入IP核內(nèi)部寫(xiě)FIFO。任何時(shí)候當(dāng)app_rdy無(wú)效時(shí),用戶接口就會(huì)忽略該命令。用戶邏輯需要將app_en與有效的命令和app_addr地址保持插入,直到如圖1-74所示app_rdy有效插入。
4.2用戶接口寫(xiě)時(shí)序
圖6、4:1模式用戶接口寫(xiě)時(shí)序(存儲(chǔ)器突發(fā)類型=BL8)
可以發(fā)出非背靠背寫(xiě)入命令,如圖6所示。該圖描述了app_wdf_data、app_wdf_wren和app_wdf_end信號(hào)的三種情況,如下所示:
①寫(xiě)入數(shù)據(jù)與相應(yīng)的寫(xiě)入命令一起插入,推薦的寫(xiě)入時(shí)序(BL8的后半部分)。
②寫(xiě)入數(shù)據(jù)在相應(yīng)寫(xiě)入命令之前插入。
③寫(xiě)入數(shù)據(jù)在相應(yīng)的寫(xiě)入命令后插入,但不應(yīng)超過(guò)兩個(gè)時(shí)鐘周期的限制。
4.3用戶接口讀時(shí)序
圖7、4:1模式用戶接口讀時(shí)序(存儲(chǔ)器突發(fā)類型=BL8)
讀取的數(shù)據(jù)由UI按請(qǐng)求的順序返回,并且在以下情況下有效:app_rd_data_valid被插入(圖7和圖1-82)。app_rd_data_end信號(hào)表示每個(gè)讀取命令突發(fā)的結(jié)束,在用戶邏輯中不需要。
05、DDR3 MIG IP核配置
硬件平臺(tái):XC7Z035FFG676-2
- Vivado軟件:2017.4
建立DDR3測(cè)試工程,進(jìn)入DDR3 MIG IP配置界面。
2.點(diǎn)擊Next,進(jìn)入下一步。
3. 創(chuàng)建MIG IP設(shè)計(jì)。
① Create Design 創(chuàng)建新設(shè)計(jì)
② Component Name,編輯MIG IP核名稱,自定義
③ Number of Controller,控制器數(shù)據(jù)量,此處選擇1個(gè)
③ AXI4 Interface,AXI4接口,測(cè)試工程選擇Native Interface接口,不選擇AXI4接口。
4. Pin Compatible FPGAs,選擇IP核兼容器件,方便DDR3 IP核工程移植。此處不選擇。
5.存儲(chǔ)器選擇,由于電路板板載DDR3內(nèi)存,故此處選擇DDR3 SDRAM。
6.Controller Options,DDR3 SDRAM配置。
① Clock Period,這個(gè)時(shí)鐘為DDR3 IO接口時(shí)鐘,即CK/CK#管腳時(shí)鐘,圖中配置為400MHz;
② PHY to Controller Clock Ratio:DDR3 IO接口時(shí)鐘和DDR3 MIG IP核用戶接口時(shí)鐘ui_clk比例,如① Clock Period=400MHz,此處設(shè)置4:1,則,ui_clk = 400MHz/4 = 100MHz。
③ 該部分設(shè)置DDR3芯片的特性。
Memory Part,IP核給出了很多定制好的鎂光系列芯片,用戶可以根據(jù)自己板載DDR3直接選擇,如果器件參數(shù)不能滿足需要,也可以自己輸出DDR3芯片相關(guān)參數(shù),即點(diǎn)擊Create Custom Part即可進(jìn)入?yún)?shù)編輯頁(yè)面。此處選擇MT41K256M16XX-107;
Memory Voltage,設(shè)置存儲(chǔ)器電壓,板載為1.5V芯片,故此處選擇1.5V;
Data Width,選擇DDR3數(shù)據(jù)位寬,板載為2片16bit DDR3,共用控制和地址,組成32bit位寬數(shù)據(jù)總線,故此處選擇32;ECC,ECC校驗(yàn)只支持72bit位寬,故不能選擇;
Data Mask,數(shù)據(jù)屏蔽位,使能后,IP核會(huì)例化相應(yīng)data mask接口,此處選擇使能。
④Nuber of Bank Machines,選擇默認(rèn)4;
ORDERING,選擇默認(rèn)Normal
7.Memory Options,DDR3 MIG IP配置。
①Input Clock Period,輸入時(shí)鐘設(shè)置,該時(shí)鐘為DDR3 MIG IP核輸入時(shí)鐘,及IP核內(nèi)部PLL源時(shí)鐘,此處選擇5000ps(200MHz);②Read Burst Type and Length,讀突發(fā)長(zhǎng)度和類型,DDR3只支持突發(fā)長(zhǎng)度BL = 8,此處選擇突發(fā)類型為Sequential;③Output Driver Impedance Control,編程輸出buffer阻抗,此處選擇RZQ/7;④Controller Chip Select Pin,控制器片選信號(hào)選擇,此處選擇Enabel;⑤On Die Termination(ODT),片上端接大小,此處選擇RZQ/4;⑥Memory Address Mapping Selection,存儲(chǔ)器地址映射,此處選擇{Bank,ROW,COLUMN}尋址方式。8. DDR3 MIG IP時(shí)鐘、復(fù)位、參考電壓等配置。
①System Clock,系統(tǒng)時(shí)鐘輸入方式,可選選擇單端、差分或者No Buffer,此處選擇No Buffer;
②Reference Clock,參考時(shí)鐘,可選選擇單端、差分或者No Buffer或則Use System Clock,此處選擇Use System Clock,即200MHz時(shí)鐘;
③System Reset Polarity,IP核復(fù)位信號(hào)極性,此處選擇ACTIVE LOW,即低電平復(fù)位;
④Debug Signals for Memory Controller,是否選擇存儲(chǔ)器調(diào)試接口,此處選擇No
⑤Internal Verf,是否使用內(nèi)部參考電壓,IP核支持DDR3參考電壓輸出,此處不勾選,即使用板載參考電壓;
⑥IO Power Reduciton,選擇IO功耗降低,此處選ON,即打開(kāi)功耗降低功能;
⑦XDAC Instantiation,是否例化XDAC,此處選擇Enable。
9. FPGA內(nèi)部端接及DCI級(jí)聯(lián)配置。
① Internal Termination Impedence,內(nèi)部端接阻抗,此處選擇50ohms;
②DCI Cascade,DCI級(jí)聯(lián)選擇,此處不勾選;
關(guān)于DCI級(jí)聯(lián)參考:Xilinx FPGA時(shí)鐘及I/O接口規(guī)劃(二)
10.選擇 Fixed Pin Out。
11.配置DDR3 SDRAM IO管腳分配。
根據(jù)原理圖DDR3 SDRAM和FPGA管腳連接關(guān)系分配對(duì)應(yīng)管腳。如果已有管腳.ucf文件,則可以點(diǎn)擊“Read XDC/UCF”,選擇.ucf文件,讀入IO約束文件;
配置完成后,需要點(diǎn)擊Validate,進(jìn)行管腳分配驗(yàn)證,驗(yàn)證通過(guò)后,方可進(jìn)行NEXT。
12.選擇狀態(tài)信號(hào),此處均選擇No connect,即不連接。
13. 該頁(yè)給出了前面DDR3 MIG IP配置總結(jié)頁(yè),可快速瀏覽前面配置的參數(shù)內(nèi)容。
14.選擇Accept,點(diǎn)擊NEXT。
15.點(diǎn)擊Generate,生產(chǎn)IP核。
至此,DDR3 MIG IP核參數(shù)配置完畢。
06、DDR3 IP核讀寫(xiě)測(cè)試
根據(jù)上一小結(jié),生成DDR3 IP核后,編寫(xiě)VerilogHDL代碼,進(jìn)行DDR3讀寫(xiě)測(cè)試。
①控制信號(hào)及命令:讀寫(xiě)DDR3,主要是按照4.1~4.3小結(jié)中的DDR3 IP核讀寫(xiě)時(shí)序編寫(xiě)邏輯代碼。
app_cmd,控制命令:3'b000為寫(xiě)命令,3'b001為讀命令;
app_addr,讀寫(xiě)地址,由于DDR3突發(fā)長(zhǎng)度固定為8,故地址遞增為8;
app_en,使能信號(hào),高有效;
app_rdy,準(zhǔn)備ok信號(hào),表示UI接口可以接收命令數(shù)據(jù);
app_wdf_rdy,寫(xiě)數(shù)據(jù)FIFO準(zhǔn)備ok,可以寫(xiě)數(shù)據(jù)到DDR3;
app_wdf_wren,寫(xiě)數(shù)據(jù)有效信號(hào),高有效;
app_wdf_end,表示當(dāng)前寫(xiě)為最后一個(gè)數(shù)據(jù),根據(jù)DDR3寫(xiě)時(shí)序,該信號(hào)和app_wdf_wren時(shí)序相同即可;
app_wdf_data,寫(xiě)DDR3數(shù)據(jù),需要注意該接口數(shù)據(jù)位寬的計(jì)算;
app_rd_data,讀出DDR3數(shù)據(jù),該接口位寬和app_wdf_data相同;
app_rd_data_valid,讀出DDR3數(shù)據(jù)有效信號(hào),高有效。
//地址、命令及使能
assign app_cmd = (state==WRITE) ? CMD_WRITE : CMD_READ;
assign app_addr = app_addr_begin;
assign app_en = (state==WRITE) ? (app_rdy&&app_wdf_rdy) : ((state==READ)&&app_rdy);//IP核使能
//寫(xiě)控制及寫(xiě)入數(shù)據(jù)
assign app_wdf_end = app_wdf_wren;
assign app_wdf_wren = (state==WRITE) ? (app_rdy&&app_wdf_rdy) : 1'b0; //寫(xiě)使能
assign app_wdf_data = {
Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],
Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],
Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],
Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0],Count_64[7:0]
};//寫(xiě)入的數(shù)據(jù)是計(jì)數(shù)器
②DDR3讀寫(xiě)狀態(tài)機(jī):先寫(xiě)入一定長(zhǎng)度數(shù)據(jù),然后讀出對(duì)應(yīng)長(zhǎng)度數(shù)據(jù),讀完后再返回寫(xiě)狀態(tài)。讀寫(xiě)狀態(tài)機(jī)比較簡(jiǎn)單,主要是讀寫(xiě)地址主要增量為突發(fā)長(zhǎng)度8。
always@(posedge ui_clk)
if(ui_clk_sync_rst&!init_calib_complete)//
begin
state <=IDLE;
app_addr_begin <=29'd0;
Count_64 <=24'd0;
end
else case(state)
IDLE: begin
state <=WRITE;
if(app_addr_begin > TEST_DATA_RANGE)
app_addr_begin <=29'd0;
Count_64 <=24'd0;
end
WRITE: begin//寫(xiě)DDR3
state <=(Count_64==TEST_DATA_RANGE)&&app_rdy&&app_wdf_rdy ? WAIT:state; //最后一個(gè)地址寫(xiě)完之后跳出寫(xiě)狀態(tài)
Count_64 <=app_rdy&&app_wdf_rdy?(Count_64+24'd1):Count_64; // 計(jì)數(shù)寫(xiě)入的數(shù)據(jù)個(gè)數(shù)
app_addr_begin <=app_rdy&&app_wdf_rdy?(app_addr_begin+29'd8):app_addr_begin; //地址突發(fā)BL=8,跳到下一個(gè)(8*32=256)bit數(shù)據(jù)地址
end
WAIT: begin
state <=READ;
Count_64 <=24'd0;
app_addr_begin <=29'd0;
end
READ: begin//讀DDR3
state <=(Count_64==TEST_DATA_RANGE)&&app_rdy? IDLE:state; //讀完寫(xiě)入數(shù)據(jù)長(zhǎng)度,切換至初始狀態(tài)
Count_64 <=app_rdy?(Count_64+24'd1):Count_64; //讀出數(shù)據(jù)個(gè)數(shù)
app_addr_begin <=app_rdy?(app_addr_begin+29'd8):app_addr_begin; //讀地址突發(fā)BL=8
end
default:begin
state <=IDLE;
app_addr_begin <=29'd0;
Count_64 <=24'd0;
end
endcase
③DDR3管腳約束。在工程文件中,不需要手動(dòng)編寫(xiě)約束文件,如本工程,只進(jìn)行了如下管腳約束。
set_property IOSTANDARD SSTL15 [get_ports clk_100M]
set_property PACKAGE_PIN C8 [get_ports clk_100M]
這是因?yàn)樵趧?chuàng)建DDR3 MIG IP核時(shí),已經(jīng)對(duì)DDR3 SDRAM管腳進(jìn)行了分配,IP核自動(dòng)生成對(duì)應(yīng)的約束文件,包含在IP文件目錄下,工程編譯綜合時(shí),會(huì)自動(dòng)編譯該IP的約束文件。
DDR3 IP核約束文件
④測(cè)試結(jié)果。
DDR3 寫(xiě)入時(shí)序及數(shù)據(jù)
DDR3 讀出時(shí)序及數(shù)據(jù)