def __init__(self,
                 variant="a7-35",
                 toolchain="vivado",
                 sys_clk_freq=int(100e6),
                 with_ethernet=False,
                 with_etherbone=False,
                 eth_ip="192.168.1.50",
                 eth_dynamic_ip=False,
                 ident_version=True,
                 with_led_chaser=True,
                 with_jtagbone=True,
                 with_spi_flash=False,
                 with_pmod_gpio=False,
                 **kwargs):
        platform = arty.Platform(variant=variant, toolchain=toolchain)

        # SoCCore ----------------------------------------------------------------------------------
        SoCCore.__init__(self,
                         platform,
                         sys_clk_freq,
                         ident="LiteX SoC on Arty A7",
                         ident_version=ident_version,
                         **kwargs)

        # CRG --------------------------------------------------------------------------------------
        self.submodules.crg = _CRG(platform, sys_clk_freq)

        # DDR3 SDRAM -------------------------------------------------------------------------------
        if not self.integrated_main_ram_size:
            self.submodules.ddrphy = s7ddrphy.A7DDRPHY(
                platform.request("ddram"),
                memtype="DDR3",
                nphases=4,
                sys_clk_freq=sys_clk_freq)
            self.add_sdram("sdram",
                           phy=self.ddrphy,
                           module=MT41K128M16(sys_clk_freq, "1:4"),
                           l2_cache_size=kwargs.get("l2_size", 8192))

        # Ethernet / Etherbone ---------------------------------------------------------------------
        if with_ethernet or with_etherbone:
            self.submodules.ethphy = LiteEthPHYMII(
                clock_pads=self.platform.request("eth_clocks"),
                pads=self.platform.request("eth"))
            if with_ethernet:
                self.add_ethernet(phy=self.ethphy, dynamic_ip=eth_dynamic_ip)
            if with_etherbone:
                self.add_etherbone(phy=self.ethphy, ip_address=eth_ip)

        # Jtagbone ---------------------------------------------------------------------------------
        if with_jtagbone:
            self.add_jtagbone()

        # SPI Flash --------------------------------------------------------------------------------
        if with_spi_flash:
            from litespi.modules import S25FL128L
            from litespi.opcodes import SpiNorFlashOpCodes as Codes
            self.add_spi_flash(mode="4x",
                               module=S25FL128L(Codes.READ_1_1_4),
                               rate="1:2",
                               with_master=True)

        # Leds -------------------------------------------------------------------------------------
        if with_led_chaser:
            self.submodules.leds = LedChaser(
                pads=platform.request_all("user_led"),
                sys_clk_freq=sys_clk_freq)

        # GPIOs ------------------------------------------------------------------------------------
        if with_pmod_gpio:
            platform.add_extension(arty.raw_pmod_io("pmoda"))
            self.submodules.gpio = GPIOTristate(platform.request("pmoda"))
Beispiel #2
0
    def __init__(self,
                 with_sdram=False,
                 with_ethernet=False,
                 ethernet_phy_model="sim",
                 with_etherbone=False,
                 etherbone_mac_address=0x10e2d5000001,
                 etherbone_ip_address="192.168.1.51",
                 with_analyzer=False,
                 sdram_module="MT48LC16M16",
                 sdram_init=[],
                 sdram_data_width=32,
                 sdram_spd_data=None,
                 sdram_verbosity=0,
                 with_i2c=False,
                 with_sdcard=False,
                 with_spi_flash=False,
                 spi_flash_init=[],
                 with_gpio=False,
                 sim_debug=False,
                 trace_reset_on=False,
                 **kwargs):
        platform = Platform()
        sys_clk_freq = int(1e6)

        # SoCCore ----------------------------------------------------------------------------------
        SoCCore.__init__(self,
                         platform,
                         clk_freq=sys_clk_freq,
                         ident="LiteX Simulation",
                         **kwargs)

        # CRG --------------------------------------------------------------------------------------
        self.submodules.crg = CRG(platform.request("sys_clk"))

        # SDRAM ------------------------------------------------------------------------------------
        if not self.integrated_main_ram_size and with_sdram:
            sdram_clk_freq = int(100e6)  # FIXME: use 100MHz timings
            if sdram_spd_data is None:
                sdram_module_cls = getattr(litedram_modules, sdram_module)
                sdram_rate = "1:{}".format(
                    sdram_module_nphases[sdram_module_cls.memtype])
                sdram_module = sdram_module_cls(sdram_clk_freq, sdram_rate)
            else:
                sdram_module = litedram_modules.SDRAMModule.from_spd_data(
                    sdram_spd_data, sdram_clk_freq)
            self.submodules.sdrphy = SDRAMPHYModel(module=sdram_module,
                                                   data_width=sdram_data_width,
                                                   clk_freq=sdram_clk_freq,
                                                   verbosity=sdram_verbosity,
                                                   init=sdram_init)
            self.add_sdram("sdram",
                           phy=self.sdrphy,
                           module=sdram_module,
                           l2_cache_size=kwargs.get("l2_size", 8192),
                           l2_cache_min_data_width=kwargs.get(
                               "min_l2_data_width", 128),
                           l2_cache_reverse=False)
            if sdram_init != []:
                # Skip SDRAM test to avoid corrupting pre-initialized contents.
                self.add_constant("SDRAM_TEST_DISABLE")
            else:
                # Reduce memtest size for simulation speedup
                self.add_constant("MEMTEST_DATA_SIZE", 8 * 1024)
                self.add_constant("MEMTEST_ADDR_SIZE", 8 * 1024)

        # Ethernet / Etherbone PHY -----------------------------------------------------------------
        if with_ethernet or with_etherbone:
            if ethernet_phy_model == "sim":
                self.submodules.ethphy = LiteEthPHYModel(
                    self.platform.request("eth", 0))
            elif ethernet_phy_model == "xgmii":
                self.submodules.ethphy = LiteEthPHYXGMII(None,
                                                         self.platform.request(
                                                             "xgmii_eth", 0),
                                                         model=True)
            elif ethernet_phy_model == "gmii":
                self.submodules.ethphy = LiteEthPHYGMII(None,
                                                        self.platform.request(
                                                            "gmii_eth", 0),
                                                        model=True)
            else:
                raise ValueError("Unknown Ethernet PHY model:",
                                 ethernet_phy_model)

        # Ethernet and Etherbone -------------------------------------------------------------------
        if with_ethernet and with_etherbone:
            etherbone_ip_address = convert_ip(etherbone_ip_address)
            # Ethernet MAC
            self.submodules.ethmac = LiteEthMAC(phy=self.ethphy,
                                                dw=8,
                                                interface="hybrid",
                                                endianness=self.cpu.endianness,
                                                hw_mac=etherbone_mac_address)

            # SoftCPU
            self.add_memory_region("ethmac",
                                   self.mem_map.get("ethmac", None),
                                   0x2000,
                                   type="io")
            self.add_wb_slave(self.mem_regions["ethmac"].origin,
                              self.ethmac.bus, 0x2000)
            if self.irq.enabled:
                self.irq.add("ethmac", use_loc_if_exists=True)
            # HW ethernet
            self.submodules.arp = LiteEthARP(self.ethmac,
                                             etherbone_mac_address,
                                             etherbone_ip_address,
                                             sys_clk_freq,
                                             dw=8)
            self.submodules.ip = LiteEthIP(self.ethmac,
                                           etherbone_mac_address,
                                           etherbone_ip_address,
                                           self.arp.table,
                                           dw=8)
            self.submodules.icmp = LiteEthICMP(self.ip,
                                               etherbone_ip_address,
                                               dw=8)
            self.submodules.udp = LiteEthUDP(self.ip,
                                             etherbone_ip_address,
                                             dw=8)
            # Etherbone
            self.submodules.etherbone = LiteEthEtherbone(self.udp,
                                                         1234,
                                                         mode="master")
            self.bus.add_master(master=self.etherbone.wishbone.bus)

        # Ethernet ---------------------------------------------------------------------------------
        elif with_ethernet:
            # Ethernet MAC
            self.submodules.ethmac = ethmac = LiteEthMAC(
                phy=self.ethphy,
                dw=64 if ethernet_phy_model == "xgmii" else 32,
                interface="wishbone",
                endianness=self.cpu.endianness)
            ethmac_region_size = (
                ethmac.rx_slots.read() +
                ethmac.tx_slots.read()) * ethmac.slot_size.read()
            self.add_memory_region("ethmac",
                                   self.mem_map.get("ethmac", None),
                                   ethmac_region_size,
                                   type="io")
            self.add_wb_slave(self.mem_regions["ethmac"].origin, ethmac.bus,
                              ethmac_region_size)
            if self.irq.enabled:
                self.irq.add("ethmac", use_loc_if_exists=True)

        # Etherbone --------------------------------------------------------------------------------
        elif with_etherbone:
            self.add_etherbone(phy=self.ethphy,
                               ip_address=etherbone_ip_address,
                               mac_address=etherbone_mac_address)

        # I2C --------------------------------------------------------------------------------------
        if with_i2c:
            pads = platform.request("i2c", 0)
            self.submodules.i2c = I2CMasterSim(pads)

        # SDCard -----------------------------------------------------------------------------------
        if with_sdcard:
            self.add_sdcard("sdcard", use_emulator=True)

        # SPI Flash --------------------------------------------------------------------------------
        if with_spi_flash:
            from litespi.phy.model import LiteSPIPHYModel
            from litespi.modules import S25FL128L
            from litespi.opcodes import SpiNorFlashOpCodes as Codes
            spiflash_module = S25FL128L(Codes.READ_1_1_4)
            if spi_flash_init is None:
                platform.add_sources(
                    os.path.abspath(os.path.dirname(__file__)),
                    "../build/sim/verilog/iddr_verilog.v")
                platform.add_sources(
                    os.path.abspath(os.path.dirname(__file__)),
                    "../build/sim/verilog/oddr_verilog.v")
            self.submodules.spiflash_phy = LiteSPIPHYModel(spiflash_module,
                                                           init=spi_flash_init)
            self.add_spi_flash(phy=self.spiflash_phy,
                               mode="4x",
                               module=spiflash_module,
                               with_master=True)

        # GPIO --------------------------------------------------------------------------------------
        if with_gpio:
            self.submodules.gpio = GPIOTristate(platform.request("gpio"),
                                                with_irq=True)
            self.irq.add("gpio", use_loc_if_exists=True)

        # Simulation debugging ----------------------------------------------------------------------
        if sim_debug:
            platform.add_debug(self, reset=1 if trace_reset_on else 0)
        else:
            self.comb += platform.trace.eq(1)

        # Analyzer ---------------------------------------------------------------------------------
        if with_analyzer:
            analyzer_signals = [
                # IBus (could also just added as self.cpu.ibus)
                self.cpu.ibus.stb,
                self.cpu.ibus.cyc,
                self.cpu.ibus.adr,
                self.cpu.ibus.we,
                self.cpu.ibus.ack,
                self.cpu.ibus.sel,
                self.cpu.ibus.dat_w,
                self.cpu.ibus.dat_r,
                # DBus (could also just added as self.cpu.dbus)
                self.cpu.dbus.stb,
                self.cpu.dbus.cyc,
                self.cpu.dbus.adr,
                self.cpu.dbus.we,
                self.cpu.dbus.ack,
                self.cpu.dbus.sel,
                self.cpu.dbus.dat_w,
                self.cpu.dbus.dat_r,
            ]
            self.submodules.analyzer = LiteScopeAnalyzer(
                analyzer_signals,
                depth=512,
                clock_domain="sys",
                csr_csv="analyzer.csv")
Beispiel #3
0
    def __init__(self, revision="1.0", device="85F", sdram_device="MT41K64M16", sys_clk_freq=int(60e6), 
        toolchain="trellis", with_ethernet=False, with_etherbone=False, eth_ip="192.168.1.50", 
        eth_dynamic_ip   = False,
        with_spi_flash   = False,
        with_led_chaser  = True,
        with_syzygy_gpio = True,
        **kwargs)       :
        platform = butterstick.Platform(revision=revision, device=device ,toolchain=toolchain)

        # SoCCore ----------------------------------------------------------------------------------
        if kwargs["uart_name"] == "serial":
            kwargs["uart_name"] = "crossover"
        SoCCore.__init__(self, platform, sys_clk_freq,
            ident = "LiteX SoC on ButterStick",
            **kwargs)

        # CRG --------------------------------------------------------------------------------------
        self.submodules.crg = _CRG(platform, sys_clk_freq)

        # 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(sdram_device)

            self.submodules.ddrphy = ECP5DDRPHY(
                platform.request("ddram"),
                sys_clk_freq=sys_clk_freq)
            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"),
                l2_cache_size = kwargs.get("l2_size", 8192)
            )

        # Ethernet / Etherbone ---------------------------------------------------------------------
        if with_ethernet or with_etherbone:
            self.submodules.ethphy = LiteEthPHYRGMII(
                clock_pads = self.platform.request("eth_clocks"),
                pads       = self.platform.request("eth"))
            if with_ethernet:
                self.add_ethernet(phy=self.ethphy, dynamic_ip=eth_dynamic_ip)
            if with_etherbone:
                self.add_etherbone(phy=self.ethphy, ip_address=eth_ip)

        # SPI Flash --------------------------------------------------------------------------------
        if with_spi_flash:
            from litespi.modules import W25Q128JV
            from litespi.opcodes import SpiNorFlashOpCodes as Codes
            self.add_spi_flash(mode="4x", module=W25Q128JV(Codes.READ_1_1_4), with_master=False)

        # Leds -------------------------------------------------------------------------------------
        if with_led_chaser:
            self.comb += platform.request("user_led_color").eq(0b010) # Blue.
            self.submodules.leds = LedChaser(
                pads         = platform.request_all("user_led"),
                sys_clk_freq = sys_clk_freq)

        # GPIOs ------------------------------------------------------------------------------------
        if with_syzygy_gpio:
            platform.add_extension(butterstick.raw_syzygy_io("SYZYGY0"))
            self.submodules.gpio = GPIOTristate(platform.request("SYZYGY0"))
Beispiel #4
0
    def __init__(self,
                 sys_clk_freq=int(75e6),
                 toolchain="trellis",
                 with_ethernet=False,
                 with_video_terminal=False,
                 with_video_framebuffer=False,
                 with_led_chaser=True,
                 with_pmod_gpio=False,
                 **kwargs):
        platform = trellisboard.Platform(toolchain=toolchain)

        # SoCCore ----------------------------------------------------------------------------------
        SoCCore.__init__(self,
                         platform,
                         sys_clk_freq,
                         ident="LiteX SoC on Trellis Board",
                         **kwargs)

        # CRG --------------------------------------------------------------------------------------
        crg_cls = _CRGSDRAM if not self.integrated_main_ram_size else _CRG
        self.submodules.crg = crg_cls(platform, sys_clk_freq)

        # DDR3 SDRAM -------------------------------------------------------------------------------
        if not self.integrated_main_ram_size:
            self.submodules.ddrphy = ECP5DDRPHY(platform.request("ddram"),
                                                sys_clk_freq=sys_clk_freq)
            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=MT41J256M16(sys_clk_freq, "1:2"),
                l2_cache_size=kwargs.get("l2_size", 8192),
            )

        # Ethernet ---------------------------------------------------------------------------------
        if with_ethernet:
            self.submodules.ethphy = LiteEthPHYRGMII(
                clock_pads=self.platform.request("eth_clocks"),
                pads=self.platform.request("eth"))
            self.add_ethernet(phy=self.ethphy)

        # HDMI -------------------------------------------------------------------------------------
        if with_video_terminal or with_video_framebuffer:
            # PHY + TP410 I2C initialization.
            hdmi_pads = platform.request("hdmi")
            self.submodules.videophy = VideoDVIPHY(hdmi_pads,
                                                   clock_domain="init")
            self.submodules.videoi2c = I2CMaster(hdmi_pads)
            self.videoi2c.add_init(
                addr=0x38,
                init=[(0x08, 0x35
                       )  # CTL_1_MODE: Normal operation, 24-bit, HSYNC/VSYNC.
                      ])

            # Video Terminal/Framebuffer.
            if with_video_terminal:
                self.add_video_terminal(phy=self.videophy,
                                        timings="640x480@75Hz",
                                        clock_domain="init")
            if with_video_framebuffer:
                self.add_video_framebuffer(phy=self.videophy,
                                           timings="640x480@75Hz",
                                           clock_domain="init")

        # Leds -------------------------------------------------------------------------------------
        if with_led_chaser:
            self.submodules.leds = LedChaser(
                pads=platform.request_all("user_led"),
                sys_clk_freq=sys_clk_freq)

        # GPIOs ------------------------------------------------------------------------------------
        if with_pmod_gpio:
            platform.add_extension(trellisboard.raw_pmod_io("pmoda"))
            self.submodules.gpio = GPIOTristate(platform.request("pmoda"))
Beispiel #5
0
    def __init__(self,
                 sys_clk_freq=int(768e4),
                 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)

        # UART
        if kwargs["with_uart"]:
            platform.add_extension([(
                "serial",
                0,
                Subsignal("tx", Pins(1)),
                Subsignal("rx", Pins(1)),
            )])

        # CRG --------------------------------------------------------------------------------------
        self.submodules.crg = CRG(platform.request("sys_clk"),
                                  rst=platform.request("sys_rst"))

        # SoCMini ----------------------------------------------------------------------------------
        SoCMini.__init__(self, platform, clk_freq=sys_clk_freq, **kwargs)

        # SPI Master
        if with_spi_master:
            platform.add_extension([(
                "spi_master",
                0,
                Subsignal("clk", Pins(1)),
                Subsignal("cs_n", Pins(1)),
                Subsignal("mosi", Pins(1)),
                Subsignal("miso", Pins(1)),
            )])
            self.submodules.spi_master = SPIMaster(
                pads=platform.request("spi_master"),
                data_width=spi_master_data_width,
                sys_clk_freq=sys_clk_freq,
                spi_clk_freq=spi_master_clk_freq,
            )
            self.add_csr("spi_master")

        # PWM
        if with_pwm:
            platform.add_extension([("pwm0", 0, Pins(1))])
            self.submodules.pwm0 = PWM(platform.request("pwm0"))
            self.add_csr("pwm0")

            platform.add_extension([("pwm1", 0, Pins(1))])
            self.submodules.pwm1 = PWM(platform.request("pwm1"))
            self.add_csr("pwm1")

            platform.add_extension([("pwm2", 0, Pins(1))])
            self.submodules.pwm2 = PWM(platform.request("pwm2"))
            self.add_csr("pwm2")

        # GPIO
        if with_gpio:
            platform.add_extension([("gpio", 0, Pins(gpio_width))])
            self.submodules.gpio = GPIOTristate(platform.request("gpio"))
            self.add_csr("gpio")

        # 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")

        # AXI-Lite Master
        if kwargs["bus"] == "axi":
            axi_bus = axi.AXILiteInterface(data_width=32, address_width=32)
            wb_bus = wishbone.Interface()
            axi2wb = axi.AXILite2Wishbone(axi_bus, wb_bus)
            self.submodules += axi2wb
            self.bus.add_master(master=wb_bus)
            platform.add_extension(axi_bus.get_ios("axi"))
            axi_pads = platform.request("axi")
            self.comb += axi_bus.connect_to_pads(axi_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)
Beispiel #6
0
    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)

        # Serial -----------------------------------------------------------------------------------
        #platform.add_extension(orangecrab.feather_serial)

        # USB hardware Abstract Control Model.
        kwargs['uart_name'] = "usb_acm"

        # SoCCore ----------------------------------------------------------------------------------
        SoCCore.__init__(self,
                         platform,
                         clk_freq=sys_clk_freq,
                         csr_data_width=32,
                         **kwargs)

        # CRG --------------------------------------------------------------------------------------
        self.submodules.crg = crg = CRG(platform,
                                        sys_clk_freq,
                                        with_usb_pll=True)

        # DDR3 SDRAM -------------------------------------------------------------------------------
        if 1:
            if not self.integrated_main_ram_size:
                available_sdram_modules = {
                    'MT41K64M16': MT41K64M16,
                    'MT41K128M16': MT41K128M16,
                    'MT41K256M16': MT41K256M16
                }
                sdram_module = available_sdram_modules.get(
                    kwargs.get("sdram_device", "MT41K64M16"))

                ddr_pads = platform.request("ddram")
                self.submodules.ddrphy = ECP5DDRPHY(ddr_pads,
                                                    sys_clk_freq=sys_clk_freq)
                self.add_csr("ddrphy")
                self.add_constant("ECP5DDRPHY")
                self.comb += crg.stop.eq(self.ddrphy.init.stop)
                self.comb += 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)

                # Virtual power pins - suggested to reduce SSO noise
                self.comb += ddr_pads.vccio.eq(0b111111)
                self.comb += ddr_pads.gnd.eq(0)

        # Add extra pin definitions
        platform.add_extension(extras)

        # RGB LED
        led = platform.request("rgb_led", 0)
        self.submodules.gpio_led = GPIOTristate(Cat(led.r, led.g, led.b))

        # i2c
        self.submodules.i2c = I2CMaster(platform.request("i2c"))

        # SDR processor
        self.submodules.sdr = sdr(platform.request("ad9203"),
                                  platform.request("pdm_out"))
        platform.add_source_dir('vsrc')

        # Controllable Self Reset
        reset_code = Signal(32, reset=0)
        self.submodules.self_reset = GPIOOut(reset_code)
        self.comb += platform.request("rst_n").eq(reset_code != 0xAA550001)

        self.submodules.button = GPIOIn(platform.request("usr_btn"))

        # 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)

        # Add GIT repo to the firmware
        git_rev_cmd = subprocess.Popen(["git", "rev-parse", "--short", "HEAD"],
                                       stdout=subprocess.PIPE,
                                       stderr=subprocess.PIPE)
        (git_stdout, _) = git_rev_cmd.communicate()
        self.add_constant('REPO_GIT_SHA1',
                          git_stdout.decode('ascii').strip('\n'))
Beispiel #7
0
    def __init__(self,
                 sys_clk_freq=int(100e6),
                 with_pwm=False,
                 with_mmcm=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)

        # UART
        if kwargs["with_uart"]:
            platform.add_extension([(
                "serial",
                0,
                Subsignal("tx", Pins(1)),
                Subsignal("rx", Pins(1)),
            )])

        # CRG --------------------------------------------------------------------------------------
        self.submodules.crg = CRG(platform.request("sys_clk"),
                                  rst=platform.request("sys_rst"))

        # SoCMini ----------------------------------------------------------------------------------
        print(kwargs)
        SoCMini.__init__(self, platform, clk_freq=sys_clk_freq, **kwargs)

        # MMCM
        if with_mmcm:
            platform.add_extension([(
                "clkgen",
                0,
                Subsignal("ref", Pins(1)),
                Subsignal("out0", Pins(1)),
                Subsignal("out1", Pins(1)),
                Subsignal("locked", Pins(1)),
            )])

            self.clock_domains.cd_out0 = ClockDomain(reset_less=True)
            self.clock_domains.cd_out1 = ClockDomain(reset_less=True)
            self.submodules.mmcm = mmcm = S7MMCM()
            mmcm.expose_drp()
            self.add_csr("mmcm")

            clkgen = platform.request("clkgen")

            mmcm.register_clkin(clkgen.ref, 100e6)
            mmcm.create_clkout(self.cd_out0, 148.5e6, with_reset=False)
            mmcm.create_clkout(self.cd_out1, 742.5e6, with_reset=False)

            self.comb += [
                clkgen.out0.eq(self.cd_out0.clk),
                clkgen.out1.eq(self.cd_out1.clk),
                clkgen.locked.eq(mmcm.locked),
            ]

        # SPI Master
        if with_spi_master:
            platform.add_extension([(
                "spi_master",
                0,
                Subsignal("clk", Pins(1)),
                Subsignal("cs_n", Pins(1)),
                Subsignal("mosi", Pins(1)),
                Subsignal("miso", Pins(1)),
            )])
            self.submodules.spi_master = SPIMaster(
                pads=platform.request("spi_master"),
                data_width=spi_master_data_width,
                sys_clk_freq=sys_clk_freq,
                spi_clk_freq=spi_master_clk_freq,
            )
            self.add_csr("spi_master")

        # PWM
        if with_pwm:
            platform.add_extension([("pwm", 0, Pins(1))])
            self.submodules.pwm = PWM(platform.request("pwm"))
            self.add_csr("pwm")

        # GPIO
        if with_gpio:
            platform.add_extension([("gpio", 0, Pins(gpio_width))])
            self.submodules.gpio = GPIOTristate(platform.request("gpio"))
            self.add_csr("gpio")

        # 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")

        # AXI-Lite Master
        if kwargs["bus"] == "axi":
            axi_bus = axi.AXILiteInterface(data_width=32, address_width=32)
            wb_bus = wishbone.Interface()
            axi2wb = axi.AXILite2Wishbone(axi_bus, wb_bus)
            self.submodules += axi2wb
            self.bus.add_master(master=wb_bus)
            platform.add_extension(axi_bus.get_ios("axi"))
            axi_pads = platform.request("axi")
            self.comb += axi_bus.connect_to_pads(axi_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)