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