### DFI Phase Adapter Example Source: https://github.com/enjoy-digital/litedram/blob/master/litedram/phy/lpddr4/README.md Example of DFI Phase Adapter for translating DFI commands to LPDDR4 command sequences. ```python class DFIPhaseAdapter(Module): def __init__(self, pads, clk_freq, cmd_latency=1): self.cmd_latency = cmd_latency self.pads = pads # DFI interface self.dfi = DFIInterface(pads.dfi) # Commands self.cmd_valid = Signal() self.cmd_ready = Signal() self.cmd_payload = Signal(Command) # Subcommands self.subcmd_valid = Signal() self.subcmd_ready = Signal() self.subcmd_payload = Signal(SubCommand) # Command translation self.subcmd_translation = { Command.ACT: SubCommand.ACT, Command.PRE: SubCommand.PRE, Command.PREA: SubCommand.PREA, Command.REF: SubCommand.REF, Command.REFAB: SubCommand.REFAB, Command.MRS: SubCommand.MRS, Command.ZQC: SubCommand.ZQC, Command.NOP: SubCommand.NOP, Command.PDEX: SubCommand.PDEX, Command.PDEA: SubCommand.PDEA, Command.POWERDOWN: SubCommand.POWERDOWN, Command.CKEOFF: SubCommand.CKEOFF, Command.CKEOFFAB: SubCommand.CKEOFFAB, Command.CKEON: SubCommand.CKEON, Command.CKEONAB: SubCommand.CKEONAB, Command.DLLK: SubCommand.DLLK, Command.DLLKAB: SubCommand.DLLKAB, Command.WRITE: SubCommand.WRITE, Command.READ: SubCommand.READ, Command.MASKEDWRITE: SubCommand.MASKEDWRITE, Command.READ_AP: SubCommand.READ_AP, Command.WRITE_AP: SubCommand.WRITE_AP, Command.READ_AP_ODT: SubCommand.READ_AP_ODT, Command.WRITE_AP_ODT: SubCommand.WRITE_AP_ODT, } # ... (rest of the class) ``` -------------------------------- ### Example LPDDR4 Simulation Log Source: https://github.com/enjoy-digital/litedram/blob/master/litedram/phy/lpddr4/README.md A sample log output from the LPDDR4 PHY simulation, showing initialization, commands, and read leveling. ```text [ 50000 ps] [INFO] RESET released [ 50000 ps] [WARN] tINIT1 violated: RESET deasserted too fast [ 50000 ps] [INFO] CKE rising edge [ 50000 ps] [WARN] tINIT3 violated: CKE set HIGH too fast after RESET being released [ 100000 ps] [INFO] FSM reset --========== Initialization ============-- Initializing SDRAM @0x40000000... Switching SDRAM to software control. [ 2000052500 ps] [INFO] FSM: RESET -> EXIT-PD [ 2002055000 ps] [INFO] FSM: EXIT-PD -> MRW [ 2199950000 ps] [INFO] RESET asserted [ 2199950000 ps] [INFO] CKE falling edge [ 2205390000 ps] [INFO] RESET released [ 98205990000 ps] [INFO] CKE rising edge [ 98302540000 ps] [INFO] MRW: MR[ 1] = 0x14 [ 98351300000 ps] [INFO] MRW: MR[ 2] = 0x09 [ 98400160000 ps] [INFO] MRW: MR[11] = 0x00 [ 98448960000 ps] [INFO] MPC: ZQC-START [ 98448962500 ps] [INFO] FSM: MRW -> ZQC [ 98497720000 ps] [INFO] MPC: ZQC-LATCH [ 98497722500 ps] [INFO] FSM: ZQC -> NORMAL Read leveling: m0, b0: |[ 98731720000 ps] [INFO] ACT: bank=0 row= 0 [ 98754895000 ps] [INFO] MASKED-WRITE: bank=0 row= 0 col= 0 [ 98763315000 ps] [INFO] READ: bank=0 row= 0 col= 0 [ 98767340000 ps] [INFO] PRE: bank = 0 [ 98802380000 ps] [INFO] ACT: bank=0 row= 0 [ 98825555000 ps] [INFO] MASKED-WRITE: bank=0 row= 0 col= 0 [ 98833975000 ps] [INFO] READ: bank=0 row= 0 col= 0 [ 98838000000 ps] [INFO] PRE: bank = 0 ``` -------------------------------- ### Fine-grained Log Level Control Source: https://github.com/enjoy-digital/litedram/blob/master/litedram/phy/lpddr4/README.md Example of controlling log levels for specific modules during simulation. ```bash python litedram/phy/lpddr4/simsoc.py --log-level cmd=info,data=debug ``` -------------------------------- ### Example DFI Command Sequence Structure Source: https://context7.com/enjoy-digital/litedram/llms.txt This is a comment indicating the structure of a DFI command sequence, typically used with litedram.init sequences. Each entry includes a description, address, bank, command string, and delay cycles. ```python # Controlled from software using litedram.init sequences: # from litedram.init import get_ddr3_phy_init_sequence # init_seq, mr_seq = get_ddr3_phy_init_sequence(phy_settings, timing_settings) # Each entry: (description, address, bank, cmd_str, delay_cycles) ``` -------------------------------- ### Run All Unit Tests Source: https://github.com/enjoy-digital/litedram/blob/master/README.md Execute all available unit tests for the LiteDRAM project. Ensure Python 3.6+ and LiteX are installed. ```sh ./setup.py test ``` -------------------------------- ### LPDDR4 Command Mapping Source: https://github.com/enjoy-digital/litedram/blob/master/litedram/phy/lpddr4/README.md Example of mapping LPDDR4 subcommands to CS/CA sequences using the Command module. ```python class Command(object): def __init__(self, cmd, subcmd, cs, ca, dq, odt): self.cmd = cmd self.subcmd = subcmd self.cs = cs self.ca = ca self.dq = dq self.odt = odt def __repr__(self): return "Command(cmd=%r, subcmd=%r, cs=%r, ca=%r, dq=%r, odt=%r)" % ( self.cmd, self.subcmd, self.cs, self.ca, self.dq, self.odt) # ... (rest of the class) ``` -------------------------------- ### LiteDRAM Verilog RTL Generator Configuration Source: https://context7.com/enjoy-digital/litedram/llms.txt Example YAML configuration for the litedram_gen tool. Defines board specifics, memory type, CPU, and user ports for generating a self-contained Verilog core. ```yaml # arty.yml — example for Xilinx Arty A7 board { "speedgrade": -1, "cpu": "vexriscv", "memtype": "DDR3", "uart": "rs232", "cmd_latency": 0, "sdram_module": "MT41K128M16", "sdram_module_nb": 2, "sdram_rank_nb": 1, "sdram_phy": "A7DDRPHY", "rtt_nom": "60ohm", "rtt_wr": "60ohm", "ron": "34ohm", "input_clk_freq": 100e6, "sys_clk_freq": 100e6, "iodelay_clk_freq":200e6, "cmd_buffer_depth":16, "user_ports": { "axi_0": {"type": "axi", "id_width": 32}, "wishbone_0": {"type": "wishbone", "block_until_ready": true}, "avalon_0": {"type": "avalon"}, "native_0": {"type": "native"}, "fifo_0": {"type": "fifo", "base": "0x00000000", "depth": "0x01000000"} } } ``` -------------------------------- ### Initialize DFI Interface with DFIInjector Source: https://context7.com/enjoy-digital/litedram/llms.txt Instantiate DFIInjector to wrap a DFI interface with per-phase CSR registers for low-level DFI command injection during DRAM initialization. Configure addressbits, bankbits, nranks, databits, and nphases according to your DRAM setup. ```python from litedram.dfii import DFIInjector # DFIInjector wraps a complete DFI interface with per-phase CSR registers dfi_injector = DFIInjector( addressbits = 14, bankbits = 3, nranks = 1, databits = 32, nphases = 4, ) self.submodules += dfi_injector ``` -------------------------------- ### Configure PMIC for 1.5V DRAM Operation Source: https://github.com/enjoy-digital/litedram/blob/master/litedram/phy/rpc/README.md Example code to configure the Power Management IC (PMIC) to supply 1.5V to the RPC DRAM. This involves I2C writes to specific registers for Vbuck2A and Vbuck2B. ```c #include unsigned char vbuck2_15 = 0x78; i2c_write(0x58, 0xa3, &vbuck2_15, sizeof(vbuck2_15)); // Vbuck2A i2c_write(0x58, 0xb4, &vbuck2_15, sizeof(vbuck2_15)); // Vbuck2B ``` -------------------------------- ### MRS and ZQC Command Handling in Initialization Source: https://github.com/enjoy-digital/litedram/blob/master/litedram/phy/lpddr4/README.md Illustrates how MRS and ZQC commands are handled during LPDDR4 initialization. ```python # MRS and ZQC commands are handled in the initialization code # ... # MRS command: DFI.address encodes both address and value # ZQC command: DFI.address is interpreted as MPC operand # ... # Example snippet from litedram/init.py (conceptual): # if command == DFI.MRS: # address = ddrphy.dfi.address >> 8 # value = ddrphy.dfi.address & 0xff # ddrphy.send_mrs(address, value) # elif command == DFI.ZQC: # mpc_operand = ddrphy.dfi.address # ddrphy.send_zqc(mpc_operand) # ... ``` -------------------------------- ### Initialize Xilinx Series 7 DDR PHY Source: https://context7.com/enjoy-digital/litedram/llms.txt Configure the S7DDRPHY for DDR3 memory with ODELAY calibration. Ensure sys_clk_freq and iodelay_clk_freq are set correctly for your system. ```python from litedram.phy.s7ddrphy import S7DDRPHY phy = S7DDRPHY( pads = platform.request("ddram"), with_odelay = True, # required for write leveling memtype = "DDR3", nphases = 4, sys_clk_freq = 100e6, iodelay_clk_freq = 200e6, cl = None, # auto cwl = None, # auto cmd_latency = 0, write_latency_calibration = True, ) # phy.settings -> PhySettings # phy.dfi -> DFI Interface # CSRs for training: _wlevel_en, _wlevel_strobe, _dly_sel, _rdly_dq_rst, etc. ``` -------------------------------- ### Run LPDDR4 PHY Simulation with Tracing Source: https://github.com/enjoy-digital/litedram/blob/master/litedram/phy/lpddr4/README.md Command to run the LPDDR4 PHY simulation with tracing enabled, generating FST files for GTKWave. ```bash python litedram/phy/lpddr4/simsoc.py --log-level info --finish-after-memtest --trace --trace-fst --gtkw-savefile ``` -------------------------------- ### Initialize LiteDRAMFIFO Source: https://context7.com/enjoy-digital/litedram/llms.txt Instantiate a DRAM-backed streaming FIFO. Use with_bypass=True to add an optional SRAM FIFO for reduced latency with small data amounts. ```python from litedram.frontend.fifo import LiteDRAMFIFO write_port = crossbar.get_port(mode="write") read_port = crossbar.get_port(mode="read") fifo = LiteDRAMFIFO( data_width = 128, base = 0x0000_0000, # DRAM start address (bytes) depth = 0x0100_0000, # FIFO depth in bytes write_port = write_port, read_port = read_port, with_bypass = True, # add SRAM bypass FIFO to reduce latency bypass_depth = 64, # bypass FIFO depth in entries writer_fifo_depth = 16, reader_fifo_depth = 16, ) self.submodules += fifo ``` -------------------------------- ### Instantiate GENSDRPHY Source: https://context7.com/enjoy-digital/litedram/llms.txt Instantiates a generic vendor-agnostic SDR PHY using SDRInput/SDROutput/SDRTristate primitives. Works on various FPGAs with 1:1 or 1:2 frequency ratios. System clock frequency and CAS latency can be specified. ```python from litedram.phy.gensdrphy import GENSDRPHY phy = GENSDRPHY( pads = platform.request("sdram"), sys_clk_freq = 100e6, cl = None, # auto-computed from frequency ) # phy.settings -> PhySettings (pass to LiteDRAMController) ``` -------------------------------- ### Initialize Lattice ECP5 DDR3 PHY Source: https://context7.com/enjoy-digital/litedram/llms.txt Configure the ECP5DDRPHY for DDR3 memory. This PHY supports a 1:2 frequency ratio and utilizes built-in ECP5 primitives. ```python from litedram.phy.ecp5ddrphy import ECP5DDRPHY phy = ECP5DDRPHY( pads = platform.request("ddram"), sys_clk_freq = 100e6, ) # phy.settings -> PhySettings # phy.dfi -> DFI Interface ``` -------------------------------- ### Initialize Artix-7 DDR PHY Source: https://context7.com/enjoy-digital/litedram/llms.txt Use the A7DDRPHY convenience subclass for Artix-7 FPGAs. This configuration uses IDELAY only and does not require ODELAY. ```python from litedram.phy.s7ddrphy import A7DDRPHY, K7DDRPHY, V7DDRPHY, KU DDRPHY # Artix-7 (no ODELAY, uses IDELAY only) phy = A7DDRPHY(pads=platform.request("ddram"), memtype="DDR3", sys_clk_freq=100e6, iodelay_clk_freq=200e6) ``` -------------------------------- ### Initialize LiteDRAMBISTChecker Source: https://context7.com/enjoy-digital/litedram/llms.txt Initializes a DRAM pattern verifier for Built-In Self Test. Compares read data against expected patterns and reports errors. ```python from litedram.frontend.bist import LiteDRAMBISTChecker dram_port = crossbar.get_port() bist_check = LiteDRAMBISTChecker(dram_port) self.submodules += bist_check ``` -------------------------------- ### Configure LiteDRAM PHY Settings Source: https://context7.com/enjoy-digital/litedram/llms.txt Use PhySettings to describe PHY characteristics like memory type, data width, DFI phase structure, and read/write latency. Optional electrical settings can be added using add_electrical_settings. ```python from litedram.common import PhySettings phy_settings = PhySettings( phytype = "S7DDRPHY", memtype = "DDR3", databits = 16, # 16 DQ lines dfi_databits = 32, # per-phase DFI data width nphases = 4, # 4 DFI phases (1:4 ratio) rdphase = 2, # READ command issued on phase 2 wrphase = 3, # WRITE command issued on phase 3 cl = 7, # CAS latency (DRAM clocks) cwl = 6, # CAS Write Latency read_latency = 5, # MC clock cycles from rddata_en to rddata_valid write_latency = 2, # MC clock cycles from wrdata_en to wrdata write_leveling = True, write_dq_dqs_training = True, write_latency_calibration = True, read_leveling = True, ) # Optional DDR3/DDR4 electrical settings phy_settings.add_electrical_settings( rtt_nom = "60ohm", rtt_wr = "60ohm", ron = "34ohm", ) ``` -------------------------------- ### Instantiate SDRAMModule from SPD Data Source: https://context7.com/enjoy-digital/litedram/llms.txt Parses geometry and timings directly from raw SPD EEPROM bytes. Requires SPD data and system clock frequency. ```python # Parse geometry and timings directly from raw SPD EEPROM bytes spd_bytes = [0x23, 0x11, 0x0b, ...] # from I2C read or 'spdread' in LiteX BIOS module2 = SDRAMModule.from_spd_data(spd_bytes, clk_freq=100e6) ``` -------------------------------- ### Instantiate LiteDRAMController Source: https://context7.com/enjoy-digital/litedram/llms.txt Instantiates a pipelined DRAM memory controller. Requires PHY settings, geometry and timing settings from a DRAM module, system clock frequency, and controller settings. ```python from litedram.core.controller import LiteDRAMController, ControllerSettings from litedram import modules as litedram_modules from litedram.common import get_default_cl_cwl module = litedram_modules.MT41K256M16(clk_freq=100e6, rate="1:4") controller = LiteDRAMController( phy_settings = phy_settings, # PhySettings instance from PHY geom_settings = module.geom_settings, timing_settings = module.timing_settings, clk_freq = 100e6, controller_settings = ControllerSettings( cmd_buffer_depth = 16, with_bandwidth = True, ), ) # controller.interface -> LiteDRAMInterface (connect to crossbar) # controller.dfi -> DFI Interface (connect to PHY) # controller.get_csrs() -> list of CSRs for read/write monitoring ``` -------------------------------- ### Run LPDDR4 PHY Simulation Source: https://github.com/enjoy-digital/litedram/blob/master/litedram/phy/lpddr4/README.md Command to run the LPDDR4 PHY simulation with basic logging and memory test completion. ```bash python litedram/phy/lpddr4/simsoc.py --log-level info --finish-after-memtest --double-rate-phy --l2-size 0 ``` -------------------------------- ### Instantiate Predefined DDR3 Module Source: https://context7.com/enjoy-digital/litedram/llms.txt Instantiates a known DDR3 module with specified clock frequency, data rate, and speed grade. Useful for obtaining geometry and timing settings for a specific DRAM part. ```python from litedram import modules as litedram_modules # Instantiate a known DDR3 module at 100 MHz system clock, 1:4 ratio module = litedram_modules.MT41K128M16( clk_freq = 100e6, rate = "1:4", speedgrade = "-125", # optional: "-125", "-15E", etc. ) geom_settings = module.geom_settings timing_settings = module.timing_settings print(f"Banks: {2**geom_settings.bankbits}") # 8 print(f"Rows: {2**geom_settings.rowbits}") # 16384 print(f"Cols: {2**geom_settings.colbits}") # 1024 print(f"tREFI: {timing_settings.tREFI}") # cycles ``` -------------------------------- ### Configure LiteDRAM Controller Settings Source: https://context7.com/enjoy-digital/litedram/llms.txt Use ControllerSettings to tune memory controller behavior, including command buffering depth, read/write scheduling policy, refresh, and auto-precharge. Options like with_bandwidth and with_refresh enable specific features. ```python from litedram.core.controller import ControllerSettings controller_settings = ControllerSettings( cmd_buffer_depth = 16, # Deeper pipeline for higher throughput cmd_buffer_buffered = False, read_time = 32, # Max cycles on reads before switching to writes write_time = 16, # Max cycles on writes before switching to reads with_bandwidth = True, # Enable bandwidth CSR counters with_refresh = True, refresh_zqcs_freq = 1e0, # ZQCS every second refresh_postponing = 4, # Allow up to 4 postponed refreshes with_auto_precharge = True, address_mapping = "ROW_BANK_COL", # Address interleaving scheme bank_byte_alignment = 0, ) ``` -------------------------------- ### Initialize LiteDRAMNativePortECC Source: https://context7.com/enjoy-digital/litedram/llms.txt Initializes a SECDED ECC wrapper for native DRAM ports. Use with_error_injection and with_we_error_detection for advanced testing. ```python from litedram.frontend.ecc import LiteDRAMNativePortECC # user_port: 64-bit wide (user data) # dram_port: 72-bit wide (64 data + 8 ECC bits per burst cycle) user_port = crossbar.get_port(data_width=64) dram_port = crossbar.get_port(data_width=72) ecc = LiteDRAMNativePortECC( port_from = user_port, port_to = dram_port, burst_cycles = 8, with_error_injection = True, # adds flip CSR for fault injection testing with_we_error_detection = True, # detect sub-word write granularity violations ) self.submodules += ecc ``` -------------------------------- ### Initialize LiteDRAMDMAWriter Source: https://context7.com/enjoy-digital/litedram/llms.txt Initializes a DMA writer for streaming data to DRAM. Use with_csr=True for register-controlled looping DMA. ```python from litedram.frontend.dma import LiteDRAMDMAWriter dram_port = crossbar.get_port() dma_writer = LiteDRAMDMAWriter( port = dram_port, fifo_depth = 16, fifo_buffered = False, with_csr = True, ) self.submodules += dma_writer ``` -------------------------------- ### Instantiate LiteDRAMNativePort Source: https://context7.com/enjoy-digital/litedram/llms.txt Directly instantiates a low-level streaming port to the DRAM controller, typically used for adapters or testbenches. Configurable by mode, address width, data width, clock domain, and ID. ```python from litedram.common import LiteDRAMNativePort from migen import * # Direct instantiation (for adapters or testbenches) port = LiteDRAMNativePort( mode = "both", # "read", "write", or "both" address_width = 25, # word address width data_width = 128, # bits clock_domain = "sys", id = 0, ) # Typical usage in Migen combinational logic: m = Module() m.comb += [ port.cmd.valid.eq(trigger), port.cmd.we.eq(1), # 1 = write, 0 = read port.cmd.addr.eq(word_address), # word-granularity (not byte) port.wdata.valid.eq(trigger), port.wdata.data.eq(write_data), port.wdata.we.eq(0xFFFF), # byte enable mask (all bytes) ] # Read: wait for port.rdata.valid, then read port.rdata.data ``` -------------------------------- ### GENSDRPHY - Generic Vendor-Agnostic SDR PHY Source: https://context7.com/enjoy-digital/litedram/llms.txt A vendor-portable SDR PHY using SDRInput/SDROutput/SDRTristate primitives. Works on Xilinx, Altera, and Lattice FPGAs with 1:1 or 1:2 frequency ratios. ```APIDOC ### `GENSDRPHY` — Generic vendor-agnostic SDR PHY Vendor-portable SDR PHY using `SDRInput`/`SDROutput`/`SDRTristate` primitives. Works on Xilinx, Altera, and Lattice FPGAs with 1:1 or 1:2 frequency ratios. ### Instantiate GENSDRPHY ```python from litedram.phy.gensdrphy import GENSDRPHY phy = GENSDRPHY( pads = platform.request("sdram"), sys_clk_freq = 100e6, cl = None, # auto-computed from frequency ) # phy.settings -> PhySettings (pass to LiteDRAMController) ``` ``` -------------------------------- ### Initialize LiteDRAMNativePortConverter for Data-Width Conversion Source: https://context7.com/enjoy-digital/litedram/llms.txt Instantiate a data-width converter for LiteDRAM Native ports. Use for downconversion (wide user to narrow controller) or upconversion (narrow user to wide controller). ```python from litedram.frontend.adapter import LiteDRAMNativePortConverter from litedram.common import LiteDRAMNativePort # Downconvert: user sees 256-bit port, controller uses 128-bit port_wide = LiteDRAMNativePort(mode="both", address_width=24, data_width=256) port_narrow = LiteDRAMNativePort(mode="both", address_width=25, data_width=128) converter = LiteDRAMNativePortConverter(port_wide, port_narrow) self.submodules += converter # Upconvert: user sees 64-bit port, controller uses 128-bit port_64 = LiteDRAMNativePort(mode="both", address_width=26, data_width=64) port_128 = LiteDRAMNativePort(mode="both", address_width=25, data_width=128) converter2 = LiteDRAMNativePortConverter(port_64, port_128) self.submodules += converter2 ``` -------------------------------- ### Run Individual Unit Test Source: https://github.com/enjoy-digital/litedram/blob/master/README.md Execute a specific unit test by its module name. Replace 'test.test_name' with the actual test module. ```python python3 -m unittest test.test_name ``` -------------------------------- ### Configure LiteDRAM Geometry Settings Source: https://context7.com/enjoy-digital/litedram/llms.txt Use GeomSettings to capture the bank, row, and column address bit widths for configuring the controller and crossbar. The addressbits property is derived from the maximum of rowbits and colbits. ```python from litedram.common import GeomSettings geom_settings = GeomSettings( bankbits = 3, # 8 banks rowbits = 14, # 16K rows colbits = 10, # 1K columns ) # geom_settings.addressbits == max(rowbits, colbits) == 14 ``` -------------------------------- ### LiteDRAM DMA Reader Configuration Source: https://context7.com/enjoy-digital/litedram/llms.txt Set up a LiteDRAMDMAReader to fetch data from DRAM based on a stream of addresses. Configure FIFO depth and buffering as needed. ```python from litedram.frontend.dma import LiteDRAMDMAReader dram_port = crossbar.get_port() dma_reader = LiteDRAMDMAReader( port = dram_port, fifo_depth = 32, # max outstanding read requests fifo_buffered = True, # use BRAM FIFO with_csr = True, # expose CSR registers for BIOS/software control ) self.submodules += dma_reader ``` -------------------------------- ### Initialize LiteDRAMBISTGenerator Source: https://context7.com/enjoy-digital/litedram/llms.txt Initializes a DRAM pattern generator for Built-In Self Test. Configurable via CSR registers for base address, length, and random mode. ```python from litedram.frontend.bist import LiteDRAMBISTGenerator dram_port = crossbar.get_port() bist_gen = LiteDRAMBISTGenerator(dram_port) self.submodules += bist_gen ``` -------------------------------- ### AXI-MM to LiteDRAM Native Port Bridge Source: https://context7.com/enjoy-digital/litedram/llms.txt Implement a full AXI-MM to LiteDRAMNativePort converter. Supports burst decomposition, configurable buffering, and optional Read-Modify-Write mode. ```python from litedram.frontend.axi import LiteDRAMAXIPort, LiteDRAMAXI2Native from litex.soc.interconnect.axi import AXIInterface axi_port = AXIInterface(data_width=128, address_width=32, id_width=4) dram_port = crossbar.get_port(data_width=128) axi_bridge = LiteDRAMAXI2Native( axi = axi_port, port = dram_port, base_address = 0x4000_0000, size = 0x1000_0000, # 256MB window with_read_modify_write = False, ) self.submodules += axi_bridge # AXI write/read channels (aw/w/b and ar/r) map transparently # Burst transactions are decomposed to individual native port commands ``` -------------------------------- ### Combine DRAM Pad Records with PHYPadsCombiner Source: https://context7.com/enjoy-digital/litedram/llms.txt Use PHYPadsCombiner to merge pad records from independent DRAM chips. Use sel_group() to select command signals from a specific chip. ```python from litedram.common import PHYPadsCombiner # Combine two independent DDR chips into one pad record pads_a = platform.request("ddram", 0) pads_b = platform.request("ddram", 1) combined = PHYPadsCombiner([pads_a, pads_b]) combined.sel_group(0) # select command signals from chip 0 ``` -------------------------------- ### Initialize LiteDRAMNativePortCDC for Clock Domain Crossing Source: https://context7.com/enjoy-digital/litedram/llms.txt Instantiate a clock domain crossing adapter for LiteDRAM Native ports. Use when ports must cross clock domains, inserting asynchronous FIFOs for command, write data, and read data streams. ```python from litedram.frontend.adapter import LiteDRAMNativePortCDC from litedram.common import LiteDRAMNativePort port_sys = LiteDRAMNativePort(mode="both", address_width=25, data_width=128, clock_domain="sys") port_video = LiteDRAMNativePort(mode="both", address_width=25, data_width=128, clock_domain="video") cdc = LiteDRAMNativePortCDC( port_from = port_video, # source domain port_to = port_sys, # destination domain cmd_depth = 4, wdata_depth = 16, rdata_depth = 16, ) self.submodules += cdc ``` -------------------------------- ### ECP5DDRPHY — Lattice ECP5 DDR3 PHY Source: https://context7.com/enjoy-digital/litedram/llms.txt 1:2 frequency-ratio DDR3 PHY for Lattice ECP5, supporting 800 MT/s with built-in ECLKSYNC, CLKDIVF, and DQSBUFM primitives. ```APIDOC ## ECP5DDRPHY — Lattice ECP5 DDR3 PHY ### Description 1:2 frequency-ratio DDR3 PHY for Lattice ECP5, supporting 800 MT/s with built-in ECLKSYNC, CLKDIVF, and DQSBUFM primitives. ### Usage Example ```python from litedram.phy.ecp5ddrphy import ECP5DDRPHY phy = ECP5DDRPHY( pads = platform.request("ddram"), sys_clk_freq = 100e6, ) ``` ``` -------------------------------- ### Select Byte Lanes with PHYPadsReducer Source: https://context7.com/enjoy-digital/litedram/llms.txt Use PHYPadsReducer to select specific byte lanes from a DRAM pad record for testing. Ensure the correct byte lanes are specified in the modules list. ```python from litedram.common import PHYPadsReducer # Use only byte lanes 0 and 2 of a 4-lane DDR3 interface pads = platform.request("ddram") reduced = PHYPadsReducer(pads, modules=[0, 2]) ``` -------------------------------- ### LiteDRAMController - Pipelined DRAM Memory Controller Source: https://context7.com/enjoy-digital/litedram/llms.txt Instantiates per-bank state machines, the multiplexer, and the refresher. Exposes a LiteDRAMInterface on the user side and a DFI interface toward the PHY. Not usually instantiated directly. ```APIDOC ## `LiteDRAMController` — pipelined DRAM memory controller Instantiates per-bank state machines (`BankMachine`), the `Multiplexer`, and the `Refresher`. Exposes a `LiteDRAMInterface` on the user side and a DFI interface toward the PHY. Not usually instantiated directly — use `LiteDRAMCrossbar` which wraps it. ### Instantiate LiteDRAMController ```python from litedram.core.controller import LiteDRAMController, ControllerSettings from litedram import modules as litedram_modules from litedram.common import get_default_cl_cwl module = litedram_modules.MT41K256M16(clk_freq=100e6, rate="1:4") controller = LiteDRAMController( phy_settings = phy_settings, # PhySettings instance from PHY geom_settings = module.geom_settings, timing_settings = module.timing_settings, clk_freq = 100e6, controller_settings = ControllerSettings( cmd_buffer_depth = 16, with_bandwidth = True, ), ) # controller.interface -> LiteDRAMInterface (connect to crossbar) # controller.dfi -> DFI Interface (connect to PHY) # controller.get_csrs() -> list of CSRs for read/write monitoring ``` ``` -------------------------------- ### S7DDRPHY — Xilinx Series 7 DDR2/DDR3/DDR4 PHY Source: https://context7.com/enjoy-digital/litedram/llms.txt High-performance PHY for Xilinx FPGAs. Supports ODELAY/IDELAY calibration, write leveling, and read leveling. CSR-controlled training sequences are invoked by the LiteX BIOS at boot. ```APIDOC ## S7DDRPHY — Xilinx Series 7 DDR2/DDR3/DDR4 PHY ### Description High-performance PHY for Xilinx Artix-7, Kintex-7, and Virtex-7 FPGAs. Supports 1:2 and 1:4 frequency ratios with ODELAY/IDELAY calibration, write leveling, and read leveling. CSR-controlled training sequences are invoked by the LiteX BIOS at boot. ### Usage Example ```python from litedram.phy.s7ddrphy import S7DDRPHY phy = S7DDRPHY( pads = platform.request("ddram"), with_odelay = True, # required for write leveling memtype = "DDR3", nphases = 4, sys_clk_freq = 100e6, iodelay_clk_freq = 200e6, cl = None, # auto cwl = None, # auto cmd_latency = 0, write_latency_calibration = True, ) ``` ### Convenience Subclasses ```python from litedram.phy.s7ddrphy import A7DDRPHY, K7DDRPHY, V7DDRPHY, KU DDRPHY # Artix-7 (no ODELAY, uses IDELAY only) phy = A7DDRPHY(pads=platform.request("ddram"), memtype="DDR3", sys_clk_freq=100e6, iodelay_clk_freq=200e6) ``` ``` -------------------------------- ### SDRAMModule - Predefined DRAM Part Definitions Source: https://context7.com/enjoy-digital/litedram/llms.txt Defines base classes for predefined DRAM part definitions, providing geometry and timing parameters. Subclasses are named after real part numbers and can be instantiated directly or from SPD data. ```APIDOC ## `SDRAMModule` — base class for predefined DRAM part definitions Provides geometry (nbanks, nrows, ncols) and timing parameters for well-known DRAM components. Subclasses are named after real part numbers. Used to instantiate `GeomSettings` and `TimingSettings` automatically. ### Instantiate a known DDR3 module ```python from litedram import modules as litedram_modules # Instantiate a known DDR3 module at 100 MHz system clock, 1:4 ratio module = litedram_modules.MT41K128M16( clk_freq = 100e6, rate = "1:4", speedgrade = "-125", # optional: "-125", "-15E", etc. ) geom_settings = module.geom_settings timing_settings = module.timing_settings print(f"Banks: {2**geom_settings.bankbits}") # 8 print(f"Rows: {2**geom_settings.rowbits}") # 16384 print(f"Cols: {2**geom_settings.colbits}") # 1024 print(f"tREFI: {timing_settings.tREFI}") # cycles ``` ### Parse geometry and timings directly from raw SPD EEPROM bytes ```python # Parse geometry and timings directly from raw SPD EEPROM bytes spd_bytes = [0x23, 0x11, 0x0b, ...] # from I2C read or 'spdread' in LiteX BIOS module2 = SDRAMModule.from_spd_data(spd_bytes, clk_freq=100e6) ``` ``` -------------------------------- ### Generate Verilog RTL from YAML Config Source: https://context7.com/enjoy-digital/litedram/llms.txt Command to generate Verilog RTL using the litedram_gen tool with a specified YAML configuration file. The output includes synthesizable Verilog, C headers, register maps, and initialization scripts. ```bash # Generate Verilog RTL from YAML config litedram_gen arty.yml # Output: build/ directory with: # litedram_core.v — synthesizable Verilog # litedram_core.h — C header for software initialization # csr.json / csr.csv — register map # init.py — Python initialization sequences ``` -------------------------------- ### Configure LiteDRAM Timing Settings Source: https://context7.com/enjoy-digital/litedram/llms.txt Use TimingSettings to define DRAM timing parameters in controller clock cycles. These are typically derived from SDRAMModule rather than set manually. Parameters like tRP, tRCD, and tRFC are included. ```python from litedram.common import TimingSettings timing_settings = TimingSettings( tRP = 4, # Row Precharge time tRCD = 4, # RAS-to-CAS Delay tWR = 5, # Write Recovery time tWTR = 4, # Write-to-Read turnaround tREFI = 781, # Refresh Interval (cycles at 100 MHz: 64ms/8192 = 7.8us) tRFC = 26, # Refresh Cycle time tFAW = 16, # Four Activate Window tCCD = 4, # CAS-to-CAS Delay tRRD = 4, # RAS-to-RAS Delay tRC = None, # Row Cycle time (optional) tRAS = None, # Row Active time (optional) tZQCS = 64, # ZQ Calibration Short ) ``` -------------------------------- ### LPDDR4 PHY Directory Structure Source: https://github.com/enjoy-digital/litedram/blob/master/litedram/phy/lpddr4/README.md This snippet shows the directory structure for the LPDDR4 PHY code, including core files and test files. ```text litedram/phy/lpddr4/ ├── basephy.py ├── commands.py ├── __init__.py ├── s7phy.py ├── simphy.py ├── sim.py ├── simsoc.py └── utils.py test/ └── test_lpddr4.py ``` ```text litedram/ ├── init.py # LPDDR4 initialization sequence and other BIOS-related definitions ├── modules.py # LPDDR4 module: MT53E256M16D1 └── common.py # defined LPDDR4 burst length github/workflows/ └── ci.yml # dependencies for running Verilator ``` -------------------------------- ### LiteDRAMWishbone2Native — Wishbone to Native port bridge Source: https://context7.com/enjoy-digital/litedram/llms.txt Converts a Wishbone master bus to a `LiteDRAMNativePort`. Supports 1:1 and N:1 data-width ratios, burst merging for narrow-to-wide conversions, and transaction abort handling when `cyc` deasserts early. ```APIDOC ## LiteDRAMWishbone2Native — Wishbone to Native port bridge ### Description Converts a Wishbone master bus to a `LiteDRAMNativePort`. Supports 1:1 and N:1 data-width ratios, burst merging for narrow-to-wide conversions, and transaction abort handling when `cyc` deasserts early. ### Usage Example ```python from litedram.frontend.wishbone import LiteDRAMWishbone2Native from litex.soc.interconnect import wishbone wb_port = wishbone.Interface(data_width=32, addressing="word") dram_port = crossbar.get_port(data_width=32) bridge = LiteDRAMWishbone2Native( wishbone = wb_port, port = dram_port, base_address = 0x4000_0000, # byte offset subtracted from Wishbone addresses ) self.submodules += bridge ``` ``` -------------------------------- ### LiteDRAMAXI2Native — AXI-MM to Native port bridge Source: https://context7.com/enjoy-digital/litedram/llms.txt Full AXI-MM to LiteDRAMNativePort converter with burst decomposition (FIXED/INCR/WRAP), configurable write/read data buffering, ID tracking, and optional Read-Modify-Write mode for ECC use cases. ```APIDOC ## LiteDRAMAXI2Native — AXI-MM to Native port bridge ### Description Full AXI-MM to LiteDRAMNativePort converter with burst decomposition (FIXED/INCR/WRAP), configurable write/read data buffering, ID tracking, and optional Read-Modify-Write mode for ECC use cases. ### Usage Example ```python from litedram.frontend.axi import LiteDRAMAXIPort, LiteDRAMAXI2Native from litex.soc.interconnect.axi import AXIInterface axi_port = AXIInterface(data_width=128, address_width=32, id_width=4) dram_port = crossbar.get_port(data_width=128) axi_bridge = LiteDRAMAXI2Native( axi = axi_port, port = dram_port, base_address = 0x4000_0000, size = 0x1000_0000, # 256MB window with_read_modify_write = False, ) self.submodules += axi_bridge ``` ``` -------------------------------- ### Wishbone to LiteDRAM Native Port Bridge Source: https://context7.com/enjoy-digital/litedram/llms.txt Convert a Wishbone master bus to a LiteDRAMNativePort. This bridge handles various data-width ratios and burst merging. ```python from litedram.frontend.wishbone import LiteDRAMWishbone2Native from litex.soc.interconnect import wishbone wb_port = wishbone.Interface(data_width=32, addressing="word") dram_port = crossbar.get_port(data_width=32) bridge = LiteDRAMWishbone2Native( wishbone = wb_port, port = dram_port, base_address = 0x4000_0000, # byte offset subtracted from Wishbone addresses ) self.submodules += bridge # Wishbone transactions now map to DRAM native-port reads/writes # cyc+stb high starts a transaction; ack is returned after completion ``` -------------------------------- ### LiteDRAMAvalonMM2Native — AvalonMM to Native port bridge Source: https://context7.com/enjoy-digital/litedram/llms.txt Converts an Altera/Intel AvalonMM master to a `LiteDRAMNativePort`. Supports burst transactions (up to configurable max_burst_length) and automatic data-width conversion. ```APIDOC ## LiteDRAMAvalonMM2Native — AvalonMM to Native port bridge ### Description Converts an Altera/Intel AvalonMM master to a `LiteDRAMNativePort`. Supports burst transactions (up to configurable max_burst_length) and automatic data-width conversion. ### Usage Example ```python from litedram.frontend.avalon import LiteDRAMAvalonMM2Native from litex.soc.interconnect import avalon av_port = avalon.AvalonMMInterface(data_width=64, address_width=32) dram_port = crossbar.get_port(data_width=64) av_bridge = LiteDRAMAvalonMM2Native( avalon = av_port, port = dram_port, max_burst_length = 16, base_address = 0x0000_0000, burst_increment = 1, ) self.submodules += av_bridge ``` ``` -------------------------------- ### LiteDRAMBISTChecker Source: https://context7.com/enjoy-digital/litedram/llms.txt The LiteDRAMBISTChecker is a DRAM pattern verifier that reads back DRAM data and compares it against the expected sequential or PRBS31 pattern. It reports the error count and location. ```APIDOC ## LiteDRAMBISTChecker ### Description Reads back DRAM data and compares it against the expected sequential or PRBS31 pattern. Reports error count and location. ### CSR interface - `reset`: write 1 to reset - `start`: write 1 to start - `base`: start address (bytes) - `end`: end address (bytes) - `length`: number of words to check - `random_data`: must match generator setting - `random_addr`: must match generator setting - `done`: read 1 when complete - `errors`: number of mismatches detected ``` -------------------------------- ### LiteDRAMCrossbar.get_port() - Add a memory port Source: https://context7.com/enjoy-digital/litedram/llms.txt The primary user-facing API for adding memory ports to the controller. Instantiates a new LiteDRAMNativePort and registers it with the crossbar's round-robin arbitration, handling CDC and data-width conversion transparently. ```APIDOC ## `LiteDRAMCrossbar.get_port()` — add a memory port to the controller The primary user-facing API. Instantiates a new `LiteDRAMNativePort` and registers it with the crossbar's round-robin arbitration. Handles CDC and data-width conversion transparently. ### Add memory ports using get_port() ```python from litedram.core.crossbar import LiteDRAMCrossbar crossbar = LiteDRAMCrossbar(controller.interface) # Port at system clock, native controller width port0 = crossbar.get_port() # Port at half controller data width (upconverted internally) port1 = crossbar.get_port(data_width=crossbar.controller.data_width // 2) # Read-only port in a different clock domain port2 = crossbar.get_port( mode = "read", clock_domain = "video", # CDC FIFOs are added automatically ) # Write-only port wider than the controller (downconverted internally) port3 = crossbar.get_port( mode = "write", data_width = crossbar.controller.data_width * 2, ) # port.cmd -> stream.Endpoint with .valid, .ready, .we, .addr # port.wdata -> stream.Endpoint with .valid, .ready, .data, .we (byte enable) # port.rdata -> stream.Endpoint with .valid, .ready, .data ``` ```