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 cpu_type
= "vexriscv",
66 cpu_reset_address
= 0x00000000,
69 integrated_rom_size
= 0,
70 integrated_rom_init
= [],
72 integrated_sram_size
= 0x1000,
73 integrated_sram_init
= [],
75 integrated_main_ram_size
= 0,
76 integrated_main_ram_init
= [],
80 csr_address_width
= 14,
81 # Identifier parameters
83 ident_version
= False,
87 uart_baudrate
= 115200,
90 # Controller parameters
94 wishbone_timeout_cycles
= 1e6
,
98 # New LiteXSoC class ----------------------------------------------------------------------------
99 LiteXSoC
.__init
__(self
, platform
, clk_freq
,
100 bus_standard
= "wishbone",
102 bus_address_width
= 32,
103 bus_timeout
= wishbone_timeout_cycles
,
104 bus_reserved_regions
= {},
106 csr_data_width
= csr_data_width
,
107 csr_address_width
= csr_address_width
,
108 csr_alignment
= csr_alignment
,
110 csr_reserved_csrs
= self
.csr_map
,
113 irq_reserved_irqs
= {},
117 self
.mem_regions
= self
.bus
.regions
118 self
.clk_freq
= self
.sys_clk_freq
119 self
.mem_map
= self
.mem_map
122 # Parameters management --------------------------------------------------------------------
123 cpu_type
= None if cpu_type
== "None" else cpu_type
124 cpu_variant
= cpu
.check_format_cpu_variant(cpu_variant
)
126 if not with_wishbone
:
127 self
.mem_map
["csr"] = 0x00000000
129 self
.cpu_type
= cpu_type
130 self
.cpu_variant
= cpu_variant
132 self
.integrated_rom_size
= integrated_rom_size
133 self
.integrated_rom_initialized
= integrated_rom_init
!= []
134 self
.integrated_sram_size
= integrated_sram_size
135 self
.integrated_main_ram_size
= integrated_main_ram_size
137 self
.csr_data_width
= csr_data_width
139 self
.with_wishbone
= with_wishbone
140 self
.wishbone_timeout_cycles
= wishbone_timeout_cycles
144 # Modules instances ------------------------------------------------------------------------
148 self
.add_controller("ctrl")
152 name
= str(cpu_type
),
153 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
)
174 self
.add_identifier("identifier", identifier
=ident
, with_build_time
=ident_version
)
178 self
.add_uart(name
=uart_name
, baudrate
=uart_baudrate
)
182 self
.add_timer(name
="timer0")
184 # Add Wishbone to CSR bridge
186 self
.add_csr_bridge(self
.mem_map
["csr"])
188 # Methods --------------------------------------------------------------------------------------
190 def add_interrupt(self
, interrupt_name
, interrupt_id
=None, use_loc_if_exists
=False):
191 self
.irq
.add(interrupt_name
, interrupt_id
, use_loc_if_exists
=use_loc_if_exists
)
193 def add_csr(self
, csr_name
, csr_id
=None, use_loc_if_exists
=False):
194 self
.csr
.add(csr_name
, csr_id
, use_loc_if_exists
=use_loc_if_exists
)
196 def initialize_rom(self
, data
):
197 self
.rom
.mem
.init
= data
199 def add_wb_master(self
, wbm
):
200 self
.bus
.add_master(master
=wbm
)
202 def add_wb_slave(self
, address
, interface
, size
=None):
204 for name
, region
in self
.bus
.regions
.items():
205 if address
== region
.origin
:
209 self
.wb_slaves
[address
] = interface
211 self
.bus
.add_slave(name
=wb_name
, slave
=interface
)
213 def add_memory_region(self
, name
, origin
, length
, type="cached"):
214 self
.bus
.add_region(name
, SoCRegion(origin
=origin
, size
=length
,
215 cached
="cached" in type,
216 linker
="linker" in type))
218 def register_mem(self
, name
, address
, interface
, size
=0x10000000):
219 self
.bus
.add_slave(name
, interface
, SoCRegion(origin
=address
, size
=size
))
221 def register_rom(self
, interface
, rom_size
=0xa000):
222 self
.bus
.add_slave("rom", interface
, SoCRegion(origin
=self
.cpu
.reset_address
, size
=rom_size
))
224 def add_csr_region(self
, name
, origin
, busword
, obj
):
225 self
.csr_regions
[name
] = SoCCSRRegion(origin
, busword
, obj
)
227 # Finalization ---------------------------------------------------------------------------------
229 def do_finalize(self
):
230 # Retro-compatibility
231 for address
, interface
in self
.wb_slaves
.items():
233 for name
, region
in self
.bus
.regions
.items():
234 if address
== region
.origin
:
237 self
.bus
.add_slave(name
=wb_name
, slave
=interface
)
239 SoC
.do_finalize(self
)
240 # Retro-compatibility
241 for region
in self
.bus
.regions
.values():
242 region
.length
= region
.size
243 region
.type = "cached" if region
.cached
else "io"
244 self
.csr_regions
= self
.csr
.regions
245 for name
, value
in self
.config
.items():
246 self
.add_config(name
, value
)
248 # SoCCore arguments --------------------------------------------------------------------------------
250 def soc_core_args(parser
):
252 parser
.add_argument("--cpu-type", default
=None,
253 help="select CPU: {}, (default=vexriscv)".format(", ".join(iter(cpu
.CPUS
.keys()))))
254 parser
.add_argument("--cpu-variant", default
=None,
255 help="select CPU variant, (default=standard)")
256 parser
.add_argument("--cpu-reset-address", default
=None, type=int,
257 help="CPU reset address (default=0x00000000 or ROM)")
259 parser
.add_argument("--integrated-rom-size", default
=0x8000, type=int,
260 help="size/enable the integrated (BIOS) ROM (default=32KB)")
261 parser
.add_argument("--integrated-rom-file", default
=None, type=str,
262 help="integrated (BIOS) ROM binary file")
264 parser
.add_argument("--integrated-sram-size", default
=0x1000, type=int,
265 help="size/enable the integrated SRAM (default=4KB)")
266 # MAIN_RAM parameters
267 parser
.add_argument("--integrated-main-ram-size", default
=None, type=int,
268 help="size/enable the integrated main RAM")
270 parser
.add_argument("--csr-data-width", default
=None, type=int,
271 help="CSR bus data-width (8 or 32, default=8)")
272 parser
.add_argument("--csr-address-width", default
=14, type=int,
273 help="CSR bus address-width")
274 # Identifier parameters
275 parser
.add_argument("--ident", default
=None, type=str,
276 help="SoC identifier (default=\"\"")
277 parser
.add_argument("--ident-version", default
=None, type=bool,
278 help="add date/time to SoC identifier (default=False)")
280 parser
.add_argument("--with-uart", default
=None, type=bool,
281 help="with UART (default=True)")
282 parser
.add_argument("--uart-name", default
="serial", type=str,
283 help="UART type/name (default=serial)")
284 parser
.add_argument("--uart-baudrate", default
=None, type=int,
285 help="UART baudrate (default=115200)")
286 parser
.add_argument("--uart-stub", default
=False, type=bool,
287 help="enable UART stub (default=False)")
289 parser
.add_argument("--with-timer", default
=None, type=bool,
290 help="with Timer (default=True)")
291 # Controller parameters
292 parser
.add_argument("--with-ctrl", default
=None, type=bool,
293 help="with Controller (default=True)")
295 def soc_core_argdict(args
):
297 rom_file
= getattr(args
, "integrated_rom_file", None)
298 if rom_file
is not None:
299 args
.integrated_rom_init
= get_mem_data(rom_file
, "little") # FIXME: endianness
300 args
.integrated_rom_size
= len(args
.integrated_rom_init
)*4
301 for a
in inspect
.getargspec(SoCCore
.__init
__).args
:
302 if a
not in ["self", "platform"]:
303 arg
= getattr(args
, a
, None)
308 # SoCMini ---------------------------------------------------------------------------------------
310 class SoCMini(SoCCore
):
311 def __init__(self
, *args
, **kwargs
):
312 if "cpu_type" not in kwargs
.keys():
313 kwargs
["cpu_type"] = "None"
314 if "integrated_sram_size" not in kwargs
.keys():
315 kwargs
["integrated_sram_size"] = 0
316 if "with_uart" not in kwargs
.keys():
317 kwargs
["with_uart"] = False
318 if "with_timer" not in kwargs
.keys():
319 kwargs
["with_timer"] = False
321 SoCCore
.__init
__(self
, *args
, **kwargs
)
323 # SoCMini arguments -----------------------------------------------------------------------------
325 soc_mini_args
= soc_core_args
326 soc_mini_argdict
= soc_core_argdict