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

标签: FPGA培训v3学院ddr3

时间: 2024-10-12 00:53:59

v3学院 FPGA专家 带你玩转DDR3的相关文章

FPGA培训专家 V3学院 FPGA专家 带你学习Verilog语言top_down书写技巧

此文章为原创出自 V3学院 www.v3edu.org,FPGA培训专家 为了提高我们代码的复用率,我们可以将不同的功能的代码分模块书写,然后在顶层连线即可.我们举一个简单的例子,如下程序,我们实现的是LED流水. 我们在led模块中先将系统时钟分频为1HZ的时钟,然后用分频后的时钟控制LED灯的流水,但我的分频和LED灯流水完全不是相同的工程,只是把分频后的时钟作为LED灯的控制时钟.这样我们会发现如果我再次用到流水灯的模块的话需要修改很多地方,那么为了让我们的模块复用率更高.更容易复用,我们

v3学院 FPGA专家 带你学习FPGA实现格雷码跨时钟域异步fifo

当由慢时钟域到快时钟域,肯定需要一个buffer做缓冲,这样才能完成时钟域的转换.一般这种情况都选择FIFO来做缓冲. 当读写FIFO的时钟不同那么称为异步FIFO,FIFO就是一个"环形存储器"读操作会把读指针指向下一个读数据,写操作会把写指针指向下一个写数据地址.当读指针追上写指针时称作读空,当写地址追上读地址时称作写满. 读空,写满标志的产生 格雷码地址编码产生 异步fifo整体逻辑框图 请扫二维码加入fpga圈 代码实现请持续关注,下次讲解! 本文章原创,来自v3学院 www.

V3学院带你学习-缩短汉明码Hamming(12,8)的FPGA实现

此文章为原创出自 V3学院 www.v3edu.org,FPGA培训专家汉明码是一种实现简单并且可以检测和纠正错误的编码, 汉明码是在原编码的基础上附加一部分数据比特,使其满足纠错码的条件.它属于线性分组码,由于线性码的编码和译码容易实现,至今仍是应用最广泛的一类码.V3学院FPGA Verilog 汉明码实现,Hamming(12,8)表示数据位长K=8,编码后码字长N=12,校验位长R=12-8=4,最小汉明距离是H=3(观察其生成矩阵,不同行向量间最少不同比特的数量),纠错能力为(H-1)

FPGA培训专家 V3学院带你学习 按键消抖 和 边缘检测

FPGA培训专家 V3学院 一般情况下,我们从按下按键到松开基本需要大于几十毫秒的时间,系统时钟的周期处于纳秒级,因此我们按下一次按键会被大于十万个时钟的上升沿采集到,然而我们希望的是按下一次按键只被一次上升沿采集到,不然会被认为按了多次按键,所以我们需要对我们的按键进行处理.假设按键在没被按下时为高电平,被按下时处于低电平,如图1所示的波形图. 图1 按键波形图 由图1 分析可知在key被按下时有且仅有一个key的上升沿和一个key的下降沿,我们可以通过检测key的上升沿或者下降沿来确定按键被

V3学院带你学习-缩短汉明码Hamming(12,8)的FPGA实现-第二部分

此文章为原创出自 V3学院 www.v3edu.org,FPGA培训专家 测试激励模块 tb_hamming_12_8.V //功能描述:给被测模块提供时钟激励,并统计解码后数据的正确性 `timescale 1ns/1ns module tb_hamming_12_8; reg sclk; wire [11:0] ham_o; wire ham_ov; wire [11:0] deham_o; wire deham_ov; reg [31:0] err_cnt; reg [23:0] buff

v3学院带您一起学习FPGA

本文为原创,转载请注明! 课程名称:双buffer乒乓操作项目概况:使用FPGA内部ram作为缓冲器,实现对外部数据流的缓存:为了提升数据的传输及处理速度,在此节课中将用到两个ram进行乒乓操作.结构框图: 效果描述:本实验做到了使用低速模块处理高速数据流,可以将缓冲的数据在没有停顿的情况下送入到数据流处理模块进行处理.应用案例:在我们做FPGA开发时,为了能更好的处理一下数据流,会经常进行一些数据的缓存,在此节课中让学员能够建立一些数据缓存的概念:乒乓操作是一种经常使用的数据流处理技巧,可以在

v3学院带你学习-时序逻辑中时钟上升沿对齐数据变化时的处理技巧的FPGA实现

此文章为原创出自 V3学院 www.v3edu.org 时序逻辑中,数据都是在时钟的上升沿或者下降沿时刻进行采样的,以上升沿为例,时钟采数据时应该采的是时钟上升沿左边变量的值,运算的结果体现在时钟上升沿的右边,但是,在用modelsim等一些仿真工具进行仿真的时候,如果时钟上升沿刚好和数据变化对齐,就会出现与上述理论不一致的原因,如下仿真波形图: 上图中的例子是用时钟上升沿控制变量a和b按位或运算并且把结果赋值给c的小实验,根据前面说的理论,黄线位置处,时钟上升沿采的变量a和b的值都为0,进行或

FPGA培训专家 v3学院 教你FPGA-赋值语句

此文章为v3学院原创 www.v3edu.org 开发过程中,我们用的最多的恐怕就是赋值语句了,我们常用的赋值方式有两种:阻塞赋值和非阻塞赋值.我刚开始学的时候就被这两种赋值方式搞晕了,当时脑子里面有几个问题总是一团乱麻-什么是阻塞赋值?什么是非阻塞赋值?什么时候用阻塞赋值?什么时候用非阻塞赋值?这两种赋值方式到底有哪些不同?什么时候两种赋值方式结合起来用? 当时由于好的教材比较少,因此我被这些简单的问题困扰了很久,今天通过本节课程的学习,我们将通过一些实际的例子来说明这些问题. 一非阻塞赋值语

V3学院带你学习-如何让chipscope里面的信号不被优化掉

此文章为原创出自 V3学院 www.v3edu.org,FPGA培训专家 在用ise对FPGA开发的时候,从仿真工具仿真的结果来看,功能都是能实现的,但是实际下载之后却不能实现具体的功能.这时我们一般会用ise自带的chipscope即在线逻辑分析仪对信号进行采样,查看硬件中具体的状态.但是很多时候,这个软件也有令我们失望的时候,因为ise里面的综合器的功能比较强大,把工程里面的一些信号给优化掉了,chipscope里面踩不到这些信号,而我们恰好是需要查看这些信号的.这时就可以用下面调取ip核的