DDR系列文章分类地址:
(1)DDR3 基础知识分享
(2)DDR3 控制器 MIG IP 详解完整版 (AXI4&Vivado&Verilog)
(3)DDR3 控制器 MIG IP 详解完整版 (native&Vivado&Verilog)
(4)基于 DDR3 的串口传图帧缓存系统设计实现
(5)基于 DDR3 的native接口串口局部传图缓存系统设计实现
(6)基于 DDR3 的串口传图缓存系统设计实现
(7)基于 FPGA 的彩色图像灰度化的设计实现
文章目录
前言
本节主要是介绍 Xilinx DDR 控制器 IP 的创建流程、IP 用户使用接口 AXI 协议介绍和
IP 对应的 Example Design 的仿真和上板验证。
提示:以下是本篇文章正文内容,下面案例可供参考
一、DDR 控制器 IP 创建流程
在建立好工程后,按如下步骤进行 DDR 控制器 IP 的创建和配置。
1、搜索查找 DDR 控制器 IP。
Xilinx 的 DDR 控制器的名称简写为 MIG(Memory Interface Generator),在 Vivado 左侧窗口点击 IP Catalog,然后在 IP Catalog 窗口直接搜索关键字“mig”,就可以很容易的找到Memory Interface Generator(MIG 7 Series)。如下图所示。
直接双击鼠标左键或通过鼠标右键选项中选择 Customize IP 并点击。如下图所示,可进
入到 IP 配置界面。
2、MIG IP 的配置。
进入IP配置界面后,第一个界面是 Memory Interface Generator 介绍页面,如下图所示。默认的器件家族(FPGA Family)、器件 型号(FPGA Part)、速度等级(Speed Grade)、综合工具(Synthesis Tool)和设计输入语言(Design Entry)都和创建工程是保持一致。
点击 Next 到 MIG Output Options 配置页面中,如下图所示。勾选“Create Design”,默认名称(Component Name)为“mig_7series_0”,用户可对其进行修改,这里保持默认。选择控制器数量(Number of Controllers)为 1,勾选 AXI4 Interface(本实验 MIG IP 的用户接口使用 AXI 协议接口)。
点击 Next 到 Pin Compatible FPGAs 配置页面,如下图所示该界面可用于配置选择和当前所设定的唯一器件型号做引脚兼容的其它 FPGA 型号。对于某些可能升级器件型号的应用而言,这个功能是很实用的。这里保持默认不做配置。
点击 Next 进入到如下图所示的 Memory Selection 配置页面,这里根据实际板子硬件进行选择,开发板板载的是 DDR3,这里选择“DDR3 SDRAM”即可。
点击 Next 进入到如下图所示的 Controller Options 配置页面该配置。
在该配置界面需要设定如下重要的 DDR3 存储器信息。对应的设置位置如下图所示。
(1)DDR3 存储器驱动的时钟周期(Clock Period)设置为 2500ps(即 400MHz),这个时钟是用于 FPGA 输出给到 DDR 存储器时钟管脚的时钟。注意这里根据实际情况是有设置区间范围的,并非可以设置任意值,这里的区间范围为 25003300ps(即300400MHz)。
(2)DDR3 存储器类型(Memory Type)为 Components。
(3)DDR3 存储器型号(Memory Part)为 MT41J128M16XX-125,这是开发板板载 DDR3存储器的实际型号(XX 表示任何字符均可)。此处倒三角点击后有很多备选型号,若实际使用型号不在此列表中,可以点击“Create Custom Part”后设置相关 DDR3 存储器的时序参数。
(4)DDR3 存储器接口电压(Memory Voltage)为 1.5V。
(5)DDR3 存储器位宽(Data Width)为 16,这里根据实际开发板板载 DDR3 存储器数据总线位宽进行设置。
(6)DDR 控制器的 bank machines 个数设置,这里参数与 DDR3 物理 bank 个数并非是同一概念,设置上并非一定需要与 DDR3 物理 bank 个数保持一致(当然设置相同数量可以增加 DDR 控制器的效率和性能,但是会占用相对多的资源,时序上要求也相对要高,性能和资源上如何达到一个比较好的平衡,需要根据实际应用场景进行设置,有关详细的设置指导可参考文档 7 Series FPGAs Memory Interface Solutions)。
(7)DDR 控制器调度命令的顺序的配置,当选择 strict 时,严格按照命令先后顺序执行;选择 normal 时,为了得到更高的效率,可能对命令重排序。为了操作简单,我们选择strict。
全部参数设置完成后如下图所示。
点击 Next 进入到如下图所示 AXI Parameter 配置页面。该界面是对 AXI 接口相关参数
进行配置,具体配置如下。
(1)AXI 接口的数据位宽,设置为 128。
(2)DDR 控制器的仲裁机制,由于 AXI 接口读写通道是独立的,读写各有自己的地址通道,而储存器控制器只有一个地址总线,同一时刻只能进行读或写,这样就存在读/写优先级的问题,这里设置 TMD(Time Division Multiplexing),该设置读写优先级相同,读写交替进行。
(3)Narrow Burst 支持,设置 0,将其关闭。
(4)AXI 接口的地址位宽,自动根据 DDR3 内存生成的位宽,这里 AXI 地址对应的数据是以 1 字节进行计算的,不要与 DDR3 的地址和存储数据混淆。板载 DDR3 存储器存储空间 2Gbit(2Gbit = 256MByte = 2^28 Byte,所以 AXI 的地址位宽为 28)。
(5)AXI 读/写通道的 ID 宽度。ID 是用来标识读/写响应和读/写数据的一致性,具体后面在讲解 AXI 协议会讲。
AXI 接口相关参数配置完成后的界面如下图所示。
点击 Next 进入到如下图所示的 Memory Options 配置页面下。
各种参数配置如下。
(1)输入系统时钟频率设置,这个时钟是提供给 MIG IP 的时钟,这里配置没有啥特别要求。如下图所示为 MIG IP 内部关于时钟的结构图,可以看到 MIG IP 里面有一个时钟锁相环,系统时钟是这个时钟锁相环的输入时钟,锁相环会根据这里的输入时钟自动产生 MIG IP 内部各种所需的时钟。所以这里的时钟频率的设置没有固定的要求,下拉框中的各种频率值都可以选择。这里考虑到 MIG IP 输入还需要一个 200M 的 IDELAYReference Clock 时钟,为了将两个时钟共用一个输入时钟,将这里的系统时钟周期(Input Clock Period)配置选择为 5000ps(200MHz)。
(2)突发读类型和长度(Read Burst Type and Length)设置为顺序读写 Sequential。
(3)输出驱动阻抗控制(Output Drive Impedance Control)选择 R ZQ/7。
(4)片上终端(On Die Termination)设置为 R ZQ/4
(5)片选信号(Controller Chip Select Pin)设置为 Enable,即使用该引脚,实际开发板的DDR3 的 CS 信号有连接到 FPGA 管脚,所以这里需要使用该引脚。如果硬件上 DDR3管脚未连接到 FPGA,那么这里就可以设置为 Disable。
(6)DDR 和 AXI 总线之间的地址映射存储器地址映射选择(Memory Address Mapping Selection)。默认选择后者。
点击 Next 进入到如下图所示的 FPGA Options 配置页面中,做如下设置。
(1)系统时钟(System Clock):这里的系统 200M 时钟由 FPGA 内部提供,不由管脚输入,选择 No Buffer,如果实际硬件管脚有提供 200MHz 时钟,也可以选择 Differential(差分输入)或 Signal-Ended(单端输入)。
(2)参考时钟(Reference Clock):该时钟需要频率为 200MHz 时钟,由于在前面配置中将系统时钟设置为 200MHz,所以可以选择 Use System Clock,这样就可以将两个输入时钟合并一个共用的 200MH 输入。如果前面的系统时钟设置的不是 200MHz 这里配置选项就没有“Use System Clock”可选,只能由管脚端口输入时钟或者 FPGA 内部产生这个 200MHz 时钟。
(3)系统复位极性(System Reset Polarity):选择 ACTIVE LOW。
(4)存储器控制器的调试信号(Debug Signal for Memory Controller)选择 OFF。
(5)勾选 internal Verf。
(6)其他保留默认设置。
全部参数设置完成后如下图所示。
点击 Next 进入到如下图所示的 Extended FPGA Option 配置页面中,设定内部终端阻抗
(Internal Termination Impedance)为 50 Ohm。
点击 Next 进入到如下图所示的 IO Planning Option 配置页面中,如果当前仅仅是仿真,
可以先选择 New Design。本次实例最终是要进行上板测试的,则选择“Fixed Pin Out: Preexisting pin out is known and fixed”。
点击 Next 进入到如下图所示的 Pin Selection 配置页面中,所有 DDR3 存储器相关的引脚定义引脚号(Pin Number)以及 IO 电平标准(IO Standard)的配置,需要和原理图连接相一致。这里有 2 中配置方式,其中一种配置方式是采用手动输入的方式,该种方式下只需要对配置界面中 Pin Number 那一列根据原理图或提供的管脚分配表选择相应的管脚即可。在选择设置完后,Bank Number 和 Byte Number 会自动填充对应的配置。手动输入模式下,IO Standard 不需要手动输入配置。
第二种方式是采用导入.ucf 约束文件方式,相比第一种方式更加方便,前提是已经编辑好了.ucf 约束文件。本实验提供的实例工程目录下有提供 ddr3_pin_.ucf,可直接使用,点击Read XDC/UCF 按钮。
在弹出的 Load Your UCF 窗口选择 ddr3_pin_.ucf,然后点击 OK。
点击 OK 后,可以看到 Pin Selection 页面中所有 DDR3 存储器相关的引脚都已经配置完成。然后点击按钮“Validate”做语法检查。
弹出如下图所示的 DRC Validation Log message 窗口,表示引脚分配通过 DRC 检查,点击 OK 关闭它即可。
如下图所示,Validation 通过后,此时 Next 按钮已经高亮。
其他的保持默认即可,几十秒后,IP 生成完成,点击 OK。
如图所示,在 Vivado 的 Source 窗口中,出现了新配置生成的 IP 核文件 mig_7series_0。
在上面窗口的 IP Sources 一栏,可以找到 IP 例化模板文件。
至此,DDR 控制器的 IP 就配置并生成完成了。
二、DDR 控制器 AXI 接口协议简介
通过打开生成 IP 的例化模板,代码如下。
1.IP例化模板
2.IP例化接口
在使用 IP 前,我们先来熟悉下 IP 输入/输出端口信号。
(1)带 ddr3 的信号是与外部 DDR3 存储器的接口;
(2)信号 init_calib_complete 是 DDR 控制器对外部 DDR3 存储器初始化和校准完成信号,若该信号为高,表示 DDR 初始化和校准完成,之后用户可往 DDR 进行数据的读写操作了。
(3)带 app 的信号是本地接口维护命令信号,这几个信号可以不用使用,输入信号直接给 0,输出信号不连接其他信号。
【注:】一般可这样
.app_sr_req (1'b0), // input app_sr_req
.app_ref_req (1'b0), // input app_ref_req
.app_zq_req (1'b0), // input app_zq_req
.app_sr_active ( ), // output app_sr_active
.app_ref_ack ( ), // output app_ref_ack
.app_zq_ack ( ), // output app_zq_ack
(4)ui_clk 和 ui_clk_sync_rst 是提供给用户侧使用的时钟信号和同步复位信号。mmcm_locked 信号是 MIG IP 里面时钟锁相环的锁定信号输出。可通过观察这个信号是否变为高电平判断内部锁相环是否锁定。
(5)sys_clk_i 是 IP 的系统时钟输入信号,根据前面 IP 配置,这个时钟需要提供 200MHz时钟,sys_rst 是 IP 的系统复位输入信号,低电平复位。
(6)带 s_axi 的信号是供用户侧使用的 AXI 接口。从 IP 例化模板端口信号可以看到AXI 接口总线共有 5 个通道,分别是 Read Address Ports、Write Address Ports、Read Data Ports、Write Data Ports、Write Response Ports。每一个 AXI 传输通道都是单方向的。接口信号中以“s_axi_aw”开头的是写地址通道信号,以“s_axi_w”开头的是写数据通道信号,以“s_axi_b”开头的是写响应通道信号,以“s_axi_rw”开头的是读地址通道信号,以“s_axi_r”开头的是读数据响应通道信号。5 个通道分为两个事务,写事务和读事务。
其中写事务的结构图如下:
读事务的结构图如下:
○1 这 5 条独立的通道都包含一个双路的 VALD、READY 握手机制。信息源通过 VALID信号来指示通道中的数据和控制信息什么时候有效。目地源用 READY 信号来表示何时准备好接收数据。传输地址信息和数据都是在 VALID 和 READY 同时为高时有效。
○2 读数据和写数据通道都包括一个 LAST 信号,用来指明一个事物传输的最后一个数据。
○3 读/写事务都有自己的地址通道,地址通道携带着传输事务所必须的地址和信息。
○4 读数据通道传送着从设备到主机的读数据和读响应信息。读响应信息指明读事务的完成状态。
○5 写数据通路传送着主机向设备的写数据和写控制信息。写响应通道提供了设备响应写事务的一种方式。在每一次突发式写会产生一个完成信号。下面分别对读事务和写事务的时序进行说明。
突发式读操作的时序图如下:
主机发送地址和控制信息到写地址通道中,当地址通道上 ARVALID 和 ARREADY 同时为高时,地址 A 被有效的传给设备,之后设备输出的数据将出现在读数据通道上。当RREADY 和 RVALID 同时为高的时候表明有效的数据传输,从图中可以看到传输了 4 个数据。为了表明一次突发式读写的完成,设备用 RLAST 信号变高电平来表示最后一个被传输的数据,D(A3)是本次读突发的最后一个读数据。
突发式写操作时序图如下:
写操作的开始时,主机发送地址和控制信息到写地址通道中,当地址通道上 AWVALID和 AWREADY 同时为高时,地址 A 被有效的传给设备。然后主机发送每一个写数据到写数据通道中,当 WREADY 和 WVALID 同时为高的时候表明一个有效的写数据,当主机发送最后一个数据时,WLAST 信号就变为高。当设备接收完所有数据之后,设备将一个写响应发送回主机来表明写事务完成,当 BVALID 和 BREADY 同时为高的时候表明有效的响应。AXI 协议支持乱序传输。每一个通过接口的事务有一个 IDtag。协议要求相同 ID tag 的事务必须有序完成,而不同 ID tag 可以乱序完成,有关乱序读写时序这里就不展开讲解。下面分别对 AXI 接口中写地址通道信号、写数据通道信号、写响应通道信号、读地址通道信号、读数据通道信号进行说明。
(1) 写地址通道信号
【注:】写地址ID,用来表示哪个主机写入的数据,一般是一台主机对应一个从机,因此这个可以随便写。
下面主要解释一下 S_AXI_AWLEN、S_AXI_AWSIZE 和 S_AXI_AWBURST
突发长度(S_AXI_AWLEN):一次突发中可能会有多次数据的传输,该信号给出了传输的次数,需要注意的是,实际传输的次数是 S_AXI_AWLEN + 1,比如该信号的值是2,那么实际上一共有三次传输,即会对三个地址处的值进行写入
突发大小(S_AXI_AWSIZE ):该信号给出了每次传输的数据的大小,需要注意的是,该信号给出的数据大小不能超过数据宽度(即 C_S_AXI_DATA_WIDTH),下表是该信号的值与其表示的传输数据大小的对应关系
突发类型(S_AXI_AWBURST):AWBURST 和 AWSIZE 决定了此处突发中每次传输的地址是如何计算的,下表给出了该信号的值与突发类型的对应关系
Fixed Burst:每次传输的地址是固定的,即为 S_AXI_AWADDR。该类型主要用于读或者清空 FIFO。
INCR (incrementing) Burst:每次传输的地址等于上一次传输的地址加上传输的大小(即S_AXI_AWSIZE信号所给出的传输的字节数),需要注意的是,Master 给出的初始地址必须是对齐的,比如说如果 AxSIZE 的值为 0b010,那么起始地址必须要是4字节对齐。该类型主要用于访问一般的存储器。
WRAP (wrapping) Burst:根据起始地址和传输大小,可以计算出一个 lower address 和 upper address,Wrapping Burst 下每次传输地址的计算和 Incrementing Burst 是相似的,除了当地址增加到 upper address 时,下次传输的地址需要回落到 lower address 。需要注意的是,起始地址必须是和 AxSIZE 对齐的,而且突发长度只能为2、4、8或16。lower address 必须与此次突发中所有传输的字节总数(即突发大小 * 突发长度)是对齐的,现在举个例子说明 lower address 和 upper address 如何计算的。例如,突发长度为 8(即AxLEN的值为7),突发大小为 4 字节(即AxSIZE为0b010),那么此次突发中传输的总字节数是 32,因此 lower address 必须是32的整数倍。假如起始地址是 72(必须和突发大小是对齐的),相邻两个32字节对齐、并且起始地址位于其间的地址是 64 和 96,因此 lower address 便是 64,upper address 便是 96-4=92 (即减去突发大小),因此此次突发的地址依次是 72, 76, 80, 84, 88, 92, 64, 68,需要注意的是传输地址中不包括96这个地址。
Wrapping Burst 主要用于 cache line 的访问,当我们访问 cache line 中的某个地址时,如果发生缺失,需要从内存中搬整个 line 大小的数据放到这个 cache line 中来,我们访问的地址不一定就是 cache line 的边界地址,此时便可以用 Wrapping Burst 来方便地解决这个问题:如果 cache line 的大小是 32 字节,便可设置突发长度为 8,突发大小为 4 字节,突发类型为 Wrapping Burst。(如要深究可参考AXI4文章)
在官方例化的IP例程中,未给上述信号,故可不管其作用,实际使用中将其直接赋值为0。
assign m_axi_awlock = 1'b0 ;
assign m_axi_awcache = 4'b0000 ;
assign m_axi_awprot = 3'b000 ;
assign m_axi_awqos = 4'b0000 ;
(2) 写数据通道信号
(3) 写响应通道信号
(4) 读地址通道信号
在官方例化的IP例程中,未给上述信号,故可不管其作用,实际使用中将其直接赋值为0。
assign m_axi_arlock = 1'b0 ;
assign m_axi_arcache = 4'b0000 ;
assign m_axi_arprot = 3'b000 ;
assign m_axi_arqos = 4'b0000 ;
(5) 读数据通道信号
三.DDR 控制器 Example Design 生成
IP 核生成完成后,在 Sources 窗口找到 IP 核选中鼠标右键点击 Open IP Example Design。
出现弹窗,设置选择生成 Example Design 的路径,这里将其设置为建立工程的目录。
点击 OK。会自动生成和打开名称为 mig_7series_0_ex 的工程。
在自动打开 mig_7series_0_ex 工程的 Source 窗口可以看到生成的设计顶层 example_top和仿真顶层 sim_tb_top。
这个工程是可以直接进行仿真看波形和进行上板测试的。
四.DDR 控制器 Example Design 仿真
对于验证 FPGA 与 DDR 接口硬件设计能否正常工作很有用。在左侧边栏 SIMULATION 下点击 Run Simulation,选择 Run Behavioral Simulation 点击可直接进行仿真。整个仿真过程需要一点时间,在仿真结束后,可以看到整个的仿真波形。
在仿真大概 0.1ms 后,init_calib_complete 信号被置高,说明这个时候对 DDR3 存储器初始化和校准已经完成。之后是往 DDR3 里写入/读出数据,通过比较同一地址写入和读出的数据是否相等验证其功能的正常。
为了能观察用户侧的 AXI 接口的控制信号的波形,将 AXI 接口的波形添加到波形窗口。
重新跑仿真,先点击 Restart(建议多点击几次 Restart,有时只点击一次后就点击 Run All 跑仿真会出现新添加的信号没有波形),再点击 Run All。
仿真结束后,随便找一处写操作过程 AXI 总线信号的变化情况。写地址通道的波形如下。这次突发写操作的起始地址是 0,突发长度是 3(等于 awlen+1),每个数据的字节数为16(等于 2awsize = 24字节),即数据位宽为 128bit,这个与我们 IP 配置 AXI 接口的数据位宽是一致的。
观察本次突发写操作的的写数据通道的波形如下。
写数据通道写入了 3 个数据,wvalid 和 wready 同时为高表示写数据有效,当写最后一个数据的时候wlast、wvalid 和 wready 是同时为高的。wstrb 等于 16’hffff,表示写入的 16 个字节全部有效。
观察本次突发写操作响应通道的波形如下。
bvalid 和 bready 同时为高表示接收到响应,bid 的值与 awid 是保持一致的,bresp 等于0 表示本次写操作的响应状态是 OK 的。
类似的方式,对读操作过程中 AXI 信号波形进行观察。首先找一次读操作过程波形,对读地址通道进行分析,波形如下。
本次读操作的起始地址是 0,突发长度是 3(等于 arlen+1),每个数据的字节数为 16(等于 2**awsize = 2^4 字节),即数据位宽为 128bit,这个与我们 IP 配置 AXI 接口的数据位宽是一致的。
观察本次突发写操作响应通道的波形如下。
读数据响应通道读出了 3 个数据,rvalid 和 rready 同时为高表示读出数据有效,当读最后一个数据的时候 rlast、rvalid 和 rready 是同时为高的。rid 的值与 arid 是保持一致的,bresp等于 0 表示本次读操作的响应状态是 OK 的。可以看出该地址读出的数据与之前写入的数据是一致的。
可以通过多个读/写操作,观察 AXI 总线信号的变化情况,对 AXI 协议能有更深的理解。
五.DDR 控制器 Example Design 上板测试
在 RTL ANALYSIS 下的找到并点击 Schematic 查看 Example Design 设计的顶层example_top 的原理图。
Example Design 设计分析后顶层原理图如下。
主要包括两个模块,右边模块是生成的 DDR 控制器 MIG IP,左边模块的功能是产生写/读 DDR 的控制信号和比较同一地址写入和读出数据是否一致,如果出现不一致,会将输出状态信号 tg_compare_error 置高。具体代码细节需要了解的,读者自己研究,这里不做讲解。Vivado 提供的 Example Design 是可以直接拿来进行上板测试的,只需输入一个复位信号和一个时钟信号该设计就能工作起来,然后用户通过观察输出的两个状态信号就可以判断验证硬件电路设计的正确性。由于这里的系统时钟需要 200MHz 时钟(时钟频率与 DDR 控制器配置相关,这个频率就是需要给 MIG IP 工作的时钟),而板子上只有一个 50M 时钟输入,这里就需要利用锁相环对 50MHz 输入时钟倍频产生 200MHz 时钟。在开发板上验证这个 Example Design,首先新建一个顶层 ddr_test,将 Example Design 的顶层 example_top 和锁相环 IP 在 ddr_test 上分别进行例化。顶层设计结构如下图所示。
添加 PLL IP,在 IP Catalog 窗口搜索关键字“clk”,找到 Clocking Wizard 双击进入配置。
配置完后的界面如下。
其他配置保持默认,点击 OK。完成 IP 生成。在 IP Source 窗口找到 IP 的例化模板,将其例化到顶层 ddr_test。
新的顶层 ddr_test 例化后的代码如下,为了直观的观察到两个状态信号的情况,将example_top 的状态输出信号接到开发板 LED 管脚,直接通过 LED 灯亮灭看测试结果。
`timescale 1ns / 1ps
module DDR_Test(
// Inouts
input clk_50M,
input resetn,
// Outputs
output [1:0] led,
// Inouts
inout [15:0] ddr3_dq,
inout [1:0] ddr3_dqs_n,
inout [1:0] ddr3_dqs_p,
// Outputs
output [13:0] ddr3_addr,
output [2:0] ddr3_ba,
output ddr3_ras_n,
output ddr3_cas_n,
output ddr3_we_n,
output ddr3_reset_n,
output [0:0] ddr3_ck_p,
output [0:0] ddr3_ck_n,
output [0:0] ddr3_cke,
output [0:0] ddr3_cs_n,
output [1:0] ddr3_dm,
output [0:0] ddr3_odt
);
assign sys_clk_i = clk_200M;
assign sys_rst = locked;
assign led = {tg_compare_error,init_calib_complete};
pll_clk pll_clk
(
// Clock out ports
.clk_out1(clk_200M), // output clk_out1
// Status and control signals
.resetn(resetn), // input resetn
.locked(locked), // output locked
// Clock in ports
.clk_in1(clk_50M)); // input clk_in1
example_top example_top(
.ddr3_dq (ddr3_dq ),
.ddr3_dqs_n (ddr3_dqs_n ),
.ddr3_dqs_p (ddr3_dqs_p ),
.ddr3_addr (ddr3_addr ),
.ddr3_ba (ddr3_ba ),
.ddr3_ras_n (ddr3_ras_n ),
.ddr3_cas_n (ddr3_cas_n ),
.ddr3_we_n (ddr3_we_n ),
.ddr3_reset_n (ddr3_reset_n ),
.ddr3_ck_p (ddr3_ck_p ),
.ddr3_ck_n (ddr3_ck_n ),
.ddr3_cke (ddr3_cke ),
.ddr3_cs_n (ddr3_cs_n ),
.ddr3_dm (ddr3_dm ),
.ddr3_odt (ddr3_odt ),
.sys_clk_i (sys_clk_i ),
.init_calib_complete (init_calib_complete),
.tg_compare_error (tg_compare_error ),
.sys_rst (sys_rst )
);
endmodule
进行分析综合,直到没有错误后,可以在 SYSTHESIS 下找到并点击 Schematic 查看原理图。
接下来进行管脚约束,DDR3 存储的管脚在 MIG IP 生成时就已经绑定,剩下主要是对复位信号(reset_n)、50MHz 时钟信号(clk50m),以及两个输出状态信号(led[1:0])的管脚进行约束,,将其分别分配到 led0~1。具体如下。
管脚约束后对其进行保存,然后 Implemetention 和生成 bit 文件。将 bit 文件下载到开发板 FPGA,观察现象。
led0 亮,led1 灭。led0 对应的是 DDR 控制器初始化和校准完成信号,led1 对应的是读写 DDR 比较数据出错信号,为低(led1 灭)表示没有出错。说明开发板 DDR3 相关硬件是能正常工作的。
【注:】根据原理图可知,驱动MIG ip需要输入200Mhz即可(这个时钟是提供给 MIG IP 的时钟,即sys_clk_i 是 IP 的系统时钟输入信号,这里考虑到 MIG IP 输入还需要一个 200M 的 IDELAYReference Clock 时钟,为了将两个时钟共用一个输入时钟,将这里的系统时钟周期(Input Clock Period)配置选择为 5000ps(200MHz)),其他的400MHZ(DDR与FPGA交互所用频率)由MIG IP生成,并由MIG IP根据4:1产生100MHZ的ui_clk 提供给用户侧使用的时钟信号(数据的地址和数据都在该时钟信号下变化)