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