20.1.2.4 DDR Controller

To enable fast simulation, the DDR controller follows a BFM behavioral model. It is a single model for DDR controller+PHY+DDR Memory, with no activity seen on the DDR pins connected to an external DDR memory. The DDR memory is modeled as a sparse array; it performs address decoding and prints row, column, bank, and rank address information in a simulation log. The following figure shows the Unused DDR dialog box.

Figure 20-7. Unused DDR

When no DDR memory is selected in MSS stand-alone configurator, and FIC tries to access the DDR memory, MSS simulation model displays the following message in the simulation log.

# DDR is set to unused in the MSS Configuration, cannot process AXI transaction with address 00c7000000.

The MSS stand-alone configurator configures the MSS DDR and generates configuration parameters. The simulation model considers only the parameters in the following table.

Table 20-10. MSS DDR Configuration Parameter Support
MSS ConfiguratorConsidered Parameters
DDR_DDRC_CFG_CHIPADDR_MAP_CFG_CHIPADDR_MAPAll possible values
DDR_DDRC_CFG_BANKADDR_MAP_0_CFG_BANKADDR_MAP_0All possible values
DDR_DDRC_CFG_ROWADDR_MAP_0_CFG_ROWADDR_MAP_0All possible values
DDR_DDRC_CFG_ROWADDR_MAP_1_CFG_ROWADDR_MAP_1All possible values
DDR_DDRC_CFG_ROWADDR_MAP_2_CFG_ROWADDR_MAP_2All possible values
DDR_DDRC_CFG_ROWADDR_MAP_3_CFG_ROWADDR_MAP_3All possible values
DDR_DDRC_CFG_COLADDR_MAP_0_CFG_COLADDR_MAP_0All possible values
DDR_DDRC_CFG_COLADDR_MAP_1_CFG_COLADDR_MAP_1All possible values
DDR_DDRC_CFG_COLADDR_MAP_2_CFG_COLADDR_MAP_2All possible values
DDR_DDRC_CFG_MEM_COLBITS_CFG_MEM_COLBITSAll possible values
DDR_DDRC_CFG_MEM_ROWBITS_CFG_MEM_ROWBITSAll possible values
DDR_DDRC_CFG_MEM_BANKBITS_CFG_MEM_BANKBITSAll possible values
DDR_DDRC_CFG_NUM_RANKS_CFG_NUM_RANKSAll possible values
DDR_DDRC_CFG_MANUAL_ADDRESS_MAP_CFG_MANUAL_ADDRESS_MAPAll possible values
DDR_DDRC_CFG_MEMORY_TYPE_CFG_MEMORY_TYPEAll possible values
DDR_DDRC_CFG_BG_INTERLEAVE_CFG_BG_INTERLEAVEAll possible values
DDR_DDRC_CFG_BL_MODE_CFG_BL_MODE8
DDR_DDRC_CFG_DQ_WIDTH_CFG_DQ_WIDTHAll possible values
DDR_DDRC_CFG_CWL_CFG_CWL(DDR3/3L/4)

All possible values
DDR_DDRC_CFG_CL_CFG_CL(DDR3/3L/4)All possible values
DDR_DDRC_CFG_WL_CFG_WL(LPDDR3/4)All possible values
DDR_DDRC_CFG_RL_CFG_RL(LPDDR3/4)All possible values
DDR_DDRC_CFG_CLK_FREQAll possible values

The following are the MSS DDR model limitations.

  • AXI transactions with 64-bit data only are supported. There is no support for word (32-bit), halfword (16-bit) based, and byte (8-bit) based AXI transactions.
  • Supports Burst Length of Fixed BL8 only.

In page hits and page misses in real time applications, this simulation model always considers page hits to avoid latencies caused by page misses.

You can access MSS DDR from any FIC interface and choose to share (compromise) bandwidth to the QoS initiator. By default, this QoS initiator is enabled and accesses DDR with default configurations. See QoS Parameter for more details.

The fabric initiator can access the DDR memory with the following AXI address region.

Table 20-11. AXI Address Region
Type64-bit Address Start64-bit Address End32-bit Address Start32-bit Address End
Non-Cache access0x14_0000_00000x17_ffff_ffff0xc000_00000xcfff_ffff
Non-Cache WCB access0x18_0000_00000x1b_ffff_ffff0xd000_00000xdfff_ffff

In DDR Memory Partition tab of MSS stand-alone configurator, the DDR memory is partitioned into Cached and Non-Cached region as shown in the following figure.

Figure 20-8. DDR Memory Partition

The stand-alone MSS configurator calculates the Physical DDR offset for each region, and this information is also used by the MSS simulation model. At present, the MSS-DDR simulation model supports access of Non-Cache region only from FPGA fabric.

After configuring the MSS-DDR and creating a Libero project, you can launch the pre-synthesis simulation. The following is an example of a simulation log of a fabric initiator, for example, PCIe-BFM accessing MSS-DDR.

###########################################################################
# AMBA BFM Model
# Version 2.1 22Dec08
#  
# Opening BFM Script file PCIE_1.vec
# Read 41 Vectors - Compiler Version 26.28
# BFM :Filenames referenced in Vectors
# PF_PCIE_C1_PF_PCIE_C1_0_PF_PCIE_PCIE_1_user.bfm
# BFM:22:writemultiple64 x c7000000 00000000 ... at 105 ns
# BFM: Data Write c7000000 0000000000000001
# BFM:24:readmultchk64 x c7000000 00000000 ... at 145 ns
# BFM: Data Write c7000008 0000000000000002
# Writing to DDR3 Memory @ rank = 0, bank = 00, row = 00700, col = 00000000, data = 00000001
# Writing to DDR3 Memory @ rank = 0, bank = 00, row = 00700, col = 00000001, data = 00000000
# Writing to DDR3 Memory @ rank = 0, bank = 00, row = 00700, col = 00000002, data = 00000002
# Writing to DDR3 Memory @ rank = 0, bank = 00, row = 00700, col = 00000003, data = 00000000
# Writing to DDR3 Memory @ rank = 0, bank = 00, row = 00700, col = 00000004, data = 00000003
# Writing to DDR3 Memory @ rank = 0, bank = 00, row = 00700, col = 00000005, data = 00000000
# Writing to DDR3 Memory @ rank = 0, bank = 00, row = 00700, col = 00000006, data = xxxxxxxx
# Writing to DDR3 Memory @ rank = 0, bank = 00, row = 00700, col = 00000007, data = xxxxxxxx
# BFM: Data Write c7000010 0000000000000003
# Reading from DDR3 Memory @ rank = 0, bank = 00, row = 00700, col = 00000000, data = 00000001
# Reading from DDR3 Memory @ rank = 0, bank = 00, row = 00700, col = 00000001, data = 00000000
# Reading from DDR3 Memory @ rank = 0, bank = 00, row = 00700, col = 00000002, data = 00000002
# Reading from DDR3 Memory @ rank = 0, bank = 00, row = 00700, col = 00000003, data = 00000000
# Reading from DDR3 Memory @ rank = 0, bank = 00, row = 00700, col = 00000004, data = 00000003
# Reading from DDR3 Memory @ rank = 0, bank = 00, row = 00700, col = 00000005, data = 00000000
# Reading from DDR3 Memory @ rank = 0, bank = 00, row = 00700, col = 00000006, data = xxxxxxxx
# Reading from DDR3 Memory @ rank = 0, bank = 00, row = 00700, col = 00000007, data = xxxxxxxx
# BFM: Data Read c7000000 0000000000000001 MASK:ffffffffffffffff at 385.000000ns
# BFM:27:return
# BFM: Data Read c7000008 0000000000000002 MASK:ffffffffffffffff at 395.000000ns
# BFM: Data Read c7000010 0000000000000003 MASK:ffffffffffffffff at 405.000000ns
#############################################################################
#  
# PCIE1 BFM Simulation Complete - 3 Instructions - NO ERRORS
#  
#############################################################################

You can disable the row and column related prints coming from the emulated DDR memory by using vsim commands as listed in following table.

Table 20-12. MSS DDR vsim Parameters
ParameterDescriptionValue
DEBUG_MEM

Enable/disable the prints coming from DDR memory in simulation log.

You can change the value of this parameter through vsim command as follows.

To disable the prints:

vsim -L polarfire -L presynth -t 1ps -gDEBUG_MEM=0 presynth.tb
  • 1: Prints row and column related information in the simulation log (Default)
  • 0: Does not print row and column related information in simulation log

The following is an example of a simulation log where PCIe-BFM accessing MSS-DDR with DDR memory and prints are disabled.

###########################################################################
# AMBA BFM Model
# Version 2.1 22Dec08
#  
# Opening BFM Script file PCIE_1.vec
# Read 41 Vectors - Compiler Version 26.28
# BFM :Filenames referenced in Vectors
# PF_PCIE_C1_PF_PCIE_C1_0_PF_PCIE_PCIE_1_user.bfm
# BFM:22:writemultiple64 x c7000000 00000000 ... at 105 ns
# BFM: Data Write c7000000 0000000000000001
# BFM:24:readmultchk64 x c7000000 00000000 ... at 145 ns
# BFM: Data Write c7000008 0000000000000002
# BFM: Data Write c7000010 0000000000000003
# BFM: Data Read c7000000 0000000000000001 MASK:ffffffffffffffff at 385.000000ns
# BFM:27:return
# BFM: Data Read c7000008 0000000000000002 MASK:ffffffffffffffff at 395.000000ns
# BFM: Data Read c7000010 0000000000000003 MASK:ffffffffffffffff at 405.000000ns
#############################################################################
#  
# PCIE1 BFM Simulation Complete - 3 Instructions - NO ERRORS
#  
#############################################################################

DDR Memory Initialization

DDR memory is modeled as a sparse array, and it allows you to initialize DDR memory content with the .mem file. The pre-initialized DDR memory helps in many applications by avoiding you to perform first AXI write transactions and then readback, instead, the fabric ​host can now start reading the DDR memory from the start of the simulation. Follow the steps to initialize the DDR memory:
  1. Prepare a user .mem file with the AXI address and data.
  2. Execute a python script that converts the user .mem file to ddr .mem file. The simulation model reads the .mem file The address and data content from this file is used to initialize the internal memory array.
  3. Run a simulation to see and use the initialized data.

User memory file (.mem)

Follow the instructions while creating a user .mem file:

  • The AXI address must start with "@" in each address line, and it must be within the range as listed in the following table.
    Table 20-13. Configurable Address in User Memory File
    Address SegmentRange
    32-bit address segment0xC000_0000 to 0xCFFF_FFFF
    38-bit address segment0x14_0000_0000 to 0x17_FFFF_FFFF
    Tip: The memory contents can be distributed by specifying multiple AXI start addresses of the corresponding segment. The model automatically calculates incremental addresses for each location within the segment.
  • For DQ_WIDTH = 16 configuration, specify the AXI address with offset of 0x10 only. The maximum address that can be given in user mem file is 0xCFFF_FFF0 for 32-bit address and 0x17_FFFF_FFF0 for 38-bit address. The AXI data to be initialized must have width = (DQ_WIDTH * BL_MAX) = 16*8 = 128 bits.
    Important: At present, only BL_MAX = 8 is supported in simulation.

    The following code block shows the user memory file format.

    @ 32-bit AXI address
    128 bits of AXI data
    128 bits of AXI data
    .
    .
    128 bits of AXI data
    @ 38-bit AXI address
    128 bits of AXI data
    128 bits of AXI data
    .
    .
    128 bits of AXI data
    
  • For DQ_WIDTH=32 configuration, specify the AXI address with offset of 0x20 only. The maximum address that can be given in the user mem file is 0xCFFF_FFE0 for 32-bit address and 0x17_FFFF_FFE0 for 38-bit address. The AXI data to be initialized must have width = (DQ_WIDTH * BL_MAX) = 32*8 = 256 bits.
    Important: At present, only BL_MAX = 8 is supported in simulation.

    The following code block shows the user memory file format.

    @ 32-bit AXI address
    256 bits of AXI data
    256 bits of AXI data
    .
    .
    128 bits of AXI data
    @ 38-bit AXI address
    256 bits of AXI data
    256 bits of AXI data
    .
    .
    256 bits of AXI data
    
  • If the AXI data width in each line of the user memory file is less than (DQ_WIDTH * BL_MAX), then the MSB bits are initialized with "0" in simulation. If the AXI data width in each line of memory file is greater than (DQ_WIDTH * BL_MAX), then all the bits are initialized with "x" in simulation.

Python Script Execution

Once the user .mem file is generated, parse this through a python script that generates a ddr mem file. This script converts AXI address to DDR Physical address as per DDR configuration. To run this script, Python3 must be installed on your PC.
Important: Generate the ddr mem file with the name “PFSoC_MSS_DDR_INIT.mem” only, and it must be available in the simulation folder of the Libero design project for the simulation to run.

The following are the arguments to the script:

  • -netlist_path followed by the name and location of netlist generated by pfsoc mss configurator (.v file).
  • -user_mem_path followed by the name and location of the user memory file.
  • -ddr_mem_path followed by the name “PFSoC_MSS_DDR_INIT.mem” and the location of the ddr mem file.

Syntax:

pfsoc_mss_ddr_init_v2.py -netlist_path <path to netlist file> -user_mem_path <path to input user mem file> -ddr_mem_path <path to output ddr mem file>

The following figure shows an example of the execution of the script in Cygwin terminal.

Figure 20-9. Execution of Script in Cygwin Terminal

Running a simulation

The generated ddr mem file must be named as PFSoC_MSS_DDR_INIT.mem, and it must be available in the simulation folder of the Libero design project for simulation to run. To run a simulation, add +PFSoC_MSS_DDR_INIT_FILE as an additional option in Command > Project settings > Vsim commands > Additional options as shown in the following figure.

Figure 20-10. Project Settings

With this additional Vsim option, the DDR simulation model invokes the task to read the contents from ddr mem file and initializes the internal memory array. The following examples show user mem file contents along with the initialized array in simulation.

  • User mem file for DQ_WIDTH = 16, BL_MAX = 8
    @C0000000
    06967346CDB6CCA21AE9AF8F3A6E9214  
    @C0000020
    06967346CDB6CCA21AE9AF8F3A6E9214
    7FA596AB8AC68D27EC35BFECC46B376E
    5A79211F6A8908C93C98A549E62C5DA9
    63FAAC6091B17839AB0B562D323CA51E
    501C37F12E4CA0A4C7EA3B8A9BF6279B
    36C9B82EEF96B7347B1FA7EC1A9FF18D
    @CFFFFFF0
    05E7A8E08DF5F46333A09306618C0E3B
    @1400000000
    E4B5EBEE9490330FCE5D1363A3EC87C7
    @1400000020
    52DB6E20042C0369F87425568F9D0B23
    4E9CD44A938EE3B6FB5FED6565E1B655
    58F737326DA54C9BC236B4F42D47DFC8
    @14FFFFFFF0
    12345678901234567891234567891234
    
    Figure 20-11. Initialized DDR Memory Array
  • User mem file for DQ_WIDTH = 32, BL_MAX = 8
    @C0000000
    06967346CDB6CCA21AE9AF8F3A6E921406967346CDB6CCA21AE9AF8F3A6E9214  
    @C0000020						
    06967346CDB6CCA21AE9AF8F3A6E921406967346CDB6CCA21AE9AF8F3A6E9214
    7FA596AB8AC68D27EC35BFECC46B376E7FA596AB8AC68D27EC35BFECC46B376E
    5A79211F6A8908C93C98A549E62C5DA95A79211F6A8908C93C98A549E62C5DA9
    63FAAC6091B17839AB0B562D323CA51E63FAAC6091B17839AB0B562D323CA51E
    501C37F12E4CA0A4C7EA3B8A9BF6279B501C37F12E4CA0A4C7EA3B8A9BF6279B
    36C9B82EEF96B7347B1FA7EC1A9FF18D36C9B82EEF96B7347B1FA7EC1A9FF18D
    @CFFFFFE0
    05E7A8E08DF5F46333A09306618C0E3B05E7A8E08DF5F46333A09306618C0E3B
    @1400000000
    E4B5EBEE9490330FCE5D1363A3EC87C7E4B5EBEE9490330FCE5D1363A3EC87C7
    @1400000020
    52DB6E20042C0369F87425568F9D0B2352DB6E20042C0369F87425568F9D0B23
    4E9CD44A938EE3B6FB5FED6565E1B6554E9CD44A938EE3B6FB5FED6565E1B655
    58F737326DA54C9BC236B4F42D47DFC858F737326DA54C9BC236B4F42D47DFC8
    @14FFFFFFE0
    1234567890123456789123456789123412345678901234567891234567891234
    
    Figure 20-12. Initialized DDR Memory Array