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

 

猜你喜欢

转载自www.cnblogs.com/qiantuo1234/p/12346912.html