from migen.fhdl import simplify
from misoclib.gensoc import cpuif
+from misoclib.cpu import CPU
from misoclib.sdram.phy import initsequence
from misoc_import import misoc_import
actions["build-bios"] = True
if not actions["load-bitstream"]:
actions["flash-bitstream"] = True
- if not hasattr(soc, "init_bios_memory"):
+ if not soc.with_rom:
actions["flash-bios"] = True
if actions["build-bitstream"] and hasattr(soc, "init_bios_memory"):
actions["build-bios"] = True
*/
""".format(platform_name, args.target, top_class.__name__, soc.cpu_type)
+ if isinstance(soc.cpu_or_bridge, CPU):
cpu_mak = cpuif.get_cpu_mak(soc.cpu_type)
write_to_file("software/include/generated/cpu.mak", cpu_mak)
linker_output_format = cpuif.get_linker_output_format(soc.cpu_type)
write_to_file("software/include/generated/output_format.ld", linker_output_format)
- linker_regions = cpuif.get_linker_regions(soc.cpu_memory_regions)
+ linker_regions = cpuif.get_linker_regions(soc.memory_regions)
write_to_file("software/include/generated/regions.ld", boilerplate + linker_regions)
- try:
- flash_boot_address = soc.flash_boot_address
- except AttributeError:
- flash_boot_address = None
- mem_header = cpuif.get_mem_header(soc.cpu_memory_regions, flash_boot_address)
- write_to_file("software/include/generated/mem.h", boilerplate + mem_header)
- csr_header = cpuif.get_csr_header(soc.cpu_csr_regions, soc.interrupt_map)
- write_to_file("software/include/generated/csr.h", boilerplate + csr_header)
+
for sdram_phy in ["sdrphy", "ddrphy"]:
if hasattr(soc, sdram_phy):
sdram_phy_header = initsequence.get_sdram_phy_header(getattr(soc, sdram_phy))
write_to_file("software/include/generated/sdram_phy.h", boilerplate + sdram_phy_header)
+ try:
+ flash_boot_address = soc.flash_boot_address
+ except AttributeError:
+ flash_boot_address = None
+ mem_header = cpuif.get_mem_header(soc.memory_regions, flash_boot_address)
+ write_to_file("software/include/generated/mem.h", boilerplate + mem_header)
+ csr_header = cpuif.get_csr_header(soc.csr_regions, soc.interrupt_map)
+ write_to_file("software/include/generated/csr.h", boilerplate + csr_header)
if actions["build-csr-csv"]:
- csr_csv = cpuif.get_csr_csv(soc.cpu_csr_regions)
+ csr_csv = cpuif.get_csr_csv(soc.csr_regions)
write_to_file(args.csr_csv, csr_csv)
if actions["build-bios"]:
raise OSError("BIOS build failed")
if actions["build-bitstream"]:
- if hasattr(soc, "init_bios_memory"):
- with open("software/bios/bios.bin", "rb") as bios_file:
- bios_data = []
- while True:
- w = bios_file.read(4)
- if not w:
- break
- bios_data.append(struct.unpack(">I", w)[0])
- soc.init_bios_memory(bios_data)
-
+ if soc.with_rom:
+ soc.init_rom()
for decorator in args.decorate:
soc = getattr(simplify, decorator)(soc)
build_kwargs = dict((k, autotype(v)) for k, v in args.build_option)
if actions["flash-bios"]:
prog = platform.create_programmer()
prog.set_flash_proxy_dir(args.flash_proxy_dir)
- prog.flash(soc.cpu_reset_address, "software/bios/bios.bin")
+ prog.flash(soc.cpu_reset_address, soc.cpu_boot_file)
+import os, struct
from operator import itemgetter
from math import ceil
from migen.bus import wishbone2lasmi, wishbone2csr
from misoclib import uart, identifier, timer
-from misoclib.cpu import lm32, mor1kx
+from misoclib.cpu import CPU, lm32, mor1kx
from misoclib.sdram import lasmicon
from misoclib.sdram import dfii
from misoclib.sdram import memtest
class GenSoC(Module):
csr_map = {
"crg": 0, # user
- "uart": 1, # provided by default
- "identifier": 2, # provided
- "timer0": 3, # provided
+ "uart": 1, # provided by default (optional)
+ "identifier": 2, # provided by default (optional)
+ "timer0": 3, # provided by default (optional)
"buttons": 4, # user
"leds": 5, # user
}
mem_map = {
"rom": 0x00000000, # (shadow @0x80000000)
"sram": 0x10000000, # (shadow @0x90000000)
+ "sdram": 0x40000000, # (shadow @0xc0000000)
"csr": 0x60000000, # (shadow @0xe0000000)
}
- def __init__(self, platform, clk_freq, cpu_reset_address, sram_size=4096, with_uart=True, cpu_type="lm32",
- csr_data_width=8, csr_address_width=14):
+ def __init__(self, platform, clk_freq, cpu_or_bridge=None,
+ with_cpu=True, cpu_type="lm32", cpu_reset_address=0x00000000,
+ cpu_boot_file="software/bios/bios.bin",
+ with_rom=False, rom_size=0x8000, rom_init_now=False,
+ with_sram=True, sram_size=4096,
+ with_sdram=False, sdram_size=64*1024,
+ with_csr=True, csr_data_width=8, csr_address_width=14,
+ with_uart=True, uart_baudrate=115200,
+ with_identifier=True,
+ with_timer=True):
+ self.platform = platform
self.clk_freq = clk_freq
+ self.cpu_or_bridge = cpu_or_bridge
+
+ self.with_cpu = with_cpu
+ self.cpu_type = cpu_type
self.cpu_reset_address = cpu_reset_address
+ self.cpu_boot_file = cpu_boot_file
+
+ self.with_rom = with_rom
+ self.rom_size = rom_size
+ self.rom_init_now = rom_init_now
+
+ self.with_sram = with_sram
self.sram_size = sram_size
- self.cpu_type = cpu_type
+
+ self.with_sdram = with_sdram
+ self.sdram_size = sdram_size
+
+ self.with_uart = with_uart
+ self.uart_baudrate = uart_baudrate
+
+ self.with_identifier = with_identifier
+
+ self.with_csr = with_csr
self.csr_data_width = csr_data_width
self.csr_address_width = csr_address_width
- self.cpu_memory_regions = []
- self.cpu_csr_regions = [] # list of (name, origin, busword, csr_list/Memory)
- self._rom_registered = False
- # Wishbone
- if cpu_type == "lm32":
- self.submodules.cpu = lm32.LM32(platform, cpu_reset_address)
- elif cpu_type == "or1k":
- self.submodules.cpu = mor1kx.MOR1KX(platform, cpu_reset_address)
- else:
- raise ValueError("Unsupported CPU type: "+cpu_type)
- self.submodules.sram = wishbone.SRAM(sram_size)
- self.submodules.wishbone2csr = wishbone2csr.WB2CSR(bus_csr=csr.Interface(csr_data_width, csr_address_width))
-
- # rom 0x00000000 (shadow @0x80000000) from register_rom
- # SRAM/debug 0x10000000 (shadow @0x90000000) provided
- # CSR bridge 0x60000000 (shadow @0xe0000000) provided
- self._wb_masters = [self.cpu.ibus, self.cpu.dbus]
- self._wb_slaves = [
- (mem_decoder(self.mem_map["sram"]), self.sram.bus),
- (mem_decoder(self.mem_map["csr"]), self.wishbone2csr.wishbone)
- ]
- self.add_cpu_memory_region("sram", self.mem_map["sram"], sram_size)
+ self.memory_regions = []
+ self.csr_regions = [] # list of (name, origin, busword, csr_list/Memory)
- # CSR
- if with_uart:
- self.submodules.uart = uart.UART(platform.request("serial"), clk_freq, baud=115200)
- platform_id = 0x554E if not hasattr(platform, "identifier") else platform.identifier
- self.submodules.identifier = identifier.Identifier(platform_id, int(clk_freq))
- self.submodules.timer0 = timer.Timer()
-
- def register_rom(self, rom_wb_if, bios_size=0xa000):
- if self._rom_registered:
- raise FinalizeError
- self._rom_registered = True
+ self._wb_masters = []
+ self._wb_slaves = []
- self.add_wb_slave(mem_decoder(self.mem_map["rom"]), rom_wb_if)
- self.add_cpu_memory_region("rom", self.cpu_reset_address, bios_size)
+ if with_cpu:
+ if cpu_type == "lm32":
+ self.submodules.cpu = lm32.LM32(platform, cpu_reset_address)
+ elif cpu_type == "or1k":
+ self.submodules.cpu = mor1kx.MOR1KX(platform, cpu_reset_address)
+ else:
+ raise ValueError("Unsupported CPU type: "+cpu_type)
+ self.cpu_or_bridge = self.cpu
+ self._wb_masters += [self.cpu.ibus, self.cpu.dbus]
+
+ if with_rom:
+ self.submodules.rom = wishbone.SRAM(rom_size, read_only=True)
+ self.register_mem("rom", self.mem_map["rom"], self.rom.bus, rom_size)
+ if rom_init_now:
+ self.init_rom()
+
+ if with_sram:
+ self.submodules.sram = wishbone.SRAM(sram_size)
+ self.register_mem("sram", self.mem_map["sram"], self.sram.bus, sram_size)
+
+ if with_sdram:
+ self.submodules.sdram = wishbone.SRAM(sdram_size)
+ self.register_mem("sdram", self.mem_map["sdram"], self.sdram.bus, sdram_size)
+
+ if with_csr:
+ self.submodules.wishbone2csr = wishbone2csr.WB2CSR(bus_csr=csr.Interface(csr_data_width, csr_address_width))
+ self.register_mem("csr", self.mem_map["csr"], self.wishbone2csr.wishbone)
+
+ if with_uart:
+ self.submodules.uart = uart.UART(platform.request("serial"), clk_freq, baud=uart_baudrate)
+
+ if with_identifier:
+ platform_id = 0x554E if not hasattr(platform, "identifier") else platform.identifier
+ self.submodules.identifier = identifier.Identifier(platform_id, int(clk_freq))
+
+ if with_timer:
+ self.submodules.timer0 = timer.Timer()
+
+ def init_rom(self, filename=None):
+ if filename is None:
+ filename = self.cpu_boot_file
+ filename_ext = os.path.splitext(filename)[1]
+ if filename_ext != ".bin":
+ raise ValueError("rom_init only supports .bin files")
+ with open(filename, "rb") as boot_file:
+ boot_data = []
+ while True:
+ w = boot_file.read(4)
+ if not w:
+ break
+ boot_data.append(struct.unpack(">I", w)[0])
+ self.rom.mem.init = boot_data
def add_wb_master(self, wbm):
if self.finalized:
raise FinalizeError
self._wb_slaves.append((address_decoder, interface))
- def check_cpu_memory_region(self, name, origin):
- for n, o, l in self.cpu_memory_regions:
+ def check_memory_region(self, name, origin):
+ for n, o, l in self.memory_regions:
if n == name or o == origin:
raise ValueError("Memory region conflict between {} and {}".format(n, name))
- def add_cpu_memory_region(self, name, origin, length):
- self.check_cpu_memory_region(name, origin)
- self.cpu_memory_regions.append((name, origin, length))
+ def add_memory_region(self, name, origin, length):
+ self.check_memory_region(name, origin)
+ self.memory_regions.append((name, origin, length))
- def check_cpu_csr_region(self, name, origin):
- for n, o, l, obj in self.cpu_csr_regions:
+ def register_mem(self, name, address, interface, size=None):
+ self.add_wb_slave(mem_decoder(address), interface)
+ if size is not None:
+ self.add_memory_region(name, address, size)
+
+ # XXX for retro-compatibilty, we should maybe use directly register_mem in targets
+ def register_rom(self, interface):
+ self.register_mem("rom", self.mem_map["rom"], interface, size=self.rom_size)
+
+ def check_csr_region(self, name, origin):
+ for n, o, l, obj in self.csr_regions:
if n == name or o == origin:
raise ValueError("CSR region conflict between {} and {}".format(n, name))
- def add_cpu_csr_region(self, name, origin, busword, obj):
- self.check_cpu_csr_region(name, origin)
- self.cpu_csr_regions.append((name, origin, busword, obj))
+ def add_csr_region(self, name, origin, busword, obj):
+ self.check_csr_region(name, origin)
+ self.csr_regions.append((name, origin, busword, obj))
def do_finalize(self):
- if not self._rom_registered:
- raise FinalizeError("Need to call GenSoC.register_rom()")
+ registered_mems = [regions[0] for regions in self.memory_regions]
+ if isinstance(self.cpu_or_bridge, CPU):
+ for mem in ["rom", "sram"]:
+ if mem not in registered_mems:
+ raise FinalizeError("CPU needs a {} to be registered with GenSoC.register_mem()".format(mem))
# Wishbone
self.submodules.wishbonecon = wishbone.InterconnectShared(self._wb_masters,
self._wb_slaves, register=True)
# CSR
- self.submodules.csrbankarray = csrgen.BankArray(self,
- lambda name, memory: self.csr_map[name if memory is None else name + "_" + memory.name_override],
- data_width=self.csr_data_width, address_width=self.csr_address_width)
- self.submodules.csrcon = csr.Interconnect(self.wishbone2csr.csr, self.csrbankarray.get_buses())
- for name, csrs, mapaddr, rmap in self.csrbankarray.banks:
- self.add_cpu_csr_region(name, self.mem_map["csr"]+0x80000000+0x800*mapaddr, flen(rmap.bus.dat_w), csrs)
- for name, memory, mapaddr, mmap in self.csrbankarray.srams:
- self.add_cpu_csr_region(name, self.mem_map["csr"]+0x80000000+0x800*mapaddr, flen(rmap.bus.dat_w), memory)
+ if self.with_csr:
+ self.submodules.csrbankarray = csrgen.BankArray(self,
+ lambda name, memory: self.csr_map[name if memory is None else name + "_" + memory.name_override],
+ data_width=self.csr_data_width, address_width=self.csr_address_width)
+ self.submodules.csrcon = csr.Interconnect(self.wishbone2csr.csr, self.csrbankarray.get_buses())
+ for name, csrs, mapaddr, rmap in self.csrbankarray.banks:
+ self.add_csr_region(name, self.mem_map["csr"]+0x80000000+0x800*mapaddr, flen(rmap.bus.dat_w), csrs)
+ for name, memory, mapaddr, mmap in self.csrbankarray.srams:
+ self.add_csr_region(name, self.mem_map["csr"]+0x80000000+0x800*mapaddr, flen(rmap.bus.dat_w), memory)
# Interrupts
- for k, v in sorted(self.interrupt_map.items(), key=itemgetter(1)):
- if hasattr(self, k):
- self.comb += self.cpu.interrupt[v].eq(getattr(self, k).ev.irq)
+ if hasattr(self.cpu_or_bridge, "interrupt"):
+ for k, v in sorted(self.interrupt_map.items(), key=itemgetter(1)):
+ if hasattr(self, k):
+ self.comb += self.cpu_or_bridge.interrupt[v].eq(getattr(self, k).ev.irq)
def ns(self, t, margin=True):
clk_period_ns = 1000000000/self.clk_freq
def do_exit(self, vns):
pass
-class IntegratedBIOS:
- def __init__(self, bios_size=0x8000):
- self.submodules.rom = wishbone.SRAM(bios_size, read_only=True)
- self.register_rom(self.rom.bus, bios_size)
-
- def init_bios_memory(self, data):
- self.rom.mem.init = data
-
class SDRAMSoC(GenSoC):
csr_map = {
"dfii": 6,
}
csr_map.update(GenSoC.csr_map)
- mem_map = {
- "sdram": 0x40000000, # (shadow @0xc0000000)
- }
- mem_map.update(GenSoC.mem_map)
+ def __init__(self, platform, clk_freq,
+ ramcon_type="lasmicon",
+ with_l2=True, l2_size=8192,
+ with_memtest=False,
+ **kwargs):
+ GenSoC.__init__(self, platform, clk_freq, **kwargs)
+ self.ramcon_type = ramcon_type
- def __init__(self, platform, clk_freq, cpu_reset_address, with_memtest=False, sram_size=4096, l2_size=8192, with_uart=True, ramcon_type="lasmicon", **kwargs):
- GenSoC.__init__(self, platform, clk_freq, cpu_reset_address, sram_size, with_uart, **kwargs)
+ self.with_l2 = with_l2
self.l2_size = l2_size
+
self.with_memtest = with_memtest
- self.ramcon_type = ramcon_type
+
self._sdram_phy_registered = False
def register_sdram_phy(self, phy_dfi, phy_settings, sdram_geom, sdram_timing):
self.submodules.memtest_w = memtest.MemtestWriter(self.lasmixbar.get_master())
self.submodules.memtest_r = memtest.MemtestReader(self.lasmixbar.get_master())
- # Wishbone bridge
- self.submodules.wishbone2lasmi = wishbone2lasmi.WB2LASMI(self.l2_size//4, self.lasmixbar.get_master())
- self.add_wb_slave(mem_decoder(self.mem_map["sdram"]), self.wishbone2lasmi.wishbone)
- self.add_cpu_memory_region("sdram", self.mem_map["sdram"],
- 2**self.lasmicon.lasmic.aw*self.lasmicon.lasmic.dw*self.lasmicon.lasmic.nbanks//8)
+ if self.with_l2:
+ self.submodules.wishbone2lasmi = wishbone2lasmi.WB2LASMI(self.l2_size//4, self.lasmixbar.get_master())
+ sdram_size = 2**self.lasmicon.lasmic.aw*self.lasmicon.lasmic.dw*self.lasmicon.lasmic.nbanks//8
+ self.register_mem("sdram", self.mem_map["sdram"], self.wishbone2lasmi.wishbone, sdram_size)
+
# MINICON
elif self.ramcon_type == "minicon":
+ if with_l2:
+ raise ValueError("MINICON does not implement L2 cache (Use LASMICON)")
+
self.submodules.minicon = sdramcon = Minicon(phy_settings, sdram_geom, sdram_timing)
self.submodules.dficon1 = dfi.Interconnect(sdramcon.dfi, self.dfii.slave)
sdram_width = flen(sdramcon.bus.dat_r)
+ sdram_size = 2**(sdram_geom.bank_a+sdram_geom.row_a+sdram_geom.col_a)*sdram_width//8
+
if (sdram_width == 32):
- self.add_wb_slave(mem_decoder(self.mem_map["sdram"]), sdramcon.bus)
+ self.register_mem("sdram", self.mem_map["sdram"], sdramcon.bus, sdram_size)
elif (sdram_width < 32):
self.submodules.dc = wishbone.DownConverter(32, sdram_width)
self.submodules.intercon = wishbone.InterconnectPointToPoint(self.dc.wishbone_o, sdramcon.bus)
- self.add_wb_slave(mem_decoder(self.mem_map["sdram"]), self.dc.wishbone_i)
+ self.register_mem("sdram", self.mem_map["sdram"], self.dc.wishbone_i, sdram_size)
else:
raise NotImplementedError("Unsupported SDRAM width of {} > 32".format(sdram_width))
-
- # Wishbone bridge
- self.add_cpu_memory_region("sdram", self.mem_map["sdram"],
- 2**(sdram_geom.bank_a+sdram_geom.row_a+sdram_geom.col_a)*sdram_width//8)
else:
raise ValueError("Unsupported SDRAM controller type: {}".format(self.ramcon_type))