DDR2 RAM 读写模块[verilog]

    需求分析

    用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