1 # This file is Copyright (c) 2013-2014 Sebastien Bourdeauducq <sb@m-labs.hk>
2 # This file is Copyright (c) 2014-2019 Florent Kermarrec <florent@enjoy-digital.fr>
3 # This file is Copyright (c) 2018 Dolu1990 <charles.papon.90@gmail.com>
4 # This file is Copyright (c) 2019 Gabriel L. Somlo <gsomlo@gmail.com>
5 # This file is Copyright (c) 2019 Ilia Sergachev <ilia.sergachev@protonmail.ch>
6 # This file is Copyright (c) 2018 Jean-François Nguyen <jf@lambdaconcept.fr>
7 # This file is Copyright (c) 2015 Robert Jordens <jordens@gmail.com>
8 # This file is Copyright (c) 2018 Sean Cross <sean@xobs.io>
9 # This file is Copyright (c) 2018 Stafford Horne <shorne@gmail.com>
10 # This file is Copyright (c) 2018-2017 Tim 'mithro' Ansell <me@mith.ro>
11 # This file is Copyright (c) 2015 whitequark <whitequark@whitequark.org>
12 # This file is Copyright (c) 2014 Yann Sionneau <ys@m-labs.hk>
15 ####################################################################################################
16 # DISCLAIMER: Provides retro-compatibility layer for existing SoCCore based designs.
17 # Most of the SoC code has been refactored/improved and is now located in integration/soc.py
18 ####################################################################################################
25 from litex
.soc
.cores
import cpu
26 from litex
.soc
.interconnect
import wishbone
27 from litex
.soc
.integration
.common
import *
28 from litex
.soc
.integration
.soc
import *
41 # Helpers ------------------------------------------------------------------------------------------
43 def mem_decoder(address
, size
=0x10000000):
44 size
= 2**log2_int(size
, False)
45 assert (address
& (size
- 1)) == 0
46 address
>>= 2 # bytes to words aligned
47 size
>>= 2 # bytes to words aligned
48 return lambda a
: (a
[log2_int(size
):] == (address
>> log2_int(size
)))
50 # SoCCore ------------------------------------------------------------------------------------------
52 class SoCCore(LiteXSoC
):
53 # default register/interrupt/memory mappings (can be redefined by user)
59 "main_ram": 0x40000000,
63 def __init__(self
, platform
, clk_freq
,
65 bus_standard
= "wishbone",
67 bus_address_width
= 32,
70 cpu_type
= "vexriscv",
71 cpu_reset_address
= None,
75 integrated_rom_size
= 0,
76 integrated_rom_init
= [],
78 integrated_sram_size
= 0x2000,
79 integrated_sram_init
= [],
81 integrated_main_ram_size
= 0,
82 integrated_main_ram_init
= [],
85 csr_address_width
= 14,
87 # Identifier parameters
89 ident_version
= False,
93 uart_baudrate
= 115200,
98 # Controller parameters
103 # New LiteXSoC class ----------------------------------------------------------------------------
104 LiteXSoC
.__init
__(self
, platform
, clk_freq
,
105 bus_standard
= bus_standard
,
106 bus_data_width
= bus_data_width
,
107 bus_address_width
= bus_address_width
,
108 bus_timeout
= bus_timeout
,
109 bus_reserved_regions
= {},
111 csr_data_width
= csr_data_width
,
112 csr_address_width
= csr_address_width
,
113 csr_paging
= csr_paging
,
114 csr_reserved_csrs
= self
.csr_map
,
117 irq_reserved_irqs
= {},
121 self
.mem_regions
= self
.bus
.regions
122 self
.clk_freq
= self
.sys_clk_freq
123 self
.mem_map
= self
.mem_map
126 # Parameters management --------------------------------------------------------------------
127 cpu_type
= None if cpu_type
== "None" else cpu_type
128 cpu_reset_address
= None if cpu_reset_address
== "None" else cpu_reset_address
130 self
.cpu_type
= cpu_type
131 self
.cpu_variant
= cpu_variant
132 self
.cpu_cls
= cpu_cls
134 self
.integrated_rom_size
= integrated_rom_size
135 self
.integrated_rom_initialized
= integrated_rom_init
!= []
136 self
.integrated_sram_size
= integrated_sram_size
137 self
.integrated_main_ram_size
= integrated_main_ram_size
139 self
.csr_data_width
= csr_data_width
143 # Modules instances ------------------------------------------------------------------------
147 self
.add_controller("ctrl")
151 name
= str(cpu_type
),
152 variant
= "standard" if cpu_variant
is None else cpu_variant
,
154 reset_address
= None if integrated_rom_size
else cpu_reset_address
)
156 # Add User's interrupts
157 for name
, loc
in self
.interrupt_map
.items():
158 self
.irq
.add(name
, loc
)
161 if integrated_rom_size
:
162 self
.add_rom("rom", self
.cpu
.reset_address
, integrated_rom_size
, integrated_rom_init
)
164 # Add integrated SRAM
165 if integrated_sram_size
:
166 self
.add_ram("sram", self
.mem_map
["sram"], integrated_sram_size
)
168 # Add integrated MAIN_RAM (only useful when no external SRAM/SDRAM is available)
169 if integrated_main_ram_size
:
170 self
.add_ram("main_ram", self
.mem_map
["main_ram"], integrated_main_ram_size
, integrated_main_ram_init
)
174 self
.add_identifier("identifier", identifier
=ident
, with_build_time
=ident_version
)
178 self
.add_uart(name
=uart_name
, baudrate
=uart_baudrate
, fifo_depth
=uart_fifo_depth
)
182 self
.add_timer(name
="timer0")
184 self
.timer0
.add_uptime()
187 self
.add_csr_bridge(self
.mem_map
["csr"])
189 # Methods --------------------------------------------------------------------------------------
191 def add_interrupt(self
, interrupt_name
, interrupt_id
=None, use_loc_if_exists
=False):
192 self
.irq
.add(interrupt_name
, interrupt_id
, use_loc_if_exists
=use_loc_if_exists
)
194 def add_csr(self
, csr_name
, csr_id
=None, use_loc_if_exists
=False):
195 self
.csr
.add(csr_name
, csr_id
, use_loc_if_exists
=use_loc_if_exists
)
197 def initialize_rom(self
, data
):
198 self
.rom
.mem
.init
= data
200 def add_wb_master(self
, wbm
):
201 self
.bus
.add_master(master
=wbm
)
203 def add_wb_slave(self
, address
, interface
, size
=None):
205 for name
, region
in self
.bus
.regions
.items():
206 if address
== region
.origin
:
210 self
.wb_slaves
[address
] = interface
212 self
.bus
.add_slave(name
=wb_name
, slave
=interface
)
214 def add_memory_region(self
, name
, origin
, length
, type="cached"):
215 self
.bus
.add_region(name
, SoCRegion(origin
=origin
, size
=length
,
216 cached
="cached" in type,
217 linker
="linker" in type))
219 def register_mem(self
, name
, address
, interface
, size
=0x10000000):
220 self
.bus
.add_slave(name
, interface
, SoCRegion(origin
=address
, size
=size
))
222 def register_rom(self
, interface
, rom_size
=0xa000):
223 self
.bus
.add_slave("rom", interface
, SoCRegion(origin
=self
.cpu
.reset_address
, size
=rom_size
))
225 def add_csr_region(self
, name
, origin
, busword
, obj
):
226 self
.csr_regions
[name
] = SoCCSRRegion(origin
, busword
, obj
)
228 # Finalization ---------------------------------------------------------------------------------
230 def do_finalize(self
):
231 # Retro-compatibility
232 for address
, interface
in self
.wb_slaves
.items():
234 for name
, region
in self
.bus
.regions
.items():
235 if address
== region
.origin
:
238 self
.bus
.add_slave(name
=wb_name
, slave
=interface
)
240 SoC
.do_finalize(self
)
241 # Retro-compatibility
242 for region
in self
.bus
.regions
.values():
243 region
.length
= region
.size
244 region
.type = "cached" if region
.cached
else "io"
246 region
.type += "+linker"
247 self
.csr_regions
= self
.csr
.regions
248 for name
, value
in self
.config
.items():
249 self
.add_config(name
, value
)
251 # SoCCore arguments --------------------------------------------------------------------------------
253 def soc_core_args(parser
):
255 parser
.add_argument("--bus-standard", default
="wishbone",
256 help="select bus standard: {}, (default=wishbone)".format(
257 ", ".join(SoCBusHandler
.supported_standard
)))
258 parser
.add_argument("--bus-data-width", default
=32, type=auto_int
,
259 help="Bus data width (default=32)")
260 parser
.add_argument("--bus-address-width", default
=32, type=auto_int
,
261 help="Bus address width (default=32)")
262 parser
.add_argument("--bus-timeout", default
=1e6
, type=float,
263 help="Bus timeout in cycles (default=1e6)")
266 parser
.add_argument("--cpu-type", default
=None,
267 help="select CPU: {}, (default=vexriscv)".format(", ".join(iter(cpu
.CPUS
.keys()))))
268 parser
.add_argument("--cpu-variant", default
=None,
269 help="select CPU variant, (default=standard)")
270 parser
.add_argument("--cpu-reset-address", default
=None, type=auto_int
,
271 help="CPU reset address (default=None (Integrated ROM)")
273 parser
.add_argument("--integrated-rom-size", default
=0x8000, type=auto_int
,
274 help="size/enable the integrated (BIOS) ROM (default=32KB)")
275 parser
.add_argument("--integrated-rom-file", default
=None, type=str,
276 help="integrated (BIOS) ROM binary file")
278 parser
.add_argument("--integrated-sram-size", default
=0x2000, type=auto_int
,
279 help="size/enable the integrated SRAM (default=8KB)")
280 # MAIN_RAM parameters
281 parser
.add_argument("--integrated-main-ram-size", default
=None, type=auto_int
,
282 help="size/enable the integrated main RAM")
284 parser
.add_argument("--csr-data-width", default
=None, type=auto_int
,
285 help="CSR bus data-width (8 or 32, default=8)")
286 parser
.add_argument("--csr-address-width", default
=14, type=auto_int
,
287 help="CSR bus address-width")
288 parser
.add_argument("--csr-paging", default
=0x800, type=auto_int
,
289 help="CSR bus paging")
290 # Identifier parameters
291 parser
.add_argument("--ident", default
=None, type=str,
292 help="SoC identifier (default=\"\"")
293 parser
.add_argument("--ident-version", default
=None, type=bool,
294 help="add date/time to SoC identifier (default=False)")
296 parser
.add_argument("--no-uart", action
="store_true",
297 help="Disable UART (default=False)")
298 parser
.add_argument("--uart-name", default
="serial", type=str,
299 help="UART type/name (default=serial)")
300 parser
.add_argument("--uart-baudrate", default
=None, type=auto_int
,
301 help="UART baudrate (default=115200)")
302 parser
.add_argument("--uart-fifo-depth", default
=16, type=auto_int
,
303 help="UART FIFO depth (default=16)")
305 parser
.add_argument("--no-timer", action
="store_true",
306 help="Disable Timer (default=False)")
307 # Controller parameters
308 parser
.add_argument("--no-ctrl", action
="store_true",
309 help="Disable Controller (default=False)")
311 def soc_core_argdict(args
):
313 rom_file
= getattr(args
, "integrated_rom_file", None)
314 if rom_file
is not None:
315 args
.integrated_rom_init
= get_mem_data(rom_file
, "little") # FIXME: endianness
316 args
.integrated_rom_size
= len(args
.integrated_rom_init
)*4
317 for a
in inspect
.getargspec(SoCCore
.__init
__).args
:
318 if a
not in ["self", "platform"]:
319 if a
in ["with_uart", "with_timer", "with_ctrl"]:
320 arg
= not getattr(args
, a
.replace("with", "no"), True)
322 arg
= getattr(args
, a
, None)
327 # SoCMini ---------------------------------------------------------------------------------------
329 class SoCMini(SoCCore
):
330 def __init__(self
, *args
, **kwargs
):
331 if "cpu_type" not in kwargs
.keys():
332 kwargs
["cpu_type"] = "None"
333 if "integrated_sram_size" not in kwargs
.keys():
334 kwargs
["integrated_sram_size"] = 0
335 if "with_uart" not in kwargs
.keys():
336 kwargs
["with_uart"] = False
337 if "with_timer" not in kwargs
.keys():
338 kwargs
["with_timer"] = False
340 SoCCore
.__init
__(self
, *args
, **kwargs
)
342 # SoCMini arguments -----------------------------------------------------------------------------
344 soc_mini_args
= soc_core_args
345 soc_mini_argdict
= soc_core_argdict