1. MCB和MIG的關系
MCB,英文全稱為Memory Controller Block,直譯是存儲器控制塊,是SPARTAN6芯片中的硬件模塊,可以實現對DDR,DDR2,DDR3,LPDDR等存儲單元的讀寫操作。
MIG,英文全稱或為Memory Interface Generator,即存儲器接口生成器,是一個IP核工具,用以產生上層軟核,來實現對DDR的應用層控制。
MCB基本結構
MIG基本結構
具體來說MCB包含了基本的DDR控制器功能(讀寫邏輯及時序控制等)以及硬件的命令和數據FIFO。MIG則在此基礎上生成了校准模塊,時鍾網絡和用戶讀寫信號(port接口的位寬,方向屬性,讀寫控制信號,滿空狀態信號等)。同時,MIG會根據選定的芯片型號配置相應的時序參數。
2. 時鍾配置
MIG的時鍾配置如下圖所示,其PLL和BUFPLL_MCB等組件包含在memx_infrastructure_inst模塊中。
MIG時鍾結構
MIG 內部時鍾時序關系
由上面兩幅圖可以看出MIG模塊輸入時鍾(主時鍾)頻率(位置1)等同於DDR操作時鍾頻率,經過PLL進行2倍頻,產生一個互補(差分)時鍾,再由BUFPLL_MCB生成兩組時鍾,一組頻率與主時鍾相同,相位相差90°;另一組實際為PLL輸出的緩沖。
3. 校准做的工作
首先對RZQ和ZIO引腳上的端接電壓進行測量,然后對READ操作中的DQS-DQ的相位進行調整。
上半部分是一樣的,都是DDR芯片IO端輸出時序,DQS和DQ邊沿對齊。
左下圖是校准前,可以看到產生一段網絡延遲(PCB走線和IO)。右圖為校准后,DQS的邊沿已經和DQ數據中心對齊,FPGA可以更加准確的進行數據采樣。
校准耗時較長,約500ns,完成后cailb_done信號會拉高,此后數據讀寫才是有效操作。
4. DDR仿真模型參數設置
在ISE生成MIG后,附帶的會生成測試台和DDR模型文件,如果是自己搭建的平台,須指定容量,位寬,速度(型號尾綴)等三個參數。否則會因為時序與MIG配置的不一致,而在仿真時發生時序違例,產生錯誤。
以MT47H64M16HR-25E IT(1Gbits,8 Meg x 16 x 8 banks)為例,應指定如下3個宏定義
`define x1Gb 1
`define sg25E 1
`define x16 1
Xilinx的DDR模型內部包含了比較詳細的DEBUG信息,如讀寫,預充電,刷新等提示信息,可以進行對照參考。
5. 用戶端口操作
用戶操作有三條數據通路,命令,數據讀,數據寫。其底層是MCB中的硬件FIFO接口,以實現和DDR數據的高速緩沖。需要注意的是命令也是以FIFO形式加載到MIG中的,一個上升沿加載一次。
在向DDR寫入數據時,應先向p0_wr端寫入數據,此時計數會增加直至FIFO滿,然后向p0_cmd端寫入寫操作命令,同時指定寫入長度和地址;再經過約一個時鍾延時后,FIFO中的數據會寫入到DDR指定的存儲區域。
在從DDR讀取數據時,應向p0_cmd端寫入讀操作命令,同時指定讀取長度和地址;經過約一個時鍾延時后,FPGA會從DDR指定位置讀取數據,同時讀FIFO計數器增加直至指定長度;再從p0_rd端讀取數據即可。
寫操作
讀操作
切記cmd有命令緩沖區,一個上升沿加載一次命令。如無需要,不可連續操作。
寫入DDR內存單元信息
簡易仿真代碼如下
1 initial begin 2 c3_p0_cmd_clk = 0; 3 c3_p0_wr_clk = 0; 4 c3_p0_rd_clk = 0; 5 6 forever begin 7 #5 c3_p0_cmd_clk = ~c3_p0_cmd_clk; 8 #5 c3_p0_wr_clk = ~c3_p0_wr_clk; 9 #5 c3_p0_rd_clk = ~c3_p0_rd_clk; 10 end 11 12 end 13 14 reg start_wr_flag; 15 reg start_rd_flag; 16 17 initial begin 18 c3_p0_cmd_instr = 3'b100; 19 c3_p0_cmd_en = 1'b0; 20 c3_p0_cmd_bl = 0; 21 c3_p0_cmd_byte_addr = 0; 22 23 start_wr_flag = 0; 24 start_rd_flag = 0; 25 26 wait (c3_calib_done); 27 28 start_wr_flag = 1; 29 wait(c3_p0_wr_full == 1); 30 start_wr_flag = 0; 31 #10; 32 33 c3_p0_cmd_instr = 3'b000; 34 c3_p0_cmd_en = 1'b1; 35 c3_p0_cmd_bl = 63; 36 c3_p0_cmd_byte_addr = 30'h000; 37 #30;//Only one posedge 38 c3_p0_cmd_en = 1'b0; 39 40 wait(c3_p0_wr_empty == 1); 41 42 c3_p0_cmd_instr = 3'b001; 43 c3_p0_cmd_en = 1'b1; 44 c3_p0_cmd_bl = 63; 45 c3_p0_cmd_byte_addr = 30'h000; 46 #30;//Only one posedge 47 c3_p0_cmd_en = 1'b0; 48 start_rd_flag = 1; 49 #5000; 50 start_rd_flag = 0; 51 52 53 end 54 55 always @(posedge c3_p0_wr_clk) begin 56 if((c3_calib_done == 1) && (start_wr_flag == 1)) begin 57 c3_p0_wr_en <= 1'b1; 58 c3_p0_wr_mask <= 0; 59 c3_p0_wr_data <= 64'h12345678; 60 end 61 else begin 62 c3_p0_wr_en <= 1'b0; 63 c3_p0_wr_mask <= 0; 64 c3_p0_wr_data <= 64'h0; 65 end 66 67 end 68 69 always @(posedge c3_p0_rd_clk) begin 70 if((c3_calib_done == 1) && (start_rd_flag == 1)) begin 71 c3_p0_rd_en <= 1'b1; 72 end 73 else begin 74 c3_p0_rd_en <= 1'b0; 75 end 76 77 end 78 79 endmodule
6. 小結
仿真的優勢在於,可以毫無成本地查看所有的信號,同時可以像CPU編程語言那樣在順序執行(邏輯上)打斷點,從而大幅度加速調試過程。在正確模型的基礎上,現代仿真工具執行的結果與實際執行情況相比有相當的保真度。
參考資料
1. Xilinx UG388《Spartan-6 FPGA Memory Controller User Guide》
2. Xilinx UG416《Spartan-6 FPGA Memory Interface Solutions》
3. Micron Technology《1Gb: x4, x8, x16 DDR2 SDRAM》datasheet