From: Florent Kermarrec Date: Sat, 28 Feb 2015 10:36:15 +0000 (+0100) Subject: remane GenSoC to SoC (more coherent and we will add support for multiple SoCs with... X-Git-Tag: 24jan2021_ls180~2566 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=69e869893d8dc48170bd3f4b08524fbf0f9db058;p=litex.git remane GenSoC to SoC (more coherent and we will add support for multiple SoCs with their own Wisbbone/CSR buses in the future) --- diff --git a/make.py b/make.py index 470a23a9..3153404b 100755 --- a/make.py +++ b/make.py @@ -6,7 +6,7 @@ from mibuild.tools import write_to_file from migen.util.misc import autotype from migen.fhdl import simplify -from misoclib.gensoc import cpuif +from misoclib.soc import cpuif from misoclib.cpu import CPU from misoclib.mem.sdram.phy import initsequence diff --git a/misoclib/com/liteeth/example_designs/targets/base.py b/misoclib/com/liteeth/example_designs/targets/base.py index 784e4762..ef099ade 100644 --- a/misoclib/com/liteeth/example_designs/targets/base.py +++ b/misoclib/com/liteeth/example_designs/targets/base.py @@ -55,7 +55,7 @@ class _CRG(Module): AsyncResetSynchronizer(self.cd_sys, ~pll_locked | platform.request("cpu_reset") | self.reset), ] -class GenSoC(Module): +class SoC(Module): csr_base = 0x00000000 csr_data_width = 32 csr_map = { @@ -109,17 +109,17 @@ class GenSoC(Module): for name, memory, mapaddr, mmap in self.csrbankarray.srams: self.add_cpu_csr_region(name, 0xe0000000+0x800*mapaddr, flen(rmap.bus.dat_w), memory) -class BaseSoC(GenSoC, AutoCSR): +class BaseSoC(SoC, AutoCSR): default_platform = "kc705" csr_map = { "phy": 11, "core": 12 } - csr_map.update(GenSoC.csr_map) + csr_map.update(SoC.csr_map) def __init__(self, platform, clk_freq=166*1000000, mac_address=0x10e2d5000000, ip_address="192.168.1.40"): - GenSoC.__init__(self, platform, clk_freq) + SoC.__init__(self, platform, clk_freq) self.submodules.crg = _CRG(platform) # wishbone SRAM (to test Wishbone over UART and Etherbone) diff --git a/misoclib/gensoc/__init__.py b/misoclib/gensoc/__init__.py deleted file mode 100644 index 3ce45252..00000000 --- a/misoclib/gensoc/__init__.py +++ /dev/null @@ -1,271 +0,0 @@ -import os, struct -from operator import itemgetter -from math import ceil - -from migen.fhdl.std import * -from migen.bank import csrgen -from migen.bus import wishbone, csr, wishbone2csr - -from misoclib.com import uart -from misoclib.cpu import CPU, lm32, mor1kx -from misoclib.cpu.peripherals import identifier, timer -from misoclib.mem.sdram.bus import dfi, lasmibus, wishbone2lasmi -from misoclib.mem.sdram import minicon,lasmicon -from misoclib.mem.sdram import dfii -from misoclib.mem.sdram import memtest - -def mem_decoder(address, start=26, end=29): - return lambda a: a[start:end] == ((address >> (start+2)) & (2**(end-start))-1) - -class GenSoC(Module): - csr_map = { - "crg": 0, # user - "uart": 1, # provided by default (optional) - "identifier": 2, # provided by default (optional) - "timer0": 3, # provided by default (optional) - "buttons": 4, # user - "leds": 5, # user - } - interrupt_map = { - "uart": 0, - "timer0": 1, - } - 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_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, - 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.with_sram = with_sram - self.sram_size = sram_size - - 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.memory_regions = [] - self.csr_regions = [] # list of (name, origin, busword, csr_list/Memory) - - self._wb_masters = [] - self._wb_slaves = [] - - 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 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, data): - self.rom.mem.init = data - - def add_wb_master(self, wbm): - if self.finalized: - raise FinalizeError - self._wb_masters.append(wbm) - - def add_wb_slave(self, address_decoder, interface): - if self.finalized: - raise FinalizeError - self._wb_slaves.append((address_decoder, interface)) - - 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_memory_region(self, name, origin, length): - self.check_memory_region(name, origin) - self.memory_regions.append((name, origin, length)) - - 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_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): - 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 - 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 - 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 - if margin: - t += clk_period_ns/2 - return ceil(t/clk_period_ns) - - def do_exit(self, vns): - pass - -class SDRAMSoC(GenSoC): - csr_map = { - "dfii": 6, - "lasmicon": 7, - "wishbone2lasmi": 8, - "memtest_w": 9, - "memtest_r": 10 - } - csr_map.update(GenSoC.csr_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 - - self.with_l2 = with_l2 - self.l2_size = l2_size - - self.with_memtest = with_memtest - - self._sdram_phy_registered = False - - def register_sdram_phy(self, phy_dfi, phy_settings, sdram_geom, sdram_timing): - if self._sdram_phy_registered: - raise FinalizeError - self._sdram_phy_registered = True - - # DFI - self.submodules.dfii = dfii.DFIInjector(sdram_geom.mux_a, sdram_geom.bank_a, - phy_settings.dfi_d, phy_settings.nphases) - self.submodules.dficon0 = dfi.Interconnect(self.dfii.master, phy_dfi) - - # LASMICON - if self.ramcon_type == "lasmicon": - self.submodules.lasmicon = lasmicon.LASMIcon(phy_settings, sdram_geom, sdram_timing) - self.submodules.dficon1 = dfi.Interconnect(self.lasmicon.dfi, self.dfii.slave) - - self.submodules.lasmixbar = lasmibus.Crossbar([self.lasmicon.lasmic], self.lasmicon.nrowbits) - - if self.with_memtest: - self.submodules.memtest_w = memtest.MemtestWriter(self.lasmixbar.get_master()) - self.submodules.memtest_r = memtest.MemtestReader(self.lasmixbar.get_master()) - - 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 self.with_l2: - raise ValueError("MINICON does not implement L2 cache (Use LASMICON or disable L2 cache (with_l2=False))") - - self.submodules.minicon = sdramcon = minicon.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.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.register_mem("sdram", self.mem_map["sdram"], self.dc.wishbone_i, sdram_size) - else: - raise NotImplementedError("Unsupported SDRAM width of {} > 32".format(sdram_width)) - else: - raise ValueError("Unsupported SDRAM controller type: {}".format(self.ramcon_type)) - - def do_finalize(self): - if not self._sdram_phy_registered: - raise FinalizeError("Need to call SDRAMSoC.register_sdram_phy()") - GenSoC.do_finalize(self) diff --git a/misoclib/gensoc/cpuif.py b/misoclib/gensoc/cpuif.py deleted file mode 100644 index 57d365b8..00000000 --- a/misoclib/gensoc/cpuif.py +++ /dev/null @@ -1,101 +0,0 @@ -from migen.fhdl.std import * -from migen.bank.description import CSRStatus - -def get_cpu_mak(cpu_type): - if cpu_type == "lm32": - cpuflags = "-mbarrel-shift-enabled -mmultiply-enabled -mdivide-enabled -msign-extend-enabled" - elif cpu_type == "or1k": - cpuflags = "-mhard-mul -mhard-div" - else: - raise ValueError("Unsupported CPU type: "+cpu_type) - return "CPU={}\nCPUFLAGS={}\n".format(cpu_type, cpuflags) - -def get_linker_output_format(cpu_type): - return "OUTPUT_FORMAT(\"elf32-{}\")\n".format(cpu_type) - -def get_linker_regions(regions): - r = "MEMORY {\n" - for name, origin, length in regions: - r += "\t{} : ORIGIN = 0x{:08x}, LENGTH = 0x{:08x}\n".format(name, origin, length) - r += "}\n" - return r - -def get_mem_header(regions, flash_boot_address): - r = "#ifndef __GENERATED_MEM_H\n#define __GENERATED_MEM_H\n\n" - for name, base, size in regions: - r += "#define {name}_BASE 0x{base:08x}\n#define {name}_SIZE 0x{size:08x}\n\n".format(name=name.upper(), base=base, size=size) - if flash_boot_address is not None: - r += "#define FLASH_BOOT_ADDRESS 0x{:08x}\n\n".format(flash_boot_address) - r += "#endif\n" - return r - -def _get_rw_functions(reg_name, reg_base, nwords, busword, read_only): - r = "" - - r += "#define CSR_"+reg_name.upper()+"_ADDR "+hex(reg_base)+"\n" - r += "#define CSR_"+reg_name.upper()+"_SIZE "+str(nwords)+"\n" - - size = nwords*busword - if size > 64: - return r - elif size > 32: - ctype = "unsigned long long int" - elif size > 16: - ctype = "unsigned int" - elif size > 8: - ctype = "unsigned short int" - else: - ctype = "unsigned char" - - r += "static inline "+ctype+" "+reg_name+"_read(void) {\n" - if size > 1: - r += "\t"+ctype+" r = MMPTR("+hex(reg_base)+");\n" - for byte in range(1, nwords): - r += "\tr <<= "+str(busword)+";\n\tr |= MMPTR("+hex(reg_base+4*byte)+");\n" - r += "\treturn r;\n}\n" - else: - r += "\treturn MMPTR("+hex(reg_base)+");\n}\n" - - if not read_only: - r += "static inline void "+reg_name+"_write("+ctype+" value) {\n" - for word in range(nwords): - shift = (nwords-word-1)*busword - if shift: - value_shifted = "value >> "+str(shift) - else: - value_shifted = "value" - r += "\tMMPTR("+hex(reg_base+4*word)+") = "+value_shifted+";\n" - r += "}\n" - return r - -def get_csr_header(regions, interrupt_map): - r = "#ifndef __GENERATED_CSR_H\n#define __GENERATED_CSR_H\n#include \n" - for name, origin, busword, obj in regions: - if isinstance(obj, Memory): - fullname = name + "_" + memory.name_override - r += "#define "+fullname.upper()+"_BASE "+hex(origin)+"\n" - else: - r += "\n/* "+name+" */\n" - r += "#define "+name.upper()+"_BASE "+hex(origin)+"\n" - for csr in obj: - nr = (csr.size + busword - 1)//busword - r += _get_rw_functions(name + "_" + csr.name, origin, nr, busword, isinstance(csr, CSRStatus)) - origin += 4*nr - try: - interrupt_nr = interrupt_map[name] - except KeyError: - pass - else: - r += "#define "+name.upper()+"_INTERRUPT "+str(interrupt_nr)+"\n" - r += "\n#endif\n" - return r - -def get_csr_csv(regions): - r = "" - for name, origin, busword, obj in regions: - if not isinstance(obj, Memory): - for csr in obj: - nr = (csr.size + busword - 1)//busword - r += "{}_{},0x{:08x},{},{}\n".format(name, csr.name, origin, nr, "ro" if isinstance(csr, CSRStatus) else "rw") - origin += 4*nr - return r diff --git a/misoclib/mem/litesata/example_designs/targets/bist.py b/misoclib/mem/litesata/example_designs/targets/bist.py index 2a8285a1..07cce1b1 100644 --- a/misoclib/mem/litesata/example_designs/targets/bist.py +++ b/misoclib/mem/litesata/example_designs/targets/bist.py @@ -55,7 +55,7 @@ class _CRG(Module): AsyncResetSynchronizer(self.cd_sys, ~pll_locked | platform.request("cpu_reset") | self.reset), ] -class GenSoC(Module): +class SoC(Module): csr_base = 0x00000000 csr_data_width = 32 csr_map = { @@ -130,15 +130,15 @@ class BISTLeds(Module): self.comb += platform.request("user_led", 2).eq(sata_phy.crg.ready) self.comb += platform.request("user_led", 3).eq(sata_phy.ctrl.ready) -class BISTSoC(GenSoC, AutoCSR): +class BISTSoC(SoC, AutoCSR): default_platform = "kc705" csr_map = { "sata": 10, } - csr_map.update(GenSoC.csr_map) + csr_map.update(SoC.csr_map) def __init__(self, platform): clk_freq = 166*1000000 - GenSoC.__init__(self, platform, clk_freq) + SoC.__init__(self, platform, clk_freq) self.submodules.crg = _CRG(platform) # SATA PHY/Core/Frontend diff --git a/misoclib/soc/__init__.py b/misoclib/soc/__init__.py new file mode 100644 index 00000000..28071461 --- /dev/null +++ b/misoclib/soc/__init__.py @@ -0,0 +1,271 @@ +import os, struct +from operator import itemgetter +from math import ceil + +from migen.fhdl.std import * +from migen.bank import csrgen +from migen.bus import wishbone, csr, wishbone2csr + +from misoclib.com import uart +from misoclib.cpu import CPU, lm32, mor1kx +from misoclib.cpu.peripherals import identifier, timer +from misoclib.mem.sdram.bus import dfi, lasmibus, wishbone2lasmi +from misoclib.mem.sdram import minicon,lasmicon +from misoclib.mem.sdram import dfii +from misoclib.mem.sdram import memtest + +def mem_decoder(address, start=26, end=29): + return lambda a: a[start:end] == ((address >> (start+2)) & (2**(end-start))-1) + +class SoC(Module): + csr_map = { + "crg": 0, # user + "uart": 1, # provided by default (optional) + "identifier": 2, # provided by default (optional) + "timer0": 3, # provided by default (optional) + "buttons": 4, # user + "leds": 5, # user + } + interrupt_map = { + "uart": 0, + "timer0": 1, + } + 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_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, + 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.with_sram = with_sram + self.sram_size = sram_size + + 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.memory_regions = [] + self.csr_regions = [] # list of (name, origin, busword, csr_list/Memory) + + self._wb_masters = [] + self._wb_slaves = [] + + 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 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, data): + self.rom.mem.init = data + + def add_wb_master(self, wbm): + if self.finalized: + raise FinalizeError + self._wb_masters.append(wbm) + + def add_wb_slave(self, address_decoder, interface): + if self.finalized: + raise FinalizeError + self._wb_slaves.append((address_decoder, interface)) + + 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_memory_region(self, name, origin, length): + self.check_memory_region(name, origin) + self.memory_regions.append((name, origin, length)) + + 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_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): + 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 SoC.register_mem()".format(mem)) + + # Wishbone + self.submodules.wishbonecon = wishbone.InterconnectShared(self._wb_masters, + self._wb_slaves, register=True) + + # CSR + 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 + 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 + if margin: + t += clk_period_ns/2 + return ceil(t/clk_period_ns) + + def do_exit(self, vns): + pass + +class SDRAMSoC(SoC): + csr_map = { + "dfii": 6, + "lasmicon": 7, + "wishbone2lasmi": 8, + "memtest_w": 9, + "memtest_r": 10 + } + csr_map.update(SoC.csr_map) + + def __init__(self, platform, clk_freq, + ramcon_type="lasmicon", + with_l2=True, l2_size=8192, + with_memtest=False, + **kwargs): + SoC.__init__(self, platform, clk_freq, **kwargs) + self.ramcon_type = ramcon_type + + self.with_l2 = with_l2 + self.l2_size = l2_size + + self.with_memtest = with_memtest + + self._sdram_phy_registered = False + + def register_sdram_phy(self, phy_dfi, phy_settings, sdram_geom, sdram_timing): + if self._sdram_phy_registered: + raise FinalizeError + self._sdram_phy_registered = True + + # DFI + self.submodules.dfii = dfii.DFIInjector(sdram_geom.mux_a, sdram_geom.bank_a, + phy_settings.dfi_d, phy_settings.nphases) + self.submodules.dficon0 = dfi.Interconnect(self.dfii.master, phy_dfi) + + # LASMICON + if self.ramcon_type == "lasmicon": + self.submodules.lasmicon = lasmicon.LASMIcon(phy_settings, sdram_geom, sdram_timing) + self.submodules.dficon1 = dfi.Interconnect(self.lasmicon.dfi, self.dfii.slave) + + self.submodules.lasmixbar = lasmibus.Crossbar([self.lasmicon.lasmic], self.lasmicon.nrowbits) + + if self.with_memtest: + self.submodules.memtest_w = memtest.MemtestWriter(self.lasmixbar.get_master()) + self.submodules.memtest_r = memtest.MemtestReader(self.lasmixbar.get_master()) + + 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 self.with_l2: + raise ValueError("MINICON does not implement L2 cache (Use LASMICON or disable L2 cache (with_l2=False))") + + self.submodules.minicon = sdramcon = minicon.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.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.register_mem("sdram", self.mem_map["sdram"], self.dc.wishbone_i, sdram_size) + else: + raise NotImplementedError("Unsupported SDRAM width of {} > 32".format(sdram_width)) + else: + raise ValueError("Unsupported SDRAM controller type: {}".format(self.ramcon_type)) + + def do_finalize(self): + if not self._sdram_phy_registered: + raise FinalizeError("Need to call SDRAMSoC.register_sdram_phy()") + SoC.do_finalize(self) diff --git a/misoclib/soc/cpuif.py b/misoclib/soc/cpuif.py new file mode 100644 index 00000000..57d365b8 --- /dev/null +++ b/misoclib/soc/cpuif.py @@ -0,0 +1,101 @@ +from migen.fhdl.std import * +from migen.bank.description import CSRStatus + +def get_cpu_mak(cpu_type): + if cpu_type == "lm32": + cpuflags = "-mbarrel-shift-enabled -mmultiply-enabled -mdivide-enabled -msign-extend-enabled" + elif cpu_type == "or1k": + cpuflags = "-mhard-mul -mhard-div" + else: + raise ValueError("Unsupported CPU type: "+cpu_type) + return "CPU={}\nCPUFLAGS={}\n".format(cpu_type, cpuflags) + +def get_linker_output_format(cpu_type): + return "OUTPUT_FORMAT(\"elf32-{}\")\n".format(cpu_type) + +def get_linker_regions(regions): + r = "MEMORY {\n" + for name, origin, length in regions: + r += "\t{} : ORIGIN = 0x{:08x}, LENGTH = 0x{:08x}\n".format(name, origin, length) + r += "}\n" + return r + +def get_mem_header(regions, flash_boot_address): + r = "#ifndef __GENERATED_MEM_H\n#define __GENERATED_MEM_H\n\n" + for name, base, size in regions: + r += "#define {name}_BASE 0x{base:08x}\n#define {name}_SIZE 0x{size:08x}\n\n".format(name=name.upper(), base=base, size=size) + if flash_boot_address is not None: + r += "#define FLASH_BOOT_ADDRESS 0x{:08x}\n\n".format(flash_boot_address) + r += "#endif\n" + return r + +def _get_rw_functions(reg_name, reg_base, nwords, busword, read_only): + r = "" + + r += "#define CSR_"+reg_name.upper()+"_ADDR "+hex(reg_base)+"\n" + r += "#define CSR_"+reg_name.upper()+"_SIZE "+str(nwords)+"\n" + + size = nwords*busword + if size > 64: + return r + elif size > 32: + ctype = "unsigned long long int" + elif size > 16: + ctype = "unsigned int" + elif size > 8: + ctype = "unsigned short int" + else: + ctype = "unsigned char" + + r += "static inline "+ctype+" "+reg_name+"_read(void) {\n" + if size > 1: + r += "\t"+ctype+" r = MMPTR("+hex(reg_base)+");\n" + for byte in range(1, nwords): + r += "\tr <<= "+str(busword)+";\n\tr |= MMPTR("+hex(reg_base+4*byte)+");\n" + r += "\treturn r;\n}\n" + else: + r += "\treturn MMPTR("+hex(reg_base)+");\n}\n" + + if not read_only: + r += "static inline void "+reg_name+"_write("+ctype+" value) {\n" + for word in range(nwords): + shift = (nwords-word-1)*busword + if shift: + value_shifted = "value >> "+str(shift) + else: + value_shifted = "value" + r += "\tMMPTR("+hex(reg_base+4*word)+") = "+value_shifted+";\n" + r += "}\n" + return r + +def get_csr_header(regions, interrupt_map): + r = "#ifndef __GENERATED_CSR_H\n#define __GENERATED_CSR_H\n#include \n" + for name, origin, busword, obj in regions: + if isinstance(obj, Memory): + fullname = name + "_" + memory.name_override + r += "#define "+fullname.upper()+"_BASE "+hex(origin)+"\n" + else: + r += "\n/* "+name+" */\n" + r += "#define "+name.upper()+"_BASE "+hex(origin)+"\n" + for csr in obj: + nr = (csr.size + busword - 1)//busword + r += _get_rw_functions(name + "_" + csr.name, origin, nr, busword, isinstance(csr, CSRStatus)) + origin += 4*nr + try: + interrupt_nr = interrupt_map[name] + except KeyError: + pass + else: + r += "#define "+name.upper()+"_INTERRUPT "+str(interrupt_nr)+"\n" + r += "\n#endif\n" + return r + +def get_csr_csv(regions): + r = "" + for name, origin, busword, obj in regions: + if not isinstance(obj, Memory): + for csr in obj: + nr = (csr.size + busword - 1)//busword + r += "{}_{},0x{:08x},{},{}\n".format(name, csr.name, origin, nr, "ro" if isinstance(csr, CSRStatus) else "rw") + origin += 4*nr + return r diff --git a/misoclib/tools/litescope/example_designs/targets/simple.py b/misoclib/tools/litescope/example_designs/targets/simple.py index 95a81e50..a282ffe8 100644 --- a/misoclib/tools/litescope/example_designs/targets/simple.py +++ b/misoclib/tools/litescope/example_designs/targets/simple.py @@ -27,7 +27,7 @@ class _CRG(Module): self.cd_sys.rst.eq(~rst_n) ] -class GenSoC(Module): +class SoC(Module): csr_base = 0x00000000 csr_data_width = 32 csr_map = { @@ -71,16 +71,16 @@ class GenSoC(Module): for name, memory, mapaddr, mmap in self.csrbankarray.srams: self.add_cpu_csr_region(name, 0xe0000000+0x800*mapaddr, flen(rmap.bus.dat_w), memory) -class LiteScopeSoC(GenSoC, AutoCSR): +class LiteScopeSoC(SoC, AutoCSR): default_platform = "de0nano" csr_map = { "io": 10, "la": 11 } - csr_map.update(GenSoC.csr_map) + csr_map.update(SoC.csr_map) def __init__(self, platform): clk_freq = 50*1000000 - GenSoC.__init__(self, platform, clk_freq) + SoC.__init__(self, platform, clk_freq) self.submodules.crg = _CRG(platform.request("clk50")) self.submodules.io = LiteScopeIO(8) diff --git a/targets/de0nano.py b/targets/de0nano.py index 13217709..3062cb3c 100644 --- a/targets/de0nano.py +++ b/targets/de0nano.py @@ -5,7 +5,7 @@ from misoclib.cpu.peripherals import gpio from misoclib.mem import sdram from misoclib.mem.sdram.phy import gensdrphy from misoclib.com import uart -from misoclib.gensoc import SDRAMSoC +from misoclib.soc import SDRAMSoC class _PLL(Module): def __init__(self, period_in, name, phase_shift, operation_mode): diff --git a/targets/kc705.py b/targets/kc705.py index a8fd017e..532b1365 100644 --- a/targets/kc705.py +++ b/targets/kc705.py @@ -4,7 +4,7 @@ from migen.genlib.resetsync import AsyncResetSynchronizer from misoclib.mem import sdram from misoclib.mem.sdram.phy import k7ddrphy from misoclib.mem.flash import spiflash -from misoclib.gensoc import SDRAMSoC, mem_decoder +from misoclib.soc import SDRAMSoC, mem_decoder from misoclib.com.liteeth.phy.gmii import LiteEthPHYGMII from misoclib.com.liteeth.mac import LiteEthMAC diff --git a/targets/mlabs_video.py b/targets/mlabs_video.py index 8ff171f3..fe8bf1b2 100644 --- a/targets/mlabs_video.py +++ b/targets/mlabs_video.py @@ -10,7 +10,7 @@ from misoclib.mem.sdram.phy import s6ddrphy from misoclib.mem.flash import norflash16 from misoclib.cpu.peripherals import gpio from misoclib.video import framebuffer -from misoclib.gensoc import SDRAMSoC, mem_decoder +from misoclib.soc import SDRAMSoC, mem_decoder from misoclib.com.liteeth.phy.mii import LiteEthPHYMII from misoclib.com.liteeth.mac import LiteEthMAC diff --git a/targets/pipistrello.py b/targets/pipistrello.py index 39ce3c8c..8c27d78b 100644 --- a/targets/pipistrello.py +++ b/targets/pipistrello.py @@ -6,7 +6,7 @@ from migen.genlib.resetsync import AsyncResetSynchronizer from misoclib.mem import sdram from misoclib.mem.sdram.phy import gensdrphy from misoclib.mem.flash import SpiFlash -from misoclib.gensoc import SDRAMSoC +from misoclib.soc import SDRAMSoC class _CRG(Module): def __init__(self, platform, clk_freq): diff --git a/targets/ppro.py b/targets/ppro.py index 3303c453..e9108344 100644 --- a/targets/ppro.py +++ b/targets/ppro.py @@ -6,7 +6,7 @@ from migen.genlib.resetsync import AsyncResetSynchronizer from misoclib.mem import sdram from misoclib.mem.sdram.phy import gensdrphy from misoclib.mem.flash import spiflash -from misoclib.gensoc import SDRAMSoC +from misoclib.soc import SDRAMSoC class _CRG(Module): def __init__(self, platform, clk_freq): diff --git a/targets/simple.py b/targets/simple.py index 02b23385..32c72ffb 100644 --- a/targets/simple.py +++ b/targets/simple.py @@ -1,7 +1,7 @@ from migen.fhdl.std import * from migen.bus import wishbone -from misoclib.gensoc import GenSoC, mem_decoder +from misoclib.soc import SoC, mem_decoder class _CRG(Module): def __init__(self, clk_in): @@ -17,9 +17,9 @@ class _CRG(Module): self.cd_sys.rst.eq(~rst_n) ] -class SimpleSoC(GenSoC): +class SimpleSoC(SoC): def __init__(self, platform, **kwargs): - GenSoC.__init__(self, platform, + SoC.__init__(self, platform, clk_freq=int((1/(platform.default_clk_period))*1000000000), with_rom=True, with_sdram=True, sdram_size=16*1024,