v3学院 FPGA专家 带你玩转DDR3
本文章原创,来自FPGA培训专家,v3学院 www.v3edu.org
本项目基于 Spartan6 xc6slx45t-2fgg484 系列FPGA
第一步:我们先创建ise工程,调取ddr3 ipcore:
打开ISE Core generater,找到MIG核
第二步:设置IPcore 名称
第三步:选择芯片类型,如果建立过IPCORE工程默认设置即可
第四步:根据原理图设置DDR3控制器所在bank
第五步:选择对应DDR3芯片
第六步:控制器相关特性设置(默认设置即可)
第七步:设置给用户使用的接口
选择单32bit写接口和32bit读接口,
第八步:设置优先级
第九步:DDR3控制器终端电阻、时钟、刷新设置
IP生成完成后目录介绍
DOCS是此IP所需要的设计文档
Example design 是例程,可以单独运行仿真
User design 是用户所需要的logic ip core,此目录详解如下
我们将xco文件添加到工程中
我们建立顶层文件,将ddr3 ipcore例化到顶层文件中,接下来我们设置ddr3需要绑定引脚的管脚,我们可以借助ddr3生成的参考文件
由于这些是咱们的内部变量,所以将它们设置成内部信号。
又由于我们ddr3 工作频率为333MHZ,所以我们要用锁相环生成一个333M的ddr3工作时钟。
那么我的顶层文件就写好了,代码如下:
module top_ddr3(
input wire clk,
input wire rst_n,
inout [16-1:0] mcb3_dram_dq,
output [14-1:0] mcb3_dram_a,
output [3-1:0] mcb3_dram_ba,
output mcb3_dram_ras_n,
output mcb3_dram_cas_n,
output mcb3_dram_we_n,
output mcb3_dram_odt,
output mcb3_dram_reset_n,
output mcb3_dram_cke,
output mcb3_dram_dm,
inout mcb3_dram_udqs,
inout mcb3_dram_udqs_n,
inout mcb3_rzq,
inout mcb3_zio,
output mcb3_dram_udm,
inout mcb3_dram_dqs,
inout mcb3_dram_dqs_n,
output mcb3_dram_ck,
output mcb3_dram_ck_n
);
wire c3_sys_clk;
wire c3_sys_rst_n;
wire c3_calib_done;
wire c3_clk0;
wire c3_rst0;
clk_ddr3 clk_ddr3_inst
(// Clock in ports
.CLK_IN1(clk), // IN
// Clock out ports
.CLK_OUT1(c3_sys_clk)); // OUT
ddr3_ipcore # (
.C3_P0_MASK_SIZE(4),
.C3_P0_DATA_PORT_SIZE(32),
.C3_P1_MASK_SIZE(4),
.C3_P1_DATA_PORT_SIZE(32),
.DEBUG_EN(0),
.C3_MEMCLK_PERIOD(3200),
.C3_CALIB_SOFT_IP("TRUE"),
.C3_SIMULATION("FALSE"),
.C3_RST_ACT_LOW(1),
.C3_INPUT_CLK_TYPE("SINGLE_ENDED"),
.C3_MEM_ADDR_ORDER("ROW_BANK_COLUMN"),
.C3_NUM_DQ_PINS(16),
.C3_MEM_ADDR_WIDTH(14),
.C3_MEM_BANKADDR_WIDTH(3)
)
u_ddr3_ipcore (
.c3_sys_clk (c3_sys_clk),
.c3_sys_rst_n (rst_n),
.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_cke (mcb3_dram_cke),
.mcb3_dram_ck (mcb3_dram_ck),
.mcb3_dram_ck_n (mcb3_dram_ck_n),
.mcb3_dram_dqs (mcb3_dram_dqs),
.mcb3_dram_dqs_n (mcb3_dram_dqs_n),
.mcb3_dram_udqs (mcb3_dram_udqs), // for X16 parts
.mcb3_dram_udqs_n (mcb3_dram_udqs_n), // for X16 parts
.mcb3_dram_udm (mcb3_dram_udm), // for X16 parts
.mcb3_dram_dm (mcb3_dram_dm),
.mcb3_dram_reset_n (mcb3_dram_reset_n),
.c3_clk0 (c3_clk0),
.c3_rst0 (c3_rst0),
.c3_calib_done (c3_calib_done),
.mcb3_rzq (rzq3),
.mcb3_zio (zio3),
.c3_p2_cmd_clk (c3_p2_cmd_clk),
.c3_p2_cmd_en (c3_p2_cmd_en),
.c3_p2_cmd_instr (c3_p2_cmd_instr),
.c3_p2_cmd_bl (c3_p2_cmd_bl),
.c3_p2_cmd_byte_addr (c3_p2_cmd_byte_addr),
.c3_p2_cmd_empty (c3_p2_cmd_empty),
.c3_p2_cmd_full (c3_p2_cmd_full),
.c3_p2_wr_clk (c3_p2_wr_clk),
.c3_p2_wr_en (c3_p2_wr_en),
.c3_p2_wr_mask (c3_p2_wr_mask),
.c3_p2_wr_data (c3_p2_wr_data),
.c3_p2_wr_full (c3_p2_wr_full),
.c3_p2_wr_empty (c3_p2_wr_empty),
.c3_p2_wr_count (c3_p2_wr_count),
.c3_p2_wr_underrun (c3_p2_wr_underrun),
.c3_p2_wr_error (c3_p2_wr_error),
.c3_p3_cmd_clk (c3_p3_cmd_clk),
.c3_p3_cmd_en (c3_p3_cmd_en),
.c3_p3_cmd_instr (c3_p3_cmd_instr),
.c3_p3_cmd_bl (c3_p3_cmd_bl),
.c3_p3_cmd_byte_addr (c3_p3_cmd_byte_addr),
.c3_p3_cmd_empty (c3_p3_cmd_empty),
.c3_p3_cmd_full (c3_p3_cmd_full),
.c3_p3_rd_clk (c3_p3_rd_clk),
.c3_p3_rd_en (c3_p3_rd_en),
.c3_p3_rd_data (c3_p3_rd_data),
.c3_p3_rd_full (c3_p3_rd_full),
.c3_p3_rd_empty (c3_p3_rd_empty),
.c3_p3_rd_count (c3_p3_rd_count),
.c3_p3_rd_overflow (c3_p3_rd_overflow),
.c3_p3_rd_error (c3_p3_rd_error)
);
endmodule
接下来,我们要进行仿真;仿真文件如下:
`timescale 1ns/1ns
module tb_DDR3();
reg clk ;
reg rst_n ;
reg rx;
wire mcb3_rzq,mcb3_zio;
wire[16-1:0] mcb3_dram_dq;
wire[14-1:0] mcb3_dram_a;
wire[3-1:0] mcb3_dram_ba;
wire c3_calib_done;
wire mcb3_dram_ck;
wire mcb3_dram_ck_n;
wire mcb3_dram_dqs;
wire mcb3_dram_dqs_n;
wire mcb3_dram_dm;
wire mcb3_dram_ras_n;
wire mcb3_dram_cas_n;
wire mcb3_dram_we_n;
wire mcb3_dram_cke;
wire mcb3_dram_odt;
wire mcb3_dram_reset_n;
wire mcb3_dram_udqs; // for X16 parts
wire mcb3_dram_udqs_n; // for X16 parts
wire mcb3_dram_udm; // for X16 parts
wire oe;
initial
begin
clk=1‘b1;
rst_n=1‘b0;
#200
rst_n=1‘b1;
end
always #10 clk <= ~clk;
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)
);
top_ddr3 top_inst(
.clk (clk ) ,
.rst_n (rst_n ) ,
.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 )
);
endmodule
仿真波形如下:可以看到c3_calib_done拉高,表示初始化完成。
更多FPGA免费技术请关注我们的官方微信。
本文章原创,来自FPGA培训专家,v3学院 www.v3edu.org