通过上 一节的学习已经能够实现通过ISE搭建DDR IP CORE并且顺利通例程的仿真,那么接下来的这一一节我们就要根据ISE给的Example 来搭建自己所需要的仿真平台。
第一:对ISE给定的Example 要有所了解,包括结构和内容;如图所示:其中docs 文件中是DDR IPCore的使用手册和指导文档;example_design存放的是ISE官方给出的仿真例程,即一个完整的DDR IP的工程,user_design 文件下存放的是与DDR IP 相关的一些文件。这里我们用到的example _design 文件多一些。
第二:开始搭建仿真平台;
(1)将上文提到的example _design 文件拷贝到 一个相对独立的路径下面,如下图所示;
(2)创建ISE工程,把创建的工程路径放到我们拷贝的example _ design 文件下。然后添加example_design->rtl文件下(包括rtl下子文件里面的所有)的所有.v文件;添加xample_design->par文件下的example_design.ucf 文件;添加example_design->sim->function文件下的(ddr3_model_c3.v仿真模型文件,ddr3_model_pararmeters_c3.v模型参数文件,sim_tb_top文件激励文件),点击MODESIM开始仿真
(2)仿真的时候会出现需要把,仿真模型的参数文件拷贝到example_design所在的文件夹下,(就是在色的仿真路径下),还会出现一些其他错误,对应的修改一下就好。仿真过后会出现一些错误,当出现TESTpassed时,说明搭建成功。
第三: 接下来就是搭建自己的所DDR工程了
(1)添加ddr_top.v文件。就添加在之前我们建好的USB工程当中,如下图所示。
(2)在这个ddr_top.v 中对DDR IPcore例化进来,就是加入mig_39_2.xco文件。找到其中的例化模板,复制到ddr_top.v 文件当中。如下图所示,其中包括ddr对一些参数的设置。
(3)例化DDR中对参数的设置如下;当然这些事工程自己生成的,你也可以更改一些,
1 mig_39_2 # (
2 .C3_P0_MASK_SIZE(8),
3 .C3_P0_DATA_PORT_SIZE(64),
4 .C3_P1_MASK_SIZE(8),
5 .C3_P1_DATA_PORT_SIZE(64),
6 .DEBUG_EN(0),
7 .C3_MEMCLK_PERIOD(3200),//当前的时钟周期
8 .C3_CALIB_SOFT_IP("TRUE"),
9 .C3_SIMULATION("TRUE"),//仿真
10 .C3_RST_ACT_LOW(1),//复位信号的配置
11 .C3_INPUT_CLK_TYPE("SINGLE_ENDED"),//时钟模式
12 .C3_MEM_ADDR_ORDER("BANK_ROW_COLUMN"),//内存读取的顺序模式
13 .C3_NUM_DQ_PINS(16),
14 .C3_MEM_ADDR_WIDTH(13),
15 .C3_MEM_BANKADDR_WIDTH(3)
16 )
DDR的接口介绍;
(c3_calib_done), //全局完成初始化标志,在此信号没有拉高之前,不能对DDR3进行操作。,从代码中可以看出,DDR3的端口分成了两部分,分别是DDR3的芯片接口以及提供给用户的逻辑操作接口。
1 u_mig_39_2 (
2 //DDR3 的接口
3 .c3_sys_clk (c3_sys_clk),//input DDR3的参考时钟
4 .c3_sys_rst_i (c3_sys_rst_i), //input DDR3的复位信号
5
6 .mcb3_dram_dq (mcb3_dram_dq),
7 .mcb3_dram_a (mcb3_dram_a),
8 .mcb3_dram_ba (mcb3_dram_ba),
9 .mcb3_dram_ras_n (mcb3_dram_ras_n),
10 .mcb3_dram_cas_n (mcb3_dram_cas_n),
11 .mcb3_dram_we_n (mcb3_dram_we_n),
12 .mcb3_dram_odt (mcb3_dram_odt),
13 .mcb3_dram_cke (mcb3_dram_cke),
14 .mcb3_dram_ck (mcb3_dram_ck),
15 .mcb3_dram_ck_n (mcb3_dram_ck_n),
16 .mcb3_dram_dqs (mcb3_dram_dqs),
17 .mcb3_dram_dqs_n (mcb3_dram_dqs_n),
18 .mcb3_dram_udqs (mcb3_dram_udqs), // for X16 parts
19 .mcb3_dram_udqs_n (mcb3_dram_udqs_n), // for X16 parts
20 .mcb3_dram_udm (mcb3_dram_udm), // for X16 parts
21 .mcb3_dram_dm (mcb3_dram_dm),
22 .mcb3_dram_reset_n (mcb3_dram_reset_n),
23
24
25
26
27 //sppourt for user
28 .c3_clk0 (c3_clk0),//output 输出给用户提供的
29 .c3_rst0 (c3_rst0),//output 输出给用户提供的
30
31
32
33 .c3_calib_done (c3_calib_done), //全局完成初始化标志
34 .mcb3_rzq ( mcb3_rzq ),
35
36 .mcb3_zio (mcb3_zio ),
37
38 //P0,p1表示两个用户会接口
39 /*********************command path****************************/
40 .c3_p0_cmd_clk (c3_clk0 ), //命令FIFO的用户时钟。 FIFO信号是 在这个时钟的上升沿捕获。
41 .c3_p0_cmd_en (p0_cmd_en), //该高电平有效信号是用于写入的写入使能信号命令FIFO。
42 .c3_p0_cmd_instr (p0_cmd_instr), //当前指令的命令代码。 位0表示READ / WRITE选择,Bit 1为Auto预充电启用,位2代表刷新总是优先考虑
43 .c3_p0_cmd_bl (p0_cmd_bl), //当前用户字数的突发长度交易。 突发长度编码为0到63,代表1到64个用户词(例如,6'b00011 是一个突发长度4的交易)。 用户字宽等于端口宽度(例如,突发长度为3 64位端口传输3 x 64位用户字= 192位 总)。
44 /*当前事务的字节起始地址。地址
45 必须与端口大小对齐:
46 32位端口:低两位必须为0。
47 64位端口:低三位必须为0。
48 128位端口:低4位必须为0*/
49 .c3_p0_cmd_byte_addr (p0_cmd_addr),
50
51 .c3_p0_cmd_empty ( ), //这个命令FIFO的高电平有效空标志
52 .c3_p0_cmd_full ( ), //此高电平有效输出是命令的man标志
53
54 /*********************write cmd****************************/
55 .c3_p0_wr_clk (c3_clk0 ),//该信号是写数据FIFO的用户时钟
56 /*该高电平有效信号是写使能
57 用于写数据FIFO。它表明了
58 pX_wr_data上的值有效
59 加载到FIFO。数据已加载
60 pX_wr_clk的上升沿时
61 pX_wr_en = 1且pX_wr_full = 0。*/
62 .c3_p0_wr_en (p0_wr_en),
63 .c3_p0_wr_mask (p0_wr_mask),//写数据的掩码,
64 /*写入要写入的数据值
65 数据FIFO并发送到内存。 PX_SIZE
66 可以是32位,64位或128位,具体取决于
67 端口配置*/
68 .c3_p0_wr_data (p0_wr_data),
69 .c3_p0_wr_full ( ), //高有效的满信号
70 .c3_p0_wr_empty ( ),//高有效的空信号
71 /*写入数据FIFO的计数值。这个
72 输出表示有多少用户单词
73 在FIFO中(从1到64)。计数值为
74 0表示FIFO为空。这个信号
75 延迟的延迟比
76 pX_wr_empty标志。因此,FIFO
77 可能是空的或经历不足
78 即使计数不为0。*/
79 .c3_p0_wr_count ( ),
80 .c3_p0_wr_underrun ( ),//高电平有效,欠载标志。
81 .c3_p0_wr_error ( ),
82 /*********************read cmd****************************/
83 .c3_p0_rd_clk (c3_p0_rd_clk ),//该信号是du数据FIFO的用户时钟
84 .c3_p0_rd_en (c3_p0_rd_en ),
85 .c3_p0_rd_data (c3_p0_rd_data ),
86 .c3_p0_rd_full (c3_p0_rd_full ),
87 .c3_p0_rd_empty (c3_p0_rd_empty),
88 .c3_p0_rd_count (c3_p0_rd_count),
89 .c3_p0_rd_overflow (c3_p0_rd_overflow),
90 .c3_p0_rd_error (c3_p0_rd_error ),
91 /********************P1 user port************************/
92 .c3_p1_cmd_clk (c3_p1_cmd_clk ),
93 .c3_p1_cmd_en (c3_p1_cmd_en ),
94 .c3_p1_cmd_instr (c3_p1_cmd_instr ),
95 .c3_p1_cmd_bl (c3_p1_cmd_bl ),
96 .c3_p1_cmd_byte_addr (c3_p1_cmd_byte_addr),
97 .c3_p1_cmd_empty (c3_p1_cmd_empty ),
98 .c3_p1_cmd_full (c3_p1_cmd_full ),
99 .c3_p1_wr_clk (c3_p1_wr_clk),
100 .c3_p1_wr_en (c3_p1_wr_en),
101 .c3_p1_wr_mask (c3_p1_wr_mask),
102 .c3_p1_wr_data (c3_p1_wr_data),
103 .c3_p1_wr_full (c3_p1_wr_full),
104 .c3_p1_wr_empty (c3_p1_wr_empty),
105 .c3_p1_wr_count (c3_p1_wr_count),
106 .c3_p1_wr_underrun (c3_p1_wr_underrun),
107 .c3_p1_wr_error (c3_p1_wr_error),
108 .c3_p1_rd_clk (c3_p1_rd_clk),
109 .c3_p1_rd_en (c3_p1_rd_en),
110 .c3_p1_rd_data (c3_p1_rd_data),
111 .c3_p1_rd_full (c3_p1_rd_full),
112 .c3_p1_rd_empty (c3_p1_rd_empty),
113 .c3_p1_rd_count (c3_p1_rd_count),
114 .c3_p1_rd_overflow (c3_p1_rd_overflow),
115 .c3_p1_rd_error (c3_p1_rd_error)
116 );
(3)从上文中所提到的Example_design 文件中把DDr所有的顶层接口复制到ddr_top.v文件中:
1 //sysyterm interface
2 input c3_sys_clk ,
3 input c3_sys_rst_i ,
4 //ddr3 interface
5 inout [15:0] mcb3_dram_dq ,
6 output wire [12:0] mcb3_dram_a ,
7 output wire [2:0] mcb3_dram_ba ,
8 output wire mcb3_dram_ras_n ,
9 output wire mcb3_dram_cas_n ,
10 output wire mcb3_dram_we_n ,
11 output wire mcb3_dram_odt ,
12 output wire mcb3_dram_reset_n ,
13 output wire mcb3_dram_cke ,
14 output wire mcb3_dram_dm ,
15 inout mcb3_dram_udqs ,
16 inout mcb3_dram_udqs_n ,
17 inout mcb3_rzq ,
18 inout mcb3_zio ,
19 output wire mcb3_dram_udm ,
20 inout mcb3_dram_dqs ,
21 inout mcb3_dram_dqs_n ,
22 output wire mcb3_dram_ck ,
23 output wire mcb3_dram_ck_n ,
其中例程中给出的为如下所示:
1 module example_top #
2 (
3 parameter C3_P0_MASK_SIZE = 8,
4 parameter C3_P0_DATA_PORT_SIZE = 64,
5 parameter C3_P1_MASK_SIZE = 8,
6 parameter C3_P1_DATA_PORT_SIZE = 64,
7 parameter DEBUG_EN = 0,
8 // # = 1, Enable debug signals/controls,
9 // = 0, Disable debug signals/controls.
10 parameter C3_MEMCLK_PERIOD = 3200,
11 // Memory data transfer clock period
12 parameter C3_CALIB_SOFT_IP = "TRUE",
13 // # = TRUE, Enables the soft calibration logic,
14 // # = FALSE, Disables the soft calibration logic.
15 parameter C3_SIMULATION = "FALSE",
16 // # = TRUE, Simulating the design. Useful to reduce the simulation time,
17 // # = FALSE, Implementing the design.
18 parameter C3_HW_TESTING = "FALSE",
19 // Determines the address space accessed by the traffic generator,
20 // # = FALSE, Smaller address space,
21 // # = TRUE, Large address space.
22 parameter C3_RST_ACT_LOW = 0,
23 // # = 1 for active low reset,
24 // # = 0 for active high reset.
25 parameter C3_INPUT_CLK_TYPE = "DIFFERENTIAL",
26 // input clock type DIFFERENTIAL or SINGLE_ENDED
27 parameter C3_MEM_ADDR_ORDER = "BANK_ROW_COLUMN",
28 // The order in which user address is provided to the memory controller,
29 // ROW_BANK_COLUMN or BANK_ROW_COLUMN
30 parameter C3_NUM_DQ_PINS = 16,
31 // External memory data width
32 parameter C3_MEM_ADDR_WIDTH = 13,
33 // External memory address width
34 parameter C3_MEM_BANKADDR_WIDTH = 3
35 // External memory bank address width
36 )
37
38 (
39 output calib_done,
40 output error,
41 inout [C3_NUM_DQ_PINS-1:0] mcb3_dram_dq,
42 output [C3_MEM_ADDR_WIDTH-1:0] mcb3_dram_a,
43 output [C3_MEM_BANKADDR_WIDTH-1:0] mcb3_dram_ba,
44 output mcb3_dram_ras_n,
45 output mcb3_dram_cas_n,
46 output mcb3_dram_we_n,
47 output mcb3_dram_odt,
48 output mcb3_dram_reset_n,
49 output mcb3_dram_cke,
50 output mcb3_dram_dm,
51 inout mcb3_dram_udqs,
52 inout mcb3_dram_udqs_n,
53 inout mcb3_rzq,
54 inout mcb3_zio,
55 output mcb3_dram_udm,
56 input c3_sys_clk_p,
57 input c3_sys_clk_n,
58 input c3_sys_rst_i,
59 inout mcb3_dram_dqs,
60 inout mcb3_dram_dqs_n,
61 output mcb3_dram_ck,
62 output mcb3_dram_ck_n
63 );
第四:创建TB激励文件;主要是根据历程中来创建的。
`timescale 1ps/1ps
module tb_ddr_top ;
reg ddr3_ref_clk ;
reg ddr3_rst_n ;
//bebug signals
reg wr_trig ;
wire c3_calib_done ;
//ddr3 interface
wire [15:0] mcb3_dram_dq ;
wire [12:0] mcb3_dram_a ;
wire [2:0] mcb3_dram_ba ;
wire mcb3_dram_ras_n ;
wire mcb3_dram_cas_n ;
wire mcb3_dram_we_n ;
wire mcb3_dram_odt ;
wire mcb3_dram_reset_n ;
wire mcb3_dram_cke ;
wire mcb3_dram_dm ;
wire mcb3_dram_udqs ;
wire mcb3_dram_udqs_n ;
wire mcb3_rzq ;
wire mcb3_zio ;
wire mcb3_dram_udm ;
wire mcb3_dram_dqs ;
wire mcb3_dram_dqs_n ;
wire mcb3_dram_ck ;
wire mcb3_dram_ck_n ;
parameter C3_MEMCLK_PERIOD = 3200;
initial begin
ddr3_ref_clk = 1;
ddr3_rst_n = 0;
#20000;
ddr3_rst_n = 1;
end
//produce debug signals
initial begin
wr_trig <= 0;
@(posedge c3_calib_done)
#100000
wr_trig <= 1;
#25600
wr_trig <= 0;
end
always #(C3_MEMCLK_PERIOD/2) ddr3_ref_clk = ~ddr3_ref_clk ;
ddr_top ddr_top_inst(
//sysyterm interface
.c3_sys_clk (ddr3_ref_clk ),
.c3_sys_rst_i (ddr3_rst_n ),
//ddr3 interface
.mcb3_dram_dq (mcb3_dram_dq ),
.mcb3_dram_a (mcb3_dram_a ),
.mcb3_dram_ba (mcb3_dram_ba ),
.mcb3_dram_ras_n (mcb3_dram_ras_n ),
.mcb3_dram_cas_n (mcb3_dram_cas_n ),
.mcb3_dram_we_n (mcb3_dram_we_n ),
.mcb3_dram_odt (mcb3_dram_odt ),
.mcb3_dram_reset_n (mcb3_dram_reset_n ),
.mcb3_dram_cke (mcb3_dram_cke ),
.mcb3_dram_dm (mcb3_dram_dm ),
.mcb3_dram_udqs (mcb3_dram_udqs ),
.mcb3_dram_udqs_n (mcb3_dram_udqs_n ),
.mcb3_rzq (mcb3_rzq ),
.mcb3_zio (mcb3_zio ),
.mcb3_dram_udm (mcb3_dram_udm ),
.mcb3_dram_dqs (mcb3_dram_dqs ),
.mcb3_dram_dqs_n (mcb3_dram_dqs_n ),
.mcb3_dram_ck (mcb3_dram_ck ),
.mcb3_dram_ck_n (mcb3_dram_ck_n ),
//debug signals
.wr_trig (wr_trig) ,
.c3_calib_done (c3_calib_done)
);
ddr3_model_c3 u_mem_c3(
.ck (mcb3_dram_ck),
.ck_n (mcb3_dram_ck_n),
.cke (mcb3_dram_cke),
.cs_n (1'b0),
.ras_n (mcb3_dram_ras_n),
.cas_n (mcb3_dram_cas_n),
.we_n (mcb3_dram_we_n),
.dm_tdqs ({mcb3_dram_udm,mcb3_dram_dm}),
.ba (mcb3_dram_ba),
.addr (mcb3_dram_a),
.dq (mcb3_dram_dq),
.dqs ({mcb3_dram_udqs,mcb3_dram_dqs}),
.dqs_n ({mcb3_dram_udqs_n,mcb3_dram_dqs_n}),
.tdqs_n (),
.odt (mcb3_dram_odt),
.rst_n (mcb3_dram_reset_n)
);
// The PULLDOWN component is connected to the ZIO signal primarily to avoid the
// unknown state in simulation. In real hardware, ZIO should be a no connect(NC) pin.
PULLDOWN zio_pulldown3 (.O(zio3)); PULLDOWN rzq_pulldown3 (.O(rzq3));
endmodule
这样自己搭建的就好了。有些细节小问题,没讲,不懂得化联系我吧,一起进步;