def __init__(self, sys_clk_freq=int(48e6), x5_clk_freq=None, toolchain="trellis", **kwargs): platform = evb_platform.Platform(toolchain=toolchain) # SoCCore ---------------------------------------------------------------------------------- SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SOC on @loxodes ECP5 Evaluation Board", ident_version=True, **kwargs) # CRG -------------------------------------------------------------------------------------- crg = _CRG(platform, sys_clk_freq) self.submodules.crg = crg # HyperRam --------------------------------------------------------------------------------- self.mem_map["hyperram"] = 0x20000000 self.submodules.hyperram = HyperRAM(platform.request("hyperram")) self.add_wb_slave(self.mem_map["hyperram"], self.hyperram.bus) self.add_memory_region("hyperram", self.mem_map["hyperram"], 8 * 1024 * 1024) # SPIFlash --------------------------------------------------------------------------------- self.submodules.spiflash = ECP5SPIFlash( pads=platform.request("spiflash"), sys_clk_freq=sys_clk_freq, spi_clk_freq=5e6, ) self.add_csr("spiflash") # Wishbone usb debug port # see https://gist.github.com/enjoy-digital/82ed88b77ef0b1e3e91b0592e44eaa14 os.system( "git clone https://github.com/litex-hub/valentyusb -b hw_cdc_eptri" ) sys.path.append("valentyusb") from valentyusb.usbcore.cpu import dummyusb, epfifo from valentyusb.usbcore import io as usbio usb_debug = True usb_pads = platform.request("usb_aux") usb_iobuf = usbio.IoBuf(usb_pads.d_p, usb_pads.d_n, usb_pads.pullup) self.submodules.usb = dummyusb.DummyUsb( usb_iobuf, debug=usb_debug ) #epfifo.PerEndpointFifoInterface(usb_iobuf, debug=usb_debug) self.add_wb_master(self.usb.debug_bridge.wishbone) #self.register_mem("vexriscv_debug", 0xf00f0000, self.cpu.debug_bus, 0x100) # https://github.com/enjoy-digital/litex/issues/345 # Leds ------------------------------------------------------------------------------------- self.submodules.leds = LedChaser(pads=platform.request_all("user_led"), sys_clk_freq=sys_clk_freq) self.add_csr("leds")
def __init__(self, platform, is_sim=False, **kwargs): clk_freq = int(48e6) SoCCore.__init__(self, platform, clk_freq, cpu_type=None, cpu_variant="linux+debug", integrated_sram_size=4096, **kwargs) if is_sim: self.submodules.crg = CocotbPlatform._CRG(self.platform) else: self.submodules.crg = _CRG(self.platform) # Add a "Version" module so we can see what version of the board this is. self.submodules.version = Version("proto2", [ (0x02, "proto2", "Prototype Version 2 (red)") ], 0) # Add a "USB" module to let us debug the device. usb_pads = platform.request("usb") usb_iobuf = usbio.IoBuf(usb_pads.d_p, usb_pads.d_n, usb_pads.pullup) self.submodules.usb = ClockDomainsRenamer({ "usb_48": "clk48", "usb_12": "clk12", })(DummyUsb(usb_iobuf, debug=True, product="Hackaday Supercon Badge")) self.add_wb_master(self.usb.debug_bridge.wishbone) # Add the 16 MB SPI flash as XIP memory at address 0x03000000 if not is_sim: flash = SpiFlashDualQuad(platform.request("spiflash4x"), dummy=5) flash.add_clk_primitive(self.platform.device) self.submodules.lxspi = flash self.register_mem("spiflash", 0x03000000, self.lxspi.bus, size=16 * 1024 * 1024) # Add the 16 MB SPI RAM at address 0x04000000 ram1 = SpiRamQuad(platform.request("spiram4x", 0), dummy=5) self.submodules.ram1 = ram1 self.register_mem("ram1", 0x04000000, self.ram1.bus, size=8 * 1024 * 1024) # Let us reboot the device self.submodules.reboot = Reboot(platform.request("programn")) # Add a Messible for sending messages to the host self.submodules.messible = Messible() # Ensure timing is correctly set up if not is_sim: self.platform.toolchain.build_template[1] += " --speed 8" # Add "speed grade 8" to nextpnr-ecp5 self.platform.toolchain.freq_constraints["sys"] = 48 if is_sim: class _WishboneBridge(Module): def __init__(self, interface): self.wishbone = interface self.add_cpu(_WishboneBridge(self.platform.request("wishbone"))) self.add_wb_master(self.cpu.wishbone)
def __init__(self, platform, output_dir="build", placer=None, pnr_seed=0, use_pll=True, **kwargs): clk_freq = int(12e6) self.submodules.crg = _CRG(platform, use_pll=use_pll) SoCCore.__init__(self, platform, clk_freq, cpu_type=None, cpu_variant=None, integrated_sram_size=0, with_uart=False, with_ctrl=False, **kwargs) # Add the LED driver block led_pads = platform.request("rgb_led") self.submodules.rgb = FomuRGB(led_pads) # UP5K has single port RAM, which is a dedicated 128 kilobyte block. # Use this as CPU RAM. spram_size = 128 * 1024 self.submodules.spram = up5kspram.Up5kSPRAM(size=spram_size) self.register_mem("sram", 0x10000000, self.spram.bus, spram_size) # Add USB pads. We use DummyUsb, which simply enumerates as a USB # device. Then all interaction is done via the wishbone bridge. usb_pads = platform.request("usb") usb_iobuf = usbio.IoBuf(usb_pads.d_p, usb_pads.d_n, usb_pads.pullup) self.submodules.usb = dummyusb.DummyUsb(usb_iobuf, debug=True) self.add_wb_master(self.usb.debug_bridge.wishbone) # Add "-relut -dffe_min_ce_use 4" to the synth_ice40 command. # "-reult" adds an additional LUT pass to pack more stuff in, and # "-dffe_min_ce_use 4" flag prevents Yosys from generating a # Clock Enable signal for a LUT that has fewer than 4 flip-flops. # This increases density, and lets us use the FPGA more efficiently. platform.toolchain.nextpnr_yosys_template[ 2] += " -relut -dffe_min_ce_use 4" # Allow us to set the nextpnr seed, because some values don't meet timing. platform.toolchain.nextpnr_build_template[1] += " --seed " + str( pnr_seed) # Different placers can improve packing efficiency, however not all placers # are enabled on all builds of nextpnr-ice40. Let the user override which # placer they want to use. if placer is not None: platform.toolchain.nextpnr_build_template[ 1] += " --placer {}".format(placer)
def __init__(self, sys_clk_freq=int(100e6), with_pwm=False, with_gpio=False, gpio_width=32, with_spi_master=False, spi_master_data_width=8, spi_master_clk_freq=8e6, **kwargs): platform = Platform(_io) # CRG -------------------------------------------------------------------------------------- self.submodules.crg = _CRG(platform) # SoCMini ---------------------------------------------------------------------------------- print(kwargs) SoCMini.__init__(self, platform, clk_freq=sys_clk_freq, **kwargs) usb_pads = platform.request("usb") usb_iobuf = usbio.IoBuf(usb_pads.d_p, usb_pads.d_n, usb_pads.pullup) self.submodules.usb = eptri.TriEndpointInterface(usb_iobuf, debug=False) self.add_csr("usb") # Wishbone Master if kwargs["bus"] == "wishbone": wb_bus = wishbone.Interface() self.bus.add_master(master=wb_bus) platform.add_extension(wb_bus.get_ios("wb")) wb_pads = platform.request("wb") self.comb += wb_bus.connect_to_pads(wb_pads, mode="slave") # IRQs for name, loc in sorted(self.irq.locs.items()): module = getattr(self, name) platform.add_extension([("irq_" + name, 0, Pins(1))]) irq_pin = platform.request("irq_" + name) self.comb += irq_pin.eq(module.ev.irq)
def __init__(self, platform, boot_source="rand", debug=None, bios_file=None, use_dsp=False, placer="heap", output_dir="build", pnr_seed=0, warmboot_offsets=None, **kwargs): # Disable integrated RAM as we'll add it later self.integrated_sram_size = 0 self.output_dir = output_dir clk_freq = int(12e6) self.submodules.crg = _CRG(platform) SoCCore.__init__(self, platform, clk_freq, integrated_sram_size=0, with_uart=False, **kwargs) usb_debug = False if debug is not None: if debug == "uart": from litex.soc.cores.uart import UARTWishboneBridge self.submodules.uart_bridge = UARTWishboneBridge(platform.request("serial"), clk_freq, baudrate=115200) self.add_wb_master(self.uart_bridge.wishbone) elif debug == "usb": usb_debug = True elif debug == "spi": import spibone # Add SPI Wishbone bridge debug_device = [ ("spidebug", 0, Subsignal("mosi", Pins("dbg:0")), Subsignal("miso", Pins("dbg:1")), Subsignal("clk", Pins("dbg:2")), Subsignal("cs_n", Pins("dbg:3")), ) ] platform.add_extension(debug_device) spi_pads = platform.request("spidebug") self.submodules.spibone = ClockDomainsRenamer("usb_12")(spibone.SpiWishboneBridge(spi_pads, wires=4)) self.add_wb_master(self.spibone.wishbone) if hasattr(self, "cpu") and not isinstance(self.cpu, CPUNone): self.cpu.use_external_variant("rtl/VexRiscv_Fomu_Debug.v") os.path.join(output_dir, "gateware") self.register_mem("vexriscv_debug", 0xf00f0000, self.cpu.debug_bus, 0x100) else: if hasattr(self, "cpu") and not isinstance(self.cpu, CPUNone): self.cpu.use_external_variant("rtl/VexRiscv_Fomu.v") # SPRAM- UP5K has single port RAM, might as well use it as SRAM to # free up scarce block RAM. spram_size = 128*1024 self.submodules.spram = up5kspram.Up5kSPRAM(size=spram_size) self.register_mem("sram", self.mem_map["sram"], self.spram.bus, spram_size) # Add a Messible for device->host communications self.submodules.messible = Messible() if boot_source == "rand": kwargs['cpu_reset_address'] = 0 bios_size = 0x2000 self.submodules.random_rom = RandomFirmwareROM(bios_size) self.add_constant("ROM_DISABLE", 1) self.register_rom(self.random_rom.bus, bios_size) elif boot_source == "bios": kwargs['cpu_reset_address'] = 0 if bios_file is None: self.integrated_rom_size = bios_size = 0x2000 self.submodules.rom = wishbone.SRAM(bios_size, read_only=True, init=[]) self.register_rom(self.rom.bus, bios_size) else: bios_size = 0x2000 self.submodules.firmware_rom = FirmwareROM(bios_size, bios_file) self.add_constant("ROM_DISABLE", 1) self.register_rom(self.firmware_rom.bus, bios_size) elif boot_source == "spi": kwargs['cpu_reset_address'] = 0 self.integrated_rom_size = bios_size = 0x2000 gateware_size = 0x1a000 self.flash_boot_address = self.mem_map["spiflash"] + gateware_size self.submodules.rom = wishbone.SRAM(bios_size, read_only=True, init=[]) self.register_rom(self.rom.bus, bios_size) else: raise ValueError("unrecognized boot_source: {}".format(boot_source)) # The litex SPI module supports memory-mapped reads, as well as a bit-banged mode # for doing writes. spi_pads = platform.request("spiflash4x") self.submodules.lxspi = spi_flash.SpiFlashDualQuad(spi_pads, dummy=platform.spi_dummy, endianness="little") self.register_mem("spiflash", self.mem_map["spiflash"], self.lxspi.bus, size=platform.spi_size) # Add USB pads, as well as the appropriate USB controller. If no CPU is # present, use the DummyUsb controller. usb_pads = platform.request("usb") usb_iobuf = usbio.IoBuf(usb_pads.d_p, usb_pads.d_n, usb_pads.pullup) if hasattr(self, "cpu") and not isinstance(self.cpu, CPUNone): self.submodules.usb = eptri.TriEndpointInterface(usb_iobuf, debug=usb_debug) else: self.submodules.usb = dummyusb.DummyUsb(usb_iobuf, debug=usb_debug) if usb_debug: self.add_wb_master(self.usb.debug_bridge.wishbone) # For the EVT board, ensure the pulldown pin is tristated as an input if hasattr(usb_pads, "pulldown"): pulldown = TSTriple() self.specials += pulldown.get_tristate(usb_pads.pulldown) self.comb += pulldown.oe.eq(0) # Add GPIO pads for the touch buttons platform.add_extension(TouchPads.touch_device) self.submodules.touch = TouchPads(platform.request("touch_pads")) # Allow the user to reboot the ICE40. Additionally, connect the CPU # RESET line to a register that can be modified, to allow for # us to debug programs even during reset. self.submodules.reboot = SBWarmBoot(self, warmboot_offsets) if hasattr(self, "cpu") and not isinstance(self.cpu, CPUNone): self.cpu.cpu_params.update( i_externalResetVector=self.reboot.addr.storage, ) self.submodules.rgb = SBLED(platform.revision, platform.request("rgb_led")) self.submodules.version = Version(platform.revision, self, pnr_seed, models=[ ("0x45", "E", "Fomu EVT"), ("0x44", "D", "Fomu DVT"), ("0x50", "P", "Fomu PVT (production)"), ("0x48", "H", "Fomu Hacker"), ("0x3f", "?", "Unknown model"), ]) # Override default LiteX's yosys/build templates assert hasattr(platform.toolchain, "yosys_template") assert hasattr(platform.toolchain, "build_template") platform.toolchain.yosys_template = [ "{read_files}", "attrmap -tocase keep -imap keep=\"true\" keep=1 -imap keep=\"false\" keep=0 -remove keep=0", "synth_ice40 -json {build_name}.json -top {build_name}", ] platform.toolchain.build_template = [ "yosys -q -l {build_name}.rpt {build_name}.ys", "nextpnr-ice40 --json {build_name}.json --pcf {build_name}.pcf --asc {build_name}.txt \ --pre-pack {build_name}_pre_pack.py --{architecture} --package {package}", "icepack {build_name}.txt {build_name}.bin" ] # Add "-relut -dffe_min_ce_use 4" to the synth_ice40 command. # The "-reult" adds an additional LUT pass to pack more stuff in, # and the "-dffe_min_ce_use 4" flag prevents Yosys from generating a # Clock Enable signal for a LUT that has fewer than 4 flip-flops. # This increases density, and lets us use the FPGA more efficiently. platform.toolchain.yosys_template[2] += " -relut -abc2 -dffe_min_ce_use 4 -relut" if use_dsp: platform.toolchain.yosys_template[2] += " -dsp" # Disable final deep-sleep power down so firmware words are loaded # onto softcore's address bus. platform.toolchain.build_template[2] = "icepack -s {build_name}.txt {build_name}.bin" # Allow us to set the nextpnr seed platform.toolchain.build_template[1] += " --seed " + str(pnr_seed) if placer is not None: platform.toolchain.build_template[1] += " --placer {}".format(placer)
def __init__(self, board, pnr_placer="heap", pnr_seed=0, usb_core="dummyusb", usb_bridge=False, **kwargs): """Create a basic SoC for Fomu. Create a basic SoC for Fomu, including a 48 MHz and 12 MHz clock domain called `usb_48` and `usb_12`. The `sys` frequency will run at 12 MHz. The USB core will optionally have a bridge to the Wishbone bus. Args: board (str): Which Fomu board to build for: pvt, evt, or hacker pnr_placer (str): Which placer to use in nextpnr pnr_seed (int): Which seed to use in nextpnr usb_core (str): The name of the USB core to use, if any: dummyusb, epfifo usb_bridge (bool): Whether to include a USB-to-Wishbone bridge Raises: ValueError: If either the `usb_core` or `board` are unrecognized Returns: Newly-constructed SoC """ if board == "pvt": from litex_boards.partner.platforms.fomu_pvt import Platform elif board == "hacker": from litex_boards.partner.platforms.fomu_hacker import Platform elif board == "evt": from litex_boards.partner.platforms.fomu_evt import Platform else: raise ValueError("unrecognized fomu board: {}".format(board)) platform = Platform() if "cpu_type" not in kwargs: kwargs["cpu_type"] = None kwargs["cpu_variant"] = None clk_freq = int(12e6) SoCCore.__init__(self, platform, clk_freq, integrated_sram_size=0, with_uart=False, with_ctrl=False, **kwargs) self.submodules.crg = _CRG(platform) # UP5K has single port RAM, which is a dedicated 128 kilobyte block. # Use this as CPU RAM. spram_size = 128 * 1024 self.submodules.spram = up5kspram.Up5kSPRAM(size=spram_size) self.register_mem("sram", self.mem_map["sram"], self.spram.bus, spram_size) if usb_core is not None: # Add USB pads. We use DummyUsb, which simply enumerates as a USB # device. Then all interaction is done via the wishbone bridge. usb_pads = platform.request("usb") usb_iobuf = usbio.IoBuf(usb_pads.d_p, usb_pads.d_n, usb_pads.pullup) if usb_core == "dummyusb": self.submodules.usb = dummyusb.DummyUsb(usb_iobuf, debug=usb_bridge) elif usb_core == "epfifo": self.submodules.usb = epfifo.PerEndpointFifo(usb_iobuf, debug=usb_bridge) else: raise ValueError("unrecognized usb_core: {}".args(usb_core)) if usb_bridge: self.add_wb_master(self.usb.debug_bridge.wishbone) # Add "-relut -dffe_min_ce_use 4" to the synth_ice40 command. # "-reult" adds an additional LUT pass to pack more stuff in, and # "-dffe_min_ce_use 4" flag prevents Yosys from generating a # Clock Enable signal for a LUT that has fewer than 4 flip-flops. # This increases density, and lets us use the FPGA more efficiently. platform.toolchain.nextpnr_yosys_template[ 2] += " -relut -dffe_min_ce_use 4" # Allow us to set the nextpnr seed, because some values don't meet timing. platform.toolchain.nextpnr_build_template[1] += " --seed " + str( pnr_seed) # Different placers can improve packing efficiency, however not all placers # are enabled on all builds of nextpnr-ice40. Let the user override which # placer they want to use. if pnr_placer is not None: platform.toolchain.nextpnr_build_template[ 1] += " --placer {}".format(pnr_placer)
def __init__(self, platform, debug=False, **kwargs): clk_freq = int(12e6) if "cpu_type" not in kwargs: kwargs["cpu_type"] = None kwargs["cpu_variant"] = None if "with_uart" not in kwargs: kwargs["with_uart"] = False if "with_ctrl" not in kwargs: kwargs["with_ctrl"] = False kwargs["integrated_sram_size"] = 0 bios_size = kwargs["integrated_rom_size"] kwargs["integrated_rom_size"] = 0 kwargs["cpu_reset_address"] = self.mem_map["spiflash"]+platform.bootloader_size+platform.gateware_size SoCCore.__init__(self, platform, clk_freq, **kwargs) self.submodules.crg = _CRG(platform) # SPRAM- UP5K has single port RAM, might as well use it as SRAM to # free up scarce block RAM. spram_size = 128*1024 self.submodules.spram = up5kspram.Up5kSPRAM(size=spram_size) self.register_mem("sram", self.mem_map["sram"], self.spram.bus, spram_size) # Control and Status self.submodules.cas = cas.ControlAndStatus(platform, clk_freq) # SPI flash peripheral self.submodules.spiflash = spi_flash.SpiFlashSingle( platform.request("spiflash"), dummy=platform.spiflash_read_dummy_bits, div=platform.spiflash_clock_div) self.add_csr("spiflash") self.add_constant("SPIFLASH_PAGE_SIZE", platform.spiflash_page_size) self.add_constant("SPIFLASH_SECTOR_SIZE", platform.spiflash_sector_size) self.register_mem("spiflash", self.mem_map["spiflash"], self.spiflash.bus, size=platform.spiflash_total_size) self.add_constant("ROM_DISABLE", 1) self.add_memory_region( "rom", kwargs["cpu_reset_address"], bios_size, type="cached+linker") self.flash_boot_address = kwargs["cpu_reset_address"]+bios_size define_flash_constants(self) # We don't have a DRAM, so use the remaining SPI flash for user # program. self.add_memory_region("user_flash", self.flash_boot_address, # Leave a grace area- possible one-by-off bug in add_memory_region? # Possible fix: addr < origin + length - 1 platform.spiflash_total_size - (self.flash_boot_address - self.mem_map["spiflash"]) - 0x100, type="cached+linker") # Add USB pads usb_pads = platform.request("usb") usb_iobuf = usbio.IoBuf(usb_pads.d_p, usb_pads.d_n, usb_pads.pullup) self.submodules.usb = dummyusb.DummyUsb(usb_iobuf, debug=debug) if debug: self.add_wb_master(self.usb.debug_bridge.wishbone) # For the EVT board, ensure the pulldown pin is tristated as an input if hasattr(usb_pads, "pulldown"): pulldown = TSTriple() self.specials += pulldown.get_tristate(usb_pads.pulldown) self.comb += pulldown.oe.eq(0)
def __init__(self, platform, is_sim=False, debug=True, **kwargs): clk_freq = int(12e6) SoCCore.__init__(self, platform, clk_freq, integrated_rom_size=16384, integrated_sram_size=131072, with_uart=True, uart_stub=True, **kwargs) if is_sim: self.submodules.crg = CocotbPlatform._CRG(self.platform) else: self.submodules.crg = _CRG(self.platform, fast_sysclk=False) # Add a "Version" module so we can see what version of the board this is. self.submodules.version = Version( "proto2", [(0x02, "proto2", "Prototype Version 2 (red)")], 0) # Add a "USB" module to let us debug the device. usb_pads = platform.request("usb") usb_iobuf = usbio.IoBuf(usb_pads.d_p, usb_pads.d_n, usb_pads.pullup) self.submodules.usb = ClockDomainsRenamer({ "usb_48": "clk48", "usb_12": "clk12", # })(DummyUsb(usb_iobuf, debug=debug, product="Hackaday Supercon Badge", cdc=True)) })(TriEndpointInterface(usb_iobuf, debug=debug)) dir_path = os.path.dirname(os.path.realpath(__file__)) if debug: from litex.soc.cores.uart import UARTWishboneBridge self.submodules.uart_bridge = UARTWishboneBridge( platform.request("serial"), clk_freq, baudrate=115200) self.add_wb_master(self.uart_bridge.wishbone) self.add_wb_master(self.usb.debug_bridge.wishbone) if self.cpu_type is not None: self.register_mem("vexriscv_debug", 0xf00f0000, self.cpu.debug_bus, 0x200) self.cpu.use_external_variant(dir_path + "/rtl/VexRiscv_HaD_Debug.v") elif self.cpu_type is not None: self.cpu.use_external_variant(dir_path + "/rtl/VexRiscv_HaD.v") # Add the 16 MB SPI flash as XIP memory at address 0x03000000 if not is_sim: flash = SpiFlashDualQuad(platform.request("spiflash4x"), dummy=6, endianness="little") flash.add_clk_primitive(self.platform.device) self.submodules.lxspi = flash self.register_mem("spiflash", self.mem_map["spiflash"], self.lxspi.bus, size=16 * 1024 * 1024) # self.submodules.picorvspi = flash = PicoRVSpi(self.platform, pads=platform.request("spiflash"), size=16 * 1024 * 1024) # self.register_mem("spiflash", self.mem_map["spiflash"], self.picorvspi.bus, size=self.picorvspi.size) self.add_constant("ROM_BOOT_ADDRESS", self.mem_map["spiflash"] + 0x300000) # # Add the 16 MB SPI RAM at address 0x40000000 # Value at 40010000: afbfcfef reset_cycles = 2**14 - 1 if is_sim: reset_cycles = 0 ram = SpiRamDualQuad(platform.request("spiram4x", 0), platform.request("spiram4x", 1), dummy=5, reset_cycles=reset_cycles, qpi=True) self.submodules.ram = ram self.register_mem("main_ram", self.mem_map["main_ram"], self.ram.bus, size=16 * 1024 * 1024) # Let us reboot the device self.submodules.reboot = Reboot(platform.request("programn")) # Add a Messible for sending messages to the host self.submodules.messible = Messible() # Add an LCD so we can see what's up self.submodules.lcdif = LCDIF(platform.request("lcd")) # Ensure timing is correctly set up if not is_sim: self.platform.toolchain.build_template[ 1] += " --speed 8" # Add "speed grade 8" to nextpnr-ecp5 self.platform.toolchain.freq_constraints["sys"] = 48 if is_sim: self.add_wb_master(self.platform.request("wishbone")) # SAO if not kwargs["sao0_disable"]: self.submodules.sao0 = ShittyAddOn( self.platform, self.platform.request("sao", 0), disable_i2c=kwargs["sao0_disable_i2c"]) self.add_csr("sao0") if not kwargs["sao1_disable"]: self.submodules.sao1 = ShittyAddOn( self.platform, self.platform.request("sao", 1), disable_i2c=kwargs["sao1_disable_i2c"]) self.add_csr("sao1") # PMOD platform.add_extension(_pmod_gpio) self.submodules.pmod = GPIOBidirectional( self.platform.request("pmod_gpio")) self.add_csr("pmod") # GENIO if not kwargs["genio_disable"]: platform.add_extension(_genio_gpio) self.submodules.genio = GPIOBidirectional( self.platform.request("genio_gpio")) self.add_csr("genio") # LEDs self.submodules.led0 = gpio.GPIOOut(self.platform.request("led", 0)) self.add_csr("led0") self.submodules.led1 = gpio.GPIOOut(self.platform.request("led", 1)) self.add_csr("led1") # Keypad self.submodules.keypad = gpio.GPIOIn( Cat(self.platform.request("keypad", 0).flatten())) self.add_csr("keypad")
def __init__(self, platform): # Set up the basic address space layout and create basic # select signals for each entry in the memory map. self.address_bus = Signal(16) for name, address_range in self.memory_map.items(): fast_sel = Signal(name=name + "_sel") slow_sel = Signal(name=name + "_sel_slow") setattr(self, name + "_sel", fast_sel) setattr(self, name + "_sel_slow", slow_sel) self.comb += [ fast_sel.eq( Mux( wrap(self.address_bus >= address_range.start) & wrap(self.address_bus < address_range.start + address_range.size), 1, 0)) ] # Latched versions, needed to drive the databus logic self.sync += [ slow_sel.eq( Mux( wrap(self.address_bus >= address_range.start) & wrap(self.address_bus < address_range.start + address_range.size), 1, 0)) ] # Fomu clock/reset generator, using the PLL to generate a 48MHz and 12MHz clock. # The 12MHz clock becomes cd_sys; the 48MHz clock is available as cd_usb_48. self.submodules.crg = CRG(platform, use_pll=True) #self.clock_domains.cd_sys = ClockDomain() #clk48_raw = platform.request("clk48") #platform.add_period_constraint(clk48_raw, 1e9/48e6) #self.startup_delay = Signal(12, reset=4095) #self.comb += [self.cd_sys.clk.eq(clk48_raw), # self.cd_sys.rst.eq(self.startup_delay!=0)] #self.sync += [ # If(self.startup_delay==0,self.startup_delay.eq(0)).Else(self.startup_delay.eq(self.startup_delay-1)) # ] #self.clk_freq = 48000000 # Output the reset to avoid some trimming. #self.comb += [ # platform.request("usb").d_p.eq(self.cd_sys.rst) # ] # CPU self.submodules.cpu = A6502(platform) # Basic RAM. self.submodules.ram = FomuSPRAM(platform) # Boot ROM (for debug only) self.submodules.high_os_rom = FomuROM(platform) # LEDs for I/O self.submodules.rgb = SBLED(platform) # Wishbone bridge self.submodules.wishbone = FomuBridge(platform) # Build up a mux for the data bus (in), IRQ, NMI, RDY, and connect up the chip selects. mux = Constant(0) rdy_mux = Constant(1) irq_mux = Constant(0) nmi_mux = Constant(0) for name, address_range in self.memory_map.items(): try: # Find the module and its select signals module = getattr(self, name) except AttributeError: print("Warning: Memory map defines \'" + name + "\' but no submodule exists.") continue select_fast = getattr(self, name + "_sel") select_slow = getattr(self, name + "_sel_slow") # Extend the existing muxes for this module. Slow select used for mux # because this CPU core reads one cycle behind the address bus. mux = Mux(select_slow, module.data_out, mux) rdy_mux = Mux(select_slow, module.rdy, rdy_mux) irq_mux = irq_mux | module.irq nmi_mux = nmi_mux | module.nmi self.comb += [ # Connect up the CS signals. module.cs.eq(select_fast), module.cs_slow.eq(select_slow), # Wire up the address bus in to each device too. module.address.eq(self.address_bus - address_range.start), # And the data bus out to it. module.data_in.eq(self.cpu.data_out), module.we.eq(self.cpu.we) ] print("Connected device", name, "at", address_range) print("Constructed data mux:", mux) print("Constructed RDY mux:", rdy_mux) self.comb += [ self.cpu.data_in.eq(mux), self.cpu.rdy.eq(rdy_mux), self.cpu.irq.eq(irq_mux), self.cpu.nmi.eq(nmi_mux), self.address_bus.eq(self.cpu.address) ] # Set up a dummyusb device. from valentyusb.usbcore import io as usbio usb_pads = platform.request("usb") usb_iobuf = usbio.IoBuf(usb_pads.d_p, usb_pads.d_n, usb_pads.pullup) self.submodules.usb = FomuUSBCDC(usb_iobuf)
def __init__(self, board, pnr_placer="heap", pnr_seed=0, usb_core="dummyusb", usb_bridge=False, **kwargs): """Create a basic SoC for Fomu. Create a basic SoC for Fomu, including a 48 MHz and 12 MHz clock domain called `usb_48` and `usb_12`. The `sys` frequency will run at 12 MHz. The USB core will optionally have a bridge to the Wishbone bus. Args: board (str): Which Fomu board to build for: pvt, evt, or hacker pnr_placer (str): Which placer to use in nextpnr pnr_seed (int): Which seed to use in nextpnr usb_core (str): The name of the USB core to use, if any: dummyusb, epfifo usb_bridge (bool): Whether to include a USB-to-Wishbone bridge Raises: ValueError: If either the `usb_core` or `board` are unrecognized Returns: Newly-constructed SoC """ if board == "pvt": from litex_boards.partner.platforms.fomu_pvt import Platform elif board == "hacker": from litex_boards.partner.platforms.fomu_hacker import Platform elif board == "evt": from litex_boards.partner.platforms.fomu_evt import Platform else: raise ValueError("unrecognized fomu board: {}".format(board)) platform = Platform() if "cpu_type" not in kwargs: kwargs["cpu_type"] = None kwargs["cpu_variant"] = None clk_freq = int(12e6) SoCCore.__init__(self, platform, clk_freq, integrated_sram_size=0, with_uart=False, with_ctrl=False, **kwargs) self.submodules.crg = _CRG(platform) # UP5K has single port RAM, which is a dedicated 128 kilobyte block. # Use this as CPU RAM. spram_size = 128 * 1024 self.submodules.spram = up5kspram.Up5kSPRAM(size=spram_size) self.register_mem("sram", self.mem_map["sram"], self.spram.bus, spram_size) if usb_core is not None: # Add USB pads. We use DummyUsb, which simply enumerates as a USB # device. Then all interaction is done via the wishbone bridge. usb_pads = platform.request("usb") usb_iobuf = usbio.IoBuf(usb_pads.d_p, usb_pads.d_n, usb_pads.pullup) if usb_core == "dummyusb": self.submodules.usb = dummyusb.DummyUsb(usb_iobuf, debug=usb_bridge) elif usb_core == "epfifo": self.submodules.usb = epfifo.PerEndpointFifo(usb_iobuf, debug=usb_bridge) else: raise ValueError("unrecognized usb_core: {}".args(usb_core)) if usb_bridge: self.add_wb_master(self.usb.debug_bridge.wishbone)
def __init__(self, platform, boot_source="rand", debug=None, bios_file=None, use_pll=True, use_dsp=False, placer=None, output_dir="build", pnr_seed=0, **kwargs): # Disable integrated RAM as we'll add it later self.integrated_sram_size = 0 self.output_dir = output_dir clk_freq = int(12e6) self.submodules.crg = _CRG(platform, use_pll=use_pll) SoCCore.__init__(self, platform, clk_freq, integrated_sram_size=0, with_uart=False, **kwargs) usb_debug = False if debug is not None: if debug == "uart": from litex.soc.cores.uart import UARTWishboneBridge self.submodules.uart_bridge = UARTWishboneBridge( platform.request("serial"), clk_freq, baudrate=115200) self.add_wb_master(self.uart_bridge.wishbone) elif debug == "usb": usb_debug = True if hasattr(self, "cpu"): self.cpu.use_external_variant("rtl/2-stage-1024-cache-debug.v") self.copy_memory_file( "2-stage-1024-cache-debug.v_toplevel_RegFilePlugin_regFile.bin" ) os.path.join(output_dir, "gateware") self.register_mem("vexriscv_debug", 0xf00f0000, self.cpu.debug_bus, 0x100) else: if hasattr(self, "cpu"): self.cpu.use_external_variant("rtl/2-stage-1024-cache.v") self.copy_memory_file( "2-stage-1024-cache.v_toplevel_RegFilePlugin_regFile.bin") # SPRAM- UP5K has single port RAM, might as well use it as SRAM to # free up scarce block RAM. spram_size = 128 * 1024 self.submodules.spram = up5kspram.Up5kSPRAM(size=spram_size) self.register_mem("sram", self.mem_map["sram"], self.spram.bus, spram_size) if boot_source == "rand": kwargs['cpu_reset_address'] = 0 bios_size = 0x2000 self.submodules.random_rom = RandomFirmwareROM(bios_size) self.add_constant("ROM_DISABLE", 1) self.register_rom(self.random_rom.bus, bios_size) elif boot_source == "bios": kwargs['cpu_reset_address'] = 0 if bios_file is None: self.integrated_rom_size = bios_size = 0x2000 self.submodules.rom = wishbone.SRAM(bios_size, read_only=True, init=[]) self.register_rom(self.rom.bus, bios_size) else: bios_size = 0x2000 self.submodules.firmware_rom = FirmwareROM( bios_size, bios_file) self.add_constant("ROM_DISABLE", 1) self.register_rom(self.firmware_rom.bus, bios_size) elif boot_source == "spi": bios_size = 0x8000 kwargs['cpu_reset_address'] = self.mem_map[ "spiflash"] + platform.gateware_size self.add_memory_region("rom", kwargs['cpu_reset_address'], bios_size) self.add_constant("ROM_DISABLE", 1) self.flash_boot_address = self.mem_map[ "spiflash"] + platform.gateware_size + bios_size self.add_memory_region( "user_flash", self.flash_boot_address, # Leave a grace area- possible one-by-off bug in add_memory_region? # Possible fix: addr < origin + length - 1 platform.spiflash_total_size - (self.flash_boot_address - self.mem_map["spiflash"]) - 0x100) else: raise ValueError( "unrecognized boot_source: {}".format(boot_source)) # Add a simple bit-banged SPI Flash module spi_pads = platform.request("spiflash") self.submodules.picorvspi = PicoRVSpi(platform, spi_pads) self.register_mem("spiflash", self.mem_map["spiflash"], self.picorvspi.bus, size=self.picorvspi.size) self.submodules.reboot = SBWarmBoot(self) if hasattr(self, "cpu"): self.cpu.cpu_params.update( i_externalResetVector=self.reboot.addr.storage, ) self.submodules.rgb = SBLED(platform.revision, platform.request("led")) self.submodules.version = Version(platform.revision, self) # Add USB pads usb_pads = platform.request("usb") usb_iobuf = usbio.IoBuf(usb_pads.d_p, usb_pads.d_n, usb_pads.pullup) if hasattr(self, "cpu"): self.submodules.usb = epfifo.PerEndpointFifoInterface( usb_iobuf, debug=usb_debug) else: self.submodules.usb = dummyusb.DummyUsb(usb_iobuf, debug=usb_debug) if usb_debug: self.add_wb_master(self.usb.debug_bridge.wishbone) # For the EVT board, ensure the pulldown pin is tristated as an input if hasattr(usb_pads, "pulldown"): pulldown = TSTriple() self.specials += pulldown.get_tristate(usb_pads.pulldown) self.comb += pulldown.oe.eq(0) # self.submodules.usb = epmem.MemInterface(usb_iobuf) # self.submodules.usb = unififo.UsbUniFifo(usb_iobuf) # Add GPIO pads for the touch buttons self.submodules.touch = TouchPads(platform.request("touch")) # Add "-relut -dffe_min_ce_use 4" to the synth_ice40 command. # The "-reult" adds an additional LUT pass to pack more stuff in, # and the "-dffe_min_ce_use 4" flag prevents Yosys from generating a # Clock Enable signal for a LUT that has fewer than 4 flip-flops. # This increases density, and lets us use the FPGA more efficiently. platform.toolchain.nextpnr_yosys_template[ 2] += " -relut -dffe_min_ce_use 4" if use_dsp: platform.toolchain.nextpnr_yosys_template[2] += " -dsp" # Disable final deep-sleep power down so firmware words are loaded # onto softcore's address bus. platform.toolchain.build_template[ 3] = "icepack -s {build_name}.txt {build_name}.bin" platform.toolchain.nextpnr_build_template[ 2] = "icepack -s {build_name}.txt {build_name}.bin" # Allow us to set the nextpnr seed platform.toolchain.nextpnr_build_template[1] += " --seed " + str( pnr_seed) if placer is not None: platform.toolchain.nextpnr_build_template[ 1] += " --placer {}".format(placer)
def __init__(self, pnr_placer="heap", pnr_seed=0, usb_core="dummyusb", usb_bridge=False, use_dsp=True, **kwargs): """Create a basic SoC for the TinyFPGA_BX. Create a basic SoC for TinyFPGA_BX, including a 48 MHz and 12 MHz clock domain called `usb_48` and `usb_12`. The `sys` frequency will run at 16 MHz. The USB core will optionally have a bridge to the Wishbone bus. Args: pnr_placer (str): Which placer to use in nextpnr pnr_seed (int): Which seed to use in nextpnr usb_core (str): The name of the USB core to use, if any: dummyusb, epfifo, eptri usb_bridge (bool): Whether to include a USB-to-Wishbone bridge Raises: ValueError: If the `usb_core` is unrecognized Returns: Newly-constructed SoC """ from litex_boards.platforms.tinyfpga_bx import Platform platform = Platform() if "cpu_type" not in kwargs: kwargs["cpu_type"] = None kwargs["cpu_variant"] = None clk_freq = int(16e6) if "with_uart" not in kwargs: kwargs["with_uart"] = False if "with_ctrl" not in kwargs: kwargs["with_ctrl"] = False kwargs["integrated_sram_size"] = 0 SoCCore.__init__(self, platform, clk_freq, **kwargs) self.submodules.crg = _CRG(platform) if usb_core is not None: # Add USB pads. We use DummyUsb, which simply enumerates as a USB # device. Then all interaction is done via the wishbone bridge. usb_pads = platform.request("usb") usb_iobuf = usbio.IoBuf(usb_pads.d_p, usb_pads.d_n, usb_pads.pullup) if usb_core == "dummyusb": self.submodules.usb = dummyusb.DummyUsb(usb_iobuf, debug=usb_bridge) elif usb_core == "epfifo": self.submodules.usb = epfifo.PerEndpointFifo(usb_iobuf, debug=usb_bridge) elif usb_core == "eptri": self.submodules.usb = eptri.TriEndpointInterface(usb_iobuf, debug=usb_bridge) else: raise ValueError("unrecognized usb_core: {}".format(usb_core)) if usb_bridge: self.add_wb_master(self.usb.debug_bridge.wishbone) # Override default LiteX's yosys/build templates assert hasattr(platform.toolchain, "yosys_template") assert hasattr(platform.toolchain, "build_template") platform.toolchain.yosys_template = [ "{read_files}", "attrmap -tocase keep -imap keep=\"true\" keep=1 -imap keep=\"false\" keep=0 -remove keep=0", "synth_ice40 -json {build_name}.json -top {build_name}", ] platform.toolchain.build_template = [ "yosys -q -l {build_name}.rpt {build_name}.ys", "nextpnr-ice40 --json {build_name}.json --pcf {build_name}.pcf --asc {build_name}.txt \ --pre-pack {build_name}_pre_pack.py --{architecture} --package {package}", "icepack {build_name}.txt {build_name}.bin" ] # Add "-relut -dffe_min_ce_use 4" to the synth_ice40 command. # The "-reult" adds an additional LUT pass to pack more stuff in, # and the "-dffe_min_ce_use 4" flag prevents Yosys from generating a # Clock Enable signal for a LUT that has fewer than 4 flip-flops. # This increases density, and lets us use the FPGA more efficiently. platform.toolchain.yosys_template[2] += " -relut -abc2 -dffe_min_ce_use 4 -relut" if use_dsp: platform.toolchain.yosys_template[2] += " -dsp" # Disable final deep-sleep power down so firmware words are loaded # onto softcore's address bus. platform.toolchain.build_template[2] = "icepack -s {build_name}.txt {build_name}.bin" # Allow us to set the nextpnr seed platform.toolchain.build_template[1] += " --seed " + str(pnr_seed) if pnr_placer is not None: platform.toolchain.build_template[1] += " --placer {}".format(pnr_placer)
def __init__(self, sys_clk_freq=int(48e6), toolchain="trellis", **kwargs): # Board Revision --------------------------------------------------------------------------- revision = kwargs.get("revision", "0.2") device = kwargs.get("device", "25F") platform = orangecrab.Platform(revision=revision, device=device, toolchain=toolchain) platform.add_extension(extras) # Disconnect Serial Debug (Stub required so BIOS is kept happy) kwargs['uart_name'] = "stream" # SoCCore ---------------------------------------------------------------------------------- SoCCore.__init__(self, platform, clk_freq=sys_clk_freq, csr_data_width=32, **kwargs) # connect UART stream to NULL self.comb += self.uart.source.ready.eq(1) # CRG -------------------------------------------------------------------------------------- self.submodules.crg = crg = CRG(platform, sys_clk_freq, with_usb_pll=True) # DDR3 SDRAM ------------------------------------------------------------------------------- if not self.integrated_main_ram_size: available_sdram_modules = { "MT41K64M16": MT41K64M16, "MT41K128M16": MT41K128M16, "MT41K256M16": MT41K256M16, "MT41K512M16": MT41K512M16, } sdram_module = available_sdram_modules.get( kwargs.get("sdram_device", "MT41K64M16")) ddram_pads = platform.request("ddram") self.submodules.ddrphy = ECP5DDRPHY(pads=ddram_pads, sys_clk_freq=sys_clk_freq) self.ddrphy.settings.rtt_nom = "disabled" self.add_csr("ddrphy") if hasattr(ddram_pads, "vccio"): self.comb += ddram_pads.vccio.eq(0b111111) if hasattr(ddram_pads, "gnd"): self.comb += ddram_pads.gnd.eq(0) self.comb += self.crg.stop.eq(self.ddrphy.init.stop) self.comb += self.crg.reset.eq(self.ddrphy.init.reset) self.add_sdram("sdram", phy=self.ddrphy, module=sdram_module(sys_clk_freq, "1:2"), origin=self.mem_map["main_ram"], size=kwargs.get("max_sdram_size", 0x40000000), l2_cache_size=kwargs.get("l2_size", 8192), l2_cache_min_data_width=kwargs.get( "min_l2_data_width", 128), l2_cache_reverse=True) # RGB LED self.submodules.rgb = RGB(platform.request("rgb_led", 0)) #self.submodules.gpio = GPIOTristateCustom(platform.request("gpio", 0)) self.submodules.gpio = IOPort(platform.request("gpio", 0)) try: self.submodules.button = GPIOIn(platform.request("usr_btn")) except: ... # Analog Mux #self.submodules.asense = AnalogSense(platform.request("analog")) # drive PROGRAMN HIGH self.comb += platform.request("rst_n").eq(1) # The litex SPI module supports memory-mapped reads, as well as a bit-banged mode # for doing writes. spi_pads = platform.request("spiflash4x") self.submodules.lxspi = spi_flash.SpiFlashDualQuad(spi_pads, dummy=6, endianness="little") self.lxspi.add_clk_primitive(platform.device) self.register_mem("spiflash", self.mem_map["spiflash"], self.lxspi.bus, size=16 * 1024 * 1024) # Attach USB to a seperate CSR bus that's decoupled from our CPU clock usb_pads = platform.request("usb") usb_iobuf = usbio.IoBuf(usb_pads.d_p, usb_pads.d_n, usb_pads.pullup) self.submodules.usb0 = CSRClockDomainWrapper(usb_iobuf) self.comb += self.cpu.interrupt[self.interrupt_map['usb']].eq( self.usb0.irq) from litex.soc.integration.soc_core import SoCRegion self.bus.add_slave( 'usb', self.usb0.bus, SoCRegion(origin=0x90000000, size=0x1000, cached=False)) self.constants[ "FLASH_BOOT_ADDRESS"] = self.mem_map['spiflash'] + 0x00100000