Skip to content

Commit 06d00fb

Browse files
committed
targets: keep XCU1525 quad DDR in 32-bit map
Use compact 512MiB windows when the selected DDR channels would otherwise push the SoC bus beyond 32 bits. This keeps VexRiscv/BIOS boot working with four DDR controllers while preserving full 1GiB windows for smaller maps.
1 parent c4ceaa0 commit 06d00fb

1 file changed

Lines changed: 33 additions & 16 deletions

File tree

litex_boards/targets/sqrl_xcu1525.py

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,10 @@
3232

3333
QSFP_PORTS = tuple(f"qsfp{qsfp}_sfp{sfp}" for qsfp in range(2) for sfp in range(4))
3434

35-
DDRAM_CHANNELS = tuple(range(4))
36-
DDRAM_CHANNEL_SIZE = 0x40000000
37-
DDRAM_ORIGINS = {
35+
DDRAM_CHANNELS = tuple(range(4))
36+
DDRAM_CHANNEL_SIZE = 0x40000000
37+
DDRAM_32BIT_WINDOW_SIZE = 0x20000000
38+
DDRAM_ORIGINS = {
3839
0: 0x40000000,
3940
1: 0x80000000,
4041
2: 0xc0000000,
@@ -81,14 +82,26 @@ def parse_ddram_channels(channels):
8182
raise ValueError("DDRAM channel must be 0, 1, 2 or 3")
8283
return tuple(parsed_channels)
8384

84-
def ddram_window_end(origins):
85-
return max(origin + DDRAM_CHANNEL_SIZE for origin in origins.values())
85+
def get_ddram_origins(channels, main_channel, window_size):
86+
main_ram_origin = SoCCore.mem_map["main_ram"]
87+
if window_size == DDRAM_CHANNEL_SIZE:
88+
return {
89+
channel: (DDRAM_ORIGINS[channel] if channel != main_channel else main_ram_origin)
90+
for channel in channels
91+
}
92+
return {
93+
channel: main_ram_origin + n*window_size
94+
for n, channel in enumerate(channels)
95+
}
96+
97+
def ddram_window_end(origins, window_size):
98+
return max(origin + window_size for origin in origins.values())
8699

87-
def ddram_windows_overlap(origins, origin, size):
100+
def ddram_windows_overlap(origins, window_size, origin, size):
88101
if origin is None:
89102
return False
90103
return any(
91-
(origin < ddram_origin + DDRAM_CHANNEL_SIZE) and (origin + size > ddram_origin)
104+
(origin < ddram_origin + window_size) and (origin + size > ddram_origin)
92105
for ddram_origin in origins.values()
93106
)
94107

@@ -152,12 +165,15 @@ def __init__(self, sys_clk_freq=125e6, ddram_channel=0,
152165
ddram_channels = (ddram_channel,)
153166
ddram_channels = parse_ddram_channels(ddram_channels)
154167
ddram_main_channel = 0 if 0 in ddram_channels else ddram_channels[0]
155-
ddram_origins = {
156-
channel: (DDRAM_ORIGINS[channel] if channel != ddram_main_channel else self.mem_map["main_ram"])
157-
for channel in ddram_channels
158-
}
159-
ddram_end = ddram_window_end(ddram_origins)
160-
if ddram_end > 2**kwargs.get("bus_address_width", 32):
168+
bus_address_width = kwargs.get("bus_address_width", 32)
169+
ddram_window_size = DDRAM_CHANNEL_SIZE
170+
ddram_origins = get_ddram_origins(ddram_channels, ddram_main_channel, ddram_window_size)
171+
ddram_end = ddram_window_end(ddram_origins, ddram_window_size)
172+
if ddram_end > 2**bus_address_width and bus_address_width <= 32:
173+
ddram_window_size = DDRAM_32BIT_WINDOW_SIZE
174+
ddram_origins = get_ddram_origins(ddram_channels, ddram_main_channel, ddram_window_size)
175+
ddram_end = ddram_window_end(ddram_origins, ddram_window_size)
176+
if ddram_end > 2**bus_address_width:
161177
kwargs["bus_address_width"] = 64
162178
if with_pcie and ddram_end > 2**pcie_address_width:
163179
pcie_address_width = 64
@@ -171,10 +187,10 @@ def __init__(self, sys_clk_freq=125e6, ddram_channel=0,
171187
# SoCCore ----------------------------------------------------------------------------------
172188
SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SoC on XCU1525", **kwargs)
173189
relocated_io = False
174-
if ddram_windows_overlap(ddram_origins, self.mem_map.get("csr"), 2**(self.csr.address_width + 2)):
190+
if ddram_windows_overlap(ddram_origins, ddram_window_size, self.mem_map.get("csr"), 2**(self.csr.address_width + 2)):
175191
self.mem_map["csr"] = DDRAM_CSR_ORIGIN
176192
relocated_io = True
177-
if ddram_windows_overlap(ddram_origins, self.mem_map.get("vexriscv_debug"), 0x100):
193+
if ddram_windows_overlap(ddram_origins, ddram_window_size, self.mem_map.get("vexriscv_debug"), 0x100):
178194
self.mem_map["vexriscv_debug"] = DDRAM_DEBUG_ORIGIN
179195
relocated_io = True
180196
if relocated_io:
@@ -200,7 +216,7 @@ def __init__(self, sys_clk_freq=125e6, ddram_channel=0,
200216
phy = phy,
201217
module = MT40A512M8(sys_clk_freq, "1:4"),
202218
origin = origin,
203-
size = DDRAM_CHANNEL_SIZE,
219+
size = ddram_window_size,
204220
region_name = None if is_main else f"ddram{channel}",
205221
main_ram = is_main,
206222
channel = channel,
@@ -211,6 +227,7 @@ def __init__(self, sys_clk_freq=125e6, ddram_channel=0,
211227
)
212228
self.add_constant("DDRAM_CHANNELS", len(ddram_channels))
213229
self.add_constant("DDRAM_MAIN_CHANNEL", ddram_main_channel)
230+
self.add_constant("DDRAM_WINDOW_SIZE", ddram_window_size)
214231
# Workadound for Vivado 2018.2 DRC, can be ignored and probably fixed on newer Vivado versions.
215232
platform.add_platform_command("set_property SEVERITY {{Warning}} [get_drc_checks PDCN-2736]")
216233

0 commit comments

Comments
 (0)