SPARTAN6 DDR2调试要点
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