QuartusII 中DDR2 IP的调用与仿真环境的搭建
项目简介简述
我们学完Xlinx的DDR IP核的使用应该对DDR的操作有了一定的理解。接下来,我们将学习Intel的DDR2的使用,这样里为什么使用DDR2而不是更快的DDR3因为Intel低型号的产品不支持DDR3,而自己的手中只有DDR2的开发板,所以我们主要讲解DDR2的使用。这里需要说一句,DDR2与DDR3只是调用IP的时候界面不同,但是用户操作的接口除了信号名称不同,信号的时序完全相同。本次实验所用到的软硬件平台如下:
软件环境:QuartusII 13.1
硬件环境:锆石A4 Plus开发板
DDR2 IP建立的步骤
这里关于QuartusII如何建立工II程,我们便省略跳过,相信学到DDR2的同学们都会软件的使用。
1、新建一个IP核
2、点击Next
1、选中DDR2 IP核
2、输入DDR2 IP核新建的名字及目录
3、点击Next
1、FPGA芯片的型号
2、FPGA芯片对应的速度等级
3、DDR2 IP参考时钟的频率
4、DDR2芯片实际工作的时钟频率,下面的控制器速率一般选择全速,速度相应的快一点
5、对应的DDR2芯片型号,选中之后,点击Next
1、这里选择quick模式,方便我们仿真的适口快点,如果选择全校验模式,仿真的时候将会特别慢
2、其余默认即可,点击Next
默认即可,点击下一步
1、选择每次突发的最大值,这里选择64,然后点击Next
1、点击生成仿真模型文件,方便我们接下来的仿真
2、点击Next
点击生成DDR2 IP
在生成DDR2 IP的时候,经常碰见,卡在下面的界面不进行下一步,这是因为系统不兼容的原因。
这里给出解决方案,就是在任务管理器中,将quartus_map.exe关闭掉即可,有时候一次不行需要多尝试几次。
DDR2 IP仿真模型的搭建
由于DDR2 IP没有给出示例工程,所以我们直接进行模型的搭建。我们仿照的测试程序可以在生成的DDR2的如下目录中找到。
上面三个文件分别是仿真模型文件和tb测试文件,所以我们将仿真模型文件复制到sim文件夹,仿照上面的tb文件写我们自己的测试文件。
DDR2 驱动代码
ddr2_drive代码:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : [email protected]
// Website :
// Module Name : ddr2_drive.v
// Create Time : 2020-03-06 13:14:59
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************
module ddr2_drive(
//System Interfaces
input sclk ,
input rst_n ,
//DDR2 Interfaces
output wire [ 0:0] mem_odt ,
output wire [ 0:0] mem_cs_n ,
output wire [ 0:0] mem_cke ,
output wire [12:0] mem_addr ,
output wire [ 2:0] mem_ba ,
output wire mem_ras_n ,
output wire mem_cas_n ,
output wire mem_we_n ,
output wire [ 3:0] mem_dm ,
inout wire [ 0:0] mem_clk ,
inout wire [ 0:0] mem_clk_n ,
inout wire [31:0] mem_dq ,
inout wire [ 3:0] mem_dqs
);
//========================================================================================\
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
//pll_inst
wire clk_100m ;
wire locked ;
//ddr2_ctrl_inst
wire phy_clk ;
wire reset_phy_clk_n ;
//========================================================================================\
//************** Main Code **********************************
//========================================================================================/
pll pll_inst(
.areset (~rst_n ),
.inclk0 (sclk ),
.c0 (clk_100m ),
.locked (locked )
);
ddr2_ctrl ddr2_ctrl_inst(
.pll_ref_clk (clk_100m ),
.global_reset_n (locked ),
.soft_reset_n (locked ),
.local_address (),
.local_write_req (),
.local_read_req (),
.local_burstbegin (),
.local_wdata (),
.local_be (),
.local_size (),
.local_ready (),
.local_rdata (),
.local_rdata_valid (),
.local_refresh_ack (),
.local_init_done (local_init_done ),
.mem_odt (mem_odt ),
.mem_cs_n (mem_cs_n ),
.mem_cke (mem_cke ),
.mem_addr (mem_addr ),
.mem_ba (mem_ba ),
.mem_ras_n (mem_ras_n ),
.mem_cas_n (mem_cas_n ),
.mem_we_n (mem_we_n ),
.mem_dm (mem_dm ),
.mem_clk (mem_clk ),
.mem_clk_n (mem_clk_n ),
.mem_dq (mem_dq ),
.mem_dqs (mem_dqs ),
.phy_clk (phy_clk ),
.reset_phy_clk_n (reset_phy_clk_n ),
.reset_request_n (),
.aux_full_rate_clk (),
.aux_half_rate_clk ()
);
endmodule
DDR2 测试模块代码
tb_ddr2模块:
`timescale 1ns / 1ps
`define CLOCK 20
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : [email protected]
// Website :
// Module Name : tb_ddr2.v
// Create Time : 2020-03-06 14:09:39
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************
module tb_ddr2();
//System Interfaces
reg sclk ;
reg rst_n ;
//DDR2 Interfaces
wire [ 0:0] mem_odt ;
wire [ 0:0] mem_cs_n ;
wire [ 0:0] mem_cke ;
wire [12:0] mem_addr ;
wire [ 2:0] mem_ba ;
wire mem_ras_n ;
wire mem_cas_n ;
wire mem_we_n ;
wire [ 3:0] mem_dm ;
wire [ 0:0] mem_clk ;
wire [ 0:0] mem_clk_n ;
wire [31:0] mem_dq ;
wire [ 3:0] mem_dqs ;
tri [ 3:0] mem_dqs_n = 100'bz ;
assign (weak1, weak0) mem_dqs_n = 1;
initial begin
sclk = 1'b0;
rst_n <= 1'b0;
#(100*`CLOCK);
rst_n <= 1'b1;
end
always #(`CLOCK/2) sclk = ~sclk;
ddr2_drive ddr2_drive_inst(
//System Interfaces
.sclk (sclk ),
.rst_n (rst_n ),
//DDR2 Interfaces
.mem_odt (mem_odt ),
.mem_cs_n (mem_cs_n ),
.mem_cke (mem_cke ),
.mem_addr (mem_addr ),
.mem_ba (mem_ba ),
.mem_ras_n (mem_ras_n ),
.mem_cas_n (mem_cas_n ),
.mem_we_n (mem_we_n ),
.mem_dm (mem_dm ),
.mem_clk (mem_clk ),
.mem_clk_n (mem_clk_n ),
.mem_dq (mem_dq ),
.mem_dqs (mem_dqs )
);
ddr2_ctrl_mem_model mem_inst(
.mem_dq (mem_dq ),
.mem_dqs (mem_dqs ),
.mem_dqs_n (mem_dqs_n ),
.mem_addr (mem_addr ),
.mem_ba (mem_ba ),
.mem_clk (mem_clk ),
.mem_clk_n (mem_clk_n ),
.mem_cke (mem_cke ),
.mem_cs_n (mem_cs_n ),
.mem_ras_n (mem_ras_n ),
.mem_cas_n (mem_cas_n ),
.mem_we_n (mem_we_n ),
.mem_dm (mem_dm ),
.mem_odt (mem_odt )
);
endmodule
这里为了简洁起见就不再给出测试模块的代码,需要的同学生成DDR IP的时候里面便有,当然也可以进群自取。
仿真测试结果
程序的仿真测试结果如下:
从上面可以看到初始化信号成功拉高,从而证明了我们仿真模型文件搭建的正确性。
总结
创作不易,认为文章有帮助的同学们可以关注点赞支持。(工程也都在群中)对文章有什么看法或者需要更近一步交流的同学,可以加入下面的群: