> ## Content Index
> Fetch the complete content index at: https://cms.yufeiran.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# DDR2 RAM Read/Write Module [Verilog]
- URL: https://cms.yufeiran.com/en-ddr2-ram-de-shi-xian-verilog/
- Published: 2021-03-10T04:40:03.000Z
- Updated: 2026-09-27T12:37:56.000Z
- Author: Feiran Yu
- Tags: works, #lang-en, #legacy-import

## Requirement Analysis

[Building a Computer with Nexys4 DDR \[1\]: Hardware](https://yufeiran.com/en/yong-nexys4ddr-zhi-zuo-yi-tai-ji-suan-ji-1/?ref=cms.yufeiran.com) needs memory with a minimum read/write width of 8 bits and a maximum read/write width of 32 bits.

## Principle Analysis

The DDR2 SDRAM on the Nexys 4 DDR is the MT47H64M16HR-25:H. Its datasheet is [here](https://www.micron.com/-/media/client/global/documents/products/data-sheet/dram/ddr2/1gb%5Fddr2.pdf?ref=cms.yufeiran.com).

Because the DDR protocol is relatively complex, Xilinx provides a memory-controller IP core that simplifies DDR control: Memory Interface Generator, or MIG. This module uses that IP core.

### DDR RAM Timing

It has the following signals:

`app_addr [26:0] in`: data address

`app_cmd [2:0] in`: operation command, `3'b001` for read and `3'b000` for write

`app_en in`: command enable

`app_rdy out`: command accepted; SDRAM raises it after receiving the signal

`app_wdf_data [127:0] in`: write data, written into SDRAM after being processed by `app_wdf_mask`

`app_wdf_mask [15:0] in`: each bit corresponds to one byte in the write data; setting a bit high means ignoring that byte when writing to SDRAM

`app_wdf_end in`: raised when sending the last data item, to notify SDRAM that the write operation is ending

`app_wdf_wren in`: write enable; after `app_wdf_data` and `app_wdf_mask` are prepared, raise this signal to tell SDRAM it can start writing

`app_wdf_rdy out`: write-data command accepted; SDRAM raises it after receiving `app_wdf_data` and `app_wdf_mask`

`app_rd_data [127:0] out`: read data

`app_rd_data_valid out`: read data valid; SDRAM raises it when data has been read into `app_rd_data`

`app_sr_req in`: reserved pin, should be pulled low

`app_ref_req in`: raise this signal for one clock cycle to send a refresh command to DRAM

`app_zq_req in`: raise this signal for one clock cycle to send a ZQ calibration command for ODT resistance calibration

`app_sr_active out`: reserved pin

`app_ref_ack out`: raised when SDRAM responds to the refresh signal

`app_zq_ack out`: raised when SDRAM responds to ZQ calibration

`ui_clk out`: user clock provided by the IP core; sequential logic operating this IP core must use this clock

`ui_clk_sync_rst out`: reset signal for user logic; same as above, sequential logic operating this IP core must use this clock domain

### Wishbone Bus Write Timing

Since this is memory, it must support writes. The diagram below shows the Wishbone bus timing for write operations. Read timing was already introduced in the previous Flash article.

![write](https://yufeiran.com/content/images/2021/03/write.jpg)

When the CPU needs to write to memory, it raises `STB_O`, `CYC_O`, and `WE_O`, and provides `ADR_O` and `DATA_O`. When memory sees `STB_O` and `CYC_O` high, it starts the operation. After the operation finishes, it raises `ACK_I`.

The Wishbone bus controller receives the `ACK_I` signal, notifies the CPU, and lowers `STB_O` and `CYC_O`. Then the memory returns to the waiting-for-command state.

## Design

### Timing and State Machine Design

As shown below:

![Timing and state machine](https://yufeiran.com/content/images/2021/03/----_20210312153046.jpg)

## Reference Links

[DDR2 simulation and design on Nexys4 DDR](https://www.jianshu.com/p/9f5d5161839c?ref=cms.yufeiran.com)

[FPGA basics \[9\]: accessing external DDR2 memory on a development board](https://blog.csdn.net/qimoDIY/article/details/88986354?ref=cms.yufeiran.com)

[Using the DDR controller MIG core](https://blog.csdn.net/weixin%5F42039756/article/details/104356457?utm%5Fmedium=distribute.pc%5Frelevant.none-task-blog-baidujs%5Ftitle-0&spm=1001.2101.3001.4242&ref=cms.yufeiran.com)

[DDR read/write control in Vivado MIG](https://blog.csdn.net/wordwarwordwar/article/details/79539049?ref=cms.yufeiran.com)

[PrimeMHD/FPGA\_ThreeLevelStorage](https://github.com/PrimeMHD/FPGA%5FThreeLevelStorage?ref=cms.yufeiran.com)

[SRAM to DDR Component](https://reference.digilentinc.com/learn/programmable-logic/tutorials/nexys-4-ddr-sram-to-ddr-component/start?ref=cms.yufeiran.com)