3232
3333QSFP_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