需求分析

用Nexys4 DDR 制作一台计算机[1] 硬件需要一次最小读写宽度8bits,最大读写宽度32bits的内存。

原理分析

NEYXS 4 DDR里的DDR2 SDRAM型号为MT47H64M16HR-25:H,它的文档在这里
由于DDR协议比较复杂,Xilinx提供了一个简化控制DDR的内存控制器IP核,Memory Interface Generator(MIG),这里就使用这个IP核来进行操作。

DDR RAM时序

它一共有以下几个信号
app_addr [26:0] in 数据地址
app_cmd [2:0] in 操作指令,3'b001为读,3'b000为写
app_en in 指令使能
app_rdy out 指令接受,SDRAM接受到信号之后就会将其拉高
app_wdf_data [127:0] in 写数据,通过app_wdf_mask处理后写入SDRAM
app_wdf_mask [15:0] in 写数据中一个byte对应这里一个bit,将某一位设高就意味着忽略该位对应的数据byte后写入SDRAM
app_wdf_end in 在发送最后一个数据的时候将其拉高,以通知SDRAM结束写入操作
app_wdf_wren in 写使能,在把前面的app_wdf_data和app_wdf_mask都写好了之后,把这个信号拉高,来通知SDRAM可以开始写入
app_wdf_rdy out 写数据指令接收,SDRAM接收到app_wdf_data和app_wdf_mask之后就会将其拉高
app_rd_data [127:0] out 读取的数据
app_rd_data_valid out 读取数据有效,当SDRAM将数据读取到app_rd_data时会将这个信号拉高
app_sr_req in 保留引脚,应该拉低
app_ref_req in 拉高这个信号发送一个refresh指令给DRAM,一次只能拉高一个时钟周期
app_zq_req in 拉高这个信号发送一个ZQ校准指令,校准ODT电阻值,也是一次只能拉高一个时钟周期
app_sr_active out 保留引脚
app_ref_ack out SDRAM响应refresh信号时拉高
app_zq_ack out SDRAM响应ZQ校准信号时拉高
ui_clk out IP核给用户用的时钟,对于这个IP核操作的时序电路必须用这个时钟信号
ui_clk_sync_rst out 给用户用的复位信号,同上,对于这个IP核操作的时序电路必须用这个时钟信号

wishbone总线写时序

既然是内存,便需要写入数据,下图是写操作时wishbone总线的时序,读操作的数据已经在前一篇flash里介绍了。
write
cpu在需要写入内存的时候,会将STB_O、CYC_O,WE_O拉高,将ADR_O,DATA_O数据给出,内存接受到STB_O和CYC_O信号拉高的时候会开始执行操作,操作执行完将ACK_I拉高。
wishbone总线控制器接收到ACK_I拉高的信号会提醒CPU并将STB_O和CYC_O信号拉低,内存进入等待指令状态

设计

时序与状态机设计

如下图
时序与状态机

参考链接

Nexys4 DDR上的DDR2仿真与设计
FPGA基础入门【9】开发板外部存储器DDR2访问
DDR控制器MIG核的使用
Vivado中MIG核中DDR的读写控制
PrimeMHD/FPGA_ThreeLevelStorage
SRAM to DDR Component