External Memory Interface Handbook Volume 2: Design Guidelines: For UniPHY-based Device Families

ID 683385
Date 3/06/2023
Public
Document Table of Contents

8.2.2. Preparing the Vendor Memory Model

You can replace the Intel-supplied memory model with a vendor-specific memory model. In general, you may find vendor-specific models to be standardized, thorough, and well supported, but sometimes more complex to setup and use.
Note: Intel does not provide support for vendor-specific memory models. If you do want to replace the Intel-supplied memory model with a vendor-supplied memory model, you should observe the following guidelines:
  • Ensure that you have the correct vendor-supplied memory model for your memory device.
  • Disconnect all signals from the default memory model and reconnect them to the vendor-supplied memory model.
  • If you intend to run simulation from the Quartus Prime software, ensure that the . qip file points to the vendor-supplied memory model.

When you are using a vendor-supplied memory model instead of the generated functional simulation model, you must modify the vendor memory model and the testbench files by following these steps:

  1. Obtain and copy the vendor memory model to the \<variation_name>_example_design\simulation\<variation_name>_sim\ submodules directory. For example, obtain the ddr2.v and ddr2_parameters.vh simulation model files from the Micron website and save them in the directory.
    • The auto-generated generic SDRAM model may be used as a placeholder for a specific vendor memory model.
    • Some vendor DIMM memory models do not use data mask (DM) pin operation, which can cause calibration failures. In these cases, use the vendor’s component simulation models directly.
  2. Open the vendor memory model file in a text editor and specify the speed grade and device width at the top of the file. For example, you can add the following statements for a DDR2 SDRAM model file:

    'define sg25

    'define x8

    The first statement specifies the memory device speed grade as –25 (for 400 MHz operation). The second statement specifies the memory device width per DQS.

  3. Check that the following statement is included in the vendor memory model file. If not, include it at the top of the file. This example is for a DDR2 SDRAM model file:

    `include "ddr2_parameters.vh"

  4. Save the vendor memory model file.
  5. Open the simulation example project file <variation_name>_example_sim.qpf, located in the <variation_name>_example_design\simulation directory.
  6. On the Tools menu, select TCL scripts to run the generate_sim_verilog_example_design.tcl file, in which generates the simulation example design.
  7. To enable vendor memory model simulation, you have to include and compile the vendor memory model by adding it into the simulation script. Open the .tcl script, msim_setup.tcl, located in the <variation_name>_example_design\simulation\verilog\mentor directory in the text editor. Add in the following line in the '# Compile the design files in correct order' section:
    vlog     +incdir+$QSYS_SIMDIR/submodules/
     "$QSYS_SIMDIR/submodules/<vendor_memory>.v"
    -work <variation_name>_example_sim_work
  8. Open the simulation example design, <variation_name>_example_sim.v, located in the <variation_name>_example_design\simulation\verilog directory in a text editor and delete the following module:
    alt_mem_if_<memory_type>_mem_model_top_<memory_type>_mem_if_dm_pins_en_mem_if_dqsn_en
    Note: The actual name of the pin may differ slightly depending on the memory controller you are using.
  9. Instantiate the downloaded memory model and connect its signals to the rest of the design.
  10. Ensure that the ports names and capitalization in the memory model match the port names and capitalization in the testbench.
    Note: The vendor memory model may use different pin names and capitalization than the generated functional simulation model.
  11. Save the testbench file.

The original instantiation may be similar to the following code:

alt_mem_if_ddr2_mem_model_top_mem_if_dm_pins_en_mem_if_dqsn_en #(
.MEM_IF_ADDR_WIDTH            (13),
.MEM_IF_ROW_ADDR_WIDTH        (12),
.MEM_IF_COL_ADDR_WIDTH        (8),
.MEM_IF_CS_PER_RANK           (1),
.MEM_IF_CONTROL_WIDTH         (1),
.MEM_IF_DQS_WIDTH             (1),
.MEM_IF_CS_WIDTH              (1),
.MEM_IF_BANKADDR_WIDTH        (3),
.MEM_IF_DQ_WIDTH              (8),
.MEM_IF_CK_WIDTH              (1),
.MEM_IF_CLK_EN_WIDTH          (1),
.DEVICE_WIDTH                 (1),
.MEM_TRCD                     (6),
.MEM_TRTP                     (3),
.MEM_DQS_TO_CLK_CAPTURE_DELAY (100),
.MEM_IF_ODT_WIDTH             (1),
.MEM_MIRROR_ADDRESSING_DEC    (0),
.MEM_REGDIMM_ENABLED          (0),
.DEVICE_DEPTH                 (1),
.MEM_INIT_EN                  (0),
.MEM_INIT_FILE                (""),
.DAT_DATA_WIDTH               (32)
) m0 (
.mem_a     (e0_memory_mem_a),     // memory.mem_a
.mem_ba    (e0_memory_mem_ba),    //       .mem_ba
.mem_ck    (e0_memory_mem_ck),    //       .mem_ck
.mem_ck_n  (e0_memory_mem_ck_n),  //       .mem_ck_n
.mem_cke   (e0_memory_mem_cke),   //       .mem_cke
.mem_cs_n  (e0_memory_mem_cs_n),  //       .mem_cs_n
.mem_dm    (e0_memory_mem_dm),    //       .mem_dm
.mem_ras_n (e0_memory_mem_ras_n), //       .mem_ras_n
.mem_cas_n (e0_memory_mem_cas_n), //       .mem_cas_n
.mem_we_n  (e0_memory_mem_we_n),  //       .mem_we_n
.mem_dq    (e0_memory_mem_dq),    //       .mem_dq
.mem_dqs   (e0_memory_mem_dqs),   //       .mem_dqs
.mem_dqs_n (e0_memory_mem_dqs_n), //       .mem_dqs_n
.mem_odt   (e0_memory_mem_odt)    //       .mem_odt
);

Replace the original code with the following code:

ddr2 memory_0 (
.addr (e0_memory_mem_a), // memory.mem_a
.ba (e0_memory_mem_ba), // .mem_ba
.clk (e0_memory_mem_ck), // .mem_ck
.clk_n (e0_memory_mem_ck_n), // .mem_ck_n
.cke (e0_memory_mem_cke), // .mem_cke
.cs_n (e0_memory_mem_cs_n), // .mem_cs_n
.dm_rdqs (e0_memory_mem_dm), // .mem_dm
.ras_n (e0_memory_mem_ras_n), // .mem_ras_n
.cas_n (e0_memory_mem_cas_n), // .mem_cas_n
.we_n (e0_memory_mem_we_n), // .mem_we_n
.dq (e0_memory_mem_dq), // .mem_dq
.dqs (e0_memory_mem_dqs), // .mem_dqs
.rdqs_n (), // .mem_dqs_n
.dqs_n (e0_memory_mem_dqs_n), // .mem_dqs_n
.odt (e0_memory_mem_odt) // .mem_odt);

If you are interfacing with a DIMM or multiple memory components, you need to instantiate all the memory components in the simulation file.