DDR Usage - MiSTer-devel/Wiki_MiSTer GitHub Wiki

The DE10-nano has a DDR memory shared between the linux system and the FPGA fabric. The DDR is connected to the FPGA through an Avalon interface.

In simple terms, the Avalon interface will set a busy signal if it cannot respond to a read or write request. The request must be kept high until busy goes down.

mister_ddr

On a read, a dout_ready signal indicates that the data is valid. Note that for the write command, the write signal must be set high for each valid data that the FPGA sets forward. This is different from the read signal, which is only set at the beginning of the transaction. An additional read signal while the current read burst is not finished will be interpreted as an additional request and will mess things up very quickly.

If you indicate a burst, you should only use straight powers of 2 and must keep count of where you are in the burst so you take down the write signal at the end of the burst. Failing to clear the write signal will either set the DDR controller in a state waiting for that extra write pulse (if you clear it too soon) or will start a whole new burst (if you clear it too late). In both cases, the DDR controller and your FPGA logic will be out of sync.

The DDR address is only checked at the beginning of each burst. You do not need to update it during the burst. Indeed, updating it may break something.

The DDR interface sports an 8-byte data bus (64 bits). The recommended way to write the address bus is thus addr[31:3] in order to signify that the lower bits [2:0] come from the byte enable mask be.

As the DDR memory is shared, writing to some regions will crash the linux subsystem. Setting the 4 top address bits to 4'd3 is recommended.

While testing a new DDR interface, it is likely that the Avalon DDR controller gets stuck for the reasons above. Thus, during development, it will often be necessary to power cycle the MiSTer to reset the controller.

DDR Use Examples

The DDR is typically used in these scenarios

  1. Fast load of game images: linux loads the data into the DDR and the core loads it into SDRAM from there directly. The NeoGeo core and JOTEGO's CPS cores use this feature. Example DDRAM module used in the NeoGeo core for reference (Note: often times each memory controller module is customized for that specific core, so you may need to tweak it a bit for your core).
  2. Rotation frame buffer: in order to rotate vertical arcade games on HDMI, a frame buffer is used. With the MiSTer FPGA template being used, you can set this up by enabling the use of the framebuffer in the QSF file, instantiating the screen_rotate module from /sys/ into the top-level emu module, and wiring up the no_rotate, rotate_ccw and flip signals similar to the following examples from the Joust2 core --> 1 - 2 - 3 - 4
  3. System frame buffer: some arcade games require a frame buffer by design either for the whole image or just for the sprites. An example is JOTEGO's Out Run core.