示例#1
0
    def __init__(self,
                 sys_clk_freq=int(50e6),
                 with_etherbone=True,
                 ip_address=None,
                 mac_address=None):
        platform = colorlight_5a_75b.Platform(revision="7.0")

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

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

        # Etherbone --------------------------------------------------------------------------------
        if with_etherbone:
            self.submodules.ethphy = LiteEthPHYRGMII(
                clock_pads=self.platform.request("eth_clocks"),
                pads=self.platform.request("eth"),
                tx_delay=0e-9)
            self.add_etherbone(
                phy=self.ethphy,
                ip_address=ip_address,
                mac_address=mac_address,
                data_width=32,
            )

        # SPIFlash ---------------------------------------------------------------------------------
        self.submodules.spiflash = ECP5SPIFlash(
            pads=platform.request("spiflash"),
            sys_clk_freq=sys_clk_freq,
            spi_clk_freq=5e6,
        )

        # Led --------------------------------------------------------------------------------------
        self.submodules.leds = LedChaser(
            pads=platform.request_all("user_led_n"), sys_clk_freq=sys_clk_freq)

        # GPIOs ------------------------------------------------------------------------------------
        platform.add_extension(_gpios)

        # Power switch
        power_sw_pads = platform.request("gpio", 0)
        power_sw_gpio = Signal()
        power_sw_timer = WaitTimer(
            2 * sys_clk_freq)  # Set Power switch high after power up for 2s.
        self.comb += power_sw_timer.wait.eq(1)
        self.submodules += power_sw_timer
        self.submodules.gpio0 = GPIOOut(power_sw_gpio)
        self.comb += power_sw_pads.eq(power_sw_gpio | ~power_sw_timer.done)

        # Reset Switch
        reset_sw_pads = platform.request("gpio", 1)
        self.submodules.gpio1 = GPIOOut(reset_sw_pads)
示例#2
0
    def __init__(self, sys_clk_freq, pins):
        self.submodules.dc = GPIOOut(pins.dc)
        self.submodules.backligth = GPIOOut(pins.bl_led)
        self.submodules.reset = GPIOOut(pins.reset)

        pins.miso = Signal()

        self.submodules.spi = SPIMaster(
            pads=pins,
            data_width=8,
            sys_clk_freq=sys_clk_freq,
            spi_clk_freq=4e6,
        )
示例#3
0
文件: tofe.py 项目: xobs/lxsocsupport
    def __init__(self, platform, shared_uart):
        TOFE.__init__(self, platform)

        # UARTs
        shared_uart.add_uart_pads(platform.request('tofe_lsio_serial'))
        shared_uart.add_uart_pads(platform.request('tofe_lsio_pmod_serial'))

        # LEDs
        lsio_leds = Signal(4)
        self.submodules.lsio_leds = GPIOOut(lsio_leds)
        self.comb += [
            platform.request('tofe_lsio_user_led', 0).eq(lsio_leds[0]),
            platform.request('tofe_lsio_user_led', 1).eq(lsio_leds[1]),
            platform.request('tofe_lsio_user_led', 2).eq(lsio_leds[2]),
            platform.request('tofe_lsio_user_led', 3).eq(lsio_leds[3]),
        ]
        # Switches
        lsio_sws = Signal(4)
        self.submodules.lsio_sws = GPIOIn(lsio_sws)
        self.comb += [
            lsio_sws[0].eq(~platform.request('tofe_lsio_user_sw', 0)),
            lsio_sws[1].eq(~platform.request('tofe_lsio_user_sw', 1)),
            lsio_sws[2].eq(~platform.request('tofe_lsio_user_sw', 2)),
            lsio_sws[3].eq(~platform.request('tofe_lsio_user_sw', 3)),
        ]
    def __init__(self, sys_clk_freq, output_dir, *args, **kwargs):
        self._logger = logging.getLogger("ZephyrSoC")

        super().__init__(
            cpu_type="vexriscv",
            cpu_variant="full",
            csr_data_width=8,
            integrated_rom_size=0x8000,
            *args,
            **kwargs,
        )  # TODO: Test if we actually need "full" for ecall

        self.submodules.gpio_leds = GPIOOut(self.platform.request("gpio_leds"))
        self.add_csr("gpio_leds")

        self.submodules.switches = GPIOIn(self.platform.request_all("sw"))
        self.add_csr("switches")

        self.platform.add_extension(pmod1_uart_ios)
        self.add_uartbone(name="pmod1_uart")

        analyzer_signals = [self.cpu.ibus, self.cpu.dbus]
        self.submodules.analyzer = LiteScopeAnalyzer(
            analyzer_signals,
            depth=512,
            clock_domain="sys",
            csr_csv=os.path.join(output_dir, "analyzer.csv"),
        )
示例#5
0
    def add_oled(self):
        pads = self.platform.request("oled_spi")
        pads.miso = Signal()
        self.submodules.oled_spi = SPIMaster(pads, 8, self.sys_clk_freq, 8e6)
        self.oled_spi.add_clk_divider()

        self.submodules.oled_ctl = GPIOOut(self.platform.request("oled_ctl"))
示例#6
0
    def __init__(self, platform):
        clk_freq = int((1 / (platform.default_clk_period)) * 1000000000)
        SoCCore.__init__(self,
                         platform,
                         clk_freq,
                         cpu_type=None,
                         csr_data_width=32,
                         with_uart=False,
                         ident="LiteUSB example design",
                         with_timer=False)
        self.submodules.crg = CRG(platform.request(platform.default_clk_name))

        self.submodules.usb_phy = FT245PHY(platform.request("usb_fifo"),
                                           self.clk_freq)
        self.submodules.usb_core = LiteUSBCore(self.usb_phy,
                                               self.clk_freq,
                                               with_crc=False)

        # Wishbone Bridge
        usb_bridge_port = self.usb_core.crossbar.get_port(
            self.usb_map["bridge"])
        self.add_cpu_or_bridge(
            LiteUSBWishboneBridge(usb_bridge_port, self.clk_freq))
        self.add_wb_master(self.cpu_or_bridge.wishbone)

        # Leds
        leds = Cat(iter([platform.request("user_led", i) for i in range(8)]))
        self.submodules.leds = GPIOOut(leds)
示例#7
0
 def __init__(self, pads):
     spi_pads = Record([("cs_n", 1), ("clk", 1), ("mosi", 1)])
     self.submodules.spi = SPIMaster(spi_pads, 8, div=16, cpha=0)
     self.comb += [
         pads.sclk.eq(spi_pads.clk),
         pads.sdin.eq(spi_pads.mosi)
     ]
     self.submodules.gpio = GPIOOut(Cat(pads.res, pads.dc, pads.vbat, pads.vdd))
示例#8
0
        def add_gpio(self):
            def platform_request_all(name):
                from litex.build.generic_platform import ConstraintError
                r = []
                while True:
                    try:
                        r += [self.platform.request(name, len(r))]
                    except ConstraintError:
                        break
                return r

            self.submodules.leds = GPIOOut(
                Cat(platform_request_all("user_led")))
            self.add_csr("leds")

            self.submodules.switches = GPIOOut(
                Cat(platform_request_all("user_sw")))
            self.add_csr("switches")
示例#9
0
    def __init__(self, with_etherbone=True, ip_address=None, mac_address=None):
        platform = colorlight_5a_75b.Platform(revision="7.0")
        sys_clk_freq = int(125e6)

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

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

        # Etherbone --------------------------------------------------------------------------------
        if with_etherbone:
            self.submodules.ethphy = LiteEthPHYRGMII(
                clock_pads=self.platform.request("eth_clocks"),
                pads=self.platform.request("eth"))
            self.add_csr("ethphy")
            self.add_etherbone(
                phy=self.ethphy,
                ip_address=ip_address,
                mac_address=mac_address,
            )

        # SPIFlash ---------------------------------------------------------------------------------
        self.submodules.spiflash = ECP5SPIFlash(
            pads=platform.request("spiflash"),
            sys_clk_freq=sys_clk_freq,
            spi_clk_freq=5e6,
        )
        self.add_csr("spiflash")

        # Led --------------------------------------------------------------------------------------
        self.submodules.led = GPIOOut(platform.request("user_led_n"))
        self.add_csr("led")

        # GPIOs ------------------------------------------------------------------------------------
        platform.add_extension(_gpios)
        self.submodules.gpio0 = GPIOOut(platform.request("gpio", 0))
        self.submodules.gpio1 = GPIOOut(platform.request("gpio", 1))
        self.add_csr("gpio0")
        self.add_csr("gpio1")
示例#10
0
    def __init__(self, platform, **kwargs):

        # We need at least a serial port peripheral
        platform.add_extension(tinyfpga_bx.serial)

        sys_clk_freq = int(1e9 / platform.default_clk_period)
        SoCCore.__init__(self,
                         platform,
                         clk_freq=sys_clk_freq,
                         integrated_rom_size=0,
                         integrated_main_ram_size=0,
                         integrated_sram_size=10 * 1024,
                         cpu_reset_address=0x20050000,
                         **kwargs)

        # Configure the clock and reset generator
        self.submodules.crg = CRG(platform.request(platform.default_clk_name))

        # Configure the TinyFPGA BX SPI flash
        self.submodules.spiflash = spi_flash.SpiFlash(
            platform.request("spiflash"), dummy=8, div=2, endianness="little")
        self.config["SPIFLASH_PAGE_SIZE"] = 256
        self.config["SPIFLASH_SECTOR_SIZE"] = 0x10000

        # Map the entire SPI flash
        spiflash_total_size = int((8 / 8) * 1024 * 1024)
        self.register_mem("spiflash",
                          self.mem_map["spiflash"],
                          self.spiflash.bus,
                          size=spiflash_total_size)

        # Configure a special region for the ROM (bootloader/bios)
        self.flash_boot_address = 0x20050000 + 0x8000
        self.add_memory_region("rom", self.cpu_reset_address, 0x8000)

        # Configure a special region for our user code (firmware)
        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
            spiflash_total_size -
            (self.flash_boot_address - self.mem_map["spiflash"]) - 0x100)

        # Configure the board LED
        leds = platform.request("user_led", 0)
        self.submodules.leds = GPIOOut(leds)

        # Need to specify '-s' flash isn't put into deep-sleep power down after bitstream loads
        platform.toolchain.nextpnr_build_template[
            2] = "icepack -s {build_name}.txt {build_name}.bin"
示例#11
0
文件: tofe.py 项目: xobs/lxsocsupport
    def __init__(self, platform):
        # TOFE board
        tofe_pads = platform.request('tofe')
        self.submodules.i2c = i2c.I2C(tofe_pads)

        # Use a proper Tristate for the reset signal so the "pull up" works.
        tofe_reset = TSTriple(1)
        self.comb += [
            tofe_reset.o.eq(0),
        ]
        self.specials += [
            tofe_reset.get_tristate(tofe_pads.rst),
        ]
        self.submodules.rst = GPIOOut(tofe_reset.oe)
示例#12
0
    def __init__(self, platform):
        self.submodules.mux = i2c.I2CMux(platform.request("opsis_i2c"))
        self.submodules.master = i2c.I2C(self.mux.get_i2c_pads())

        # Use a proper Tristate for the FX2 reset so the "pull up" works.
        fx2_reset = TSTriple(1)
        self.comb += [
            fx2_reset.o.eq(0),
        ]
        self.specials += [
            fx2_reset.get_tristate(platform.request("fx2_reset")),
        ]
        self.submodules.fx2_reset = GPIOOut(fx2_reset.oe)

        self.submodules.fx2_hack = I2CShiftReg(self.mux.get_i2c_pads())
示例#13
0
    def __init__(self,
                 sys_clk_freq=int(125e6),
                 with_pcie=False,
                 with_led_chaser=True,
                 **kwargs):
        platform = fairwaves_xtrx.Platform()

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

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

        # PCIe -------------------------------------------------------------------------------------
        if with_pcie:
            self.submodules.pcie_phy = S7PCIEPHY(platform,
                                                 platform.request("pcie_x1"),
                                                 data_width=64,
                                                 bar0_size=0x20000)
            self.add_pcie(phy=self.pcie_phy, ndmas=1)

            # ICAP (For FPGA reload over PCIe).
            from litex.soc.cores.icap import ICAP
            self.submodules.icap = ICAP()
            self.icap.add_reload()
            self.icap.add_timing_constraints(platform, sys_clk_freq,
                                             self.crg.cd_sys.clk)

            # Flash (For SPIFlash update over PCIe). FIXME: Should probably be updated to use SpiFlashSingle/SpiFlashDualQuad (so MMAPed and do the update with bit-banging)
            from litex.soc.cores.gpio import GPIOOut
            from litex.soc.cores.spi_flash import S7SPIFlash
            self.submodules.flash_cs_n = GPIOOut(
                platform.request("flash_cs_n"))
            self.submodules.flash = S7SPIFlash(platform.request("flash"),
                                               sys_clk_freq, 25e6)

        # Leds -------------------------------------------------------------------------------------
        if with_led_chaser:
            self.submodules.leds = LedChaser(
                pads=platform.request_all("user_led"),
                sys_clk_freq=sys_clk_freq)
示例#14
0
    def __init__(self, platform, **kwargs):
        sys_clk_freq = platform.clkFreq

        # SoCMini (No CPU, we are controlling the SoC over UART)
        SoCMini.__init__(self,
                         platform,
                         sys_clk_freq,
                         csr_data_width=32,
                         ident="My first LiteX System On Chip",
                         ident_version=True)

        # Clock Reset Generation
        self.submodules.crg = CRG(platform.request("clk29"))

        # No CPU, use Serial to control Wishbone bus
        self.submodules.serial_bridge = UARTWishboneBridge(
            platform.request("uart"), sys_clk_freq)
        self.add_wb_master(self.serial_bridge.wishbone)

        # FPGA identification
        self.submodules.dna = dna.DNA()
        self.add_csr("dna")

        # Led
        self.submodules.led = GPIOOut(
            Cat([
                platform.request("green_led"),
                platform.request("orange_led")
            ]))
        self.add_csr("led")

        # Display 7 Segments
        self.submodules.display7Seg = SevenSegmentDisplay(
            sys_clk_freq, platform.request("seven_seg"))
        self.add_csr("display7Seg")

        # Encoder
        self.submodules.encoder = RotaryEncoder(sys_clk_freq,
                                                platform.request("encoder"))
        self.add_csr("encoder")
示例#15
0
    def __init__(self, platform, clk_freq):
        switches = Signal(1)
        leds = Signal(2)

        self.reset = Signal()

        # # #

        self.submodules.switches = GPIOIn(switches)
        self.submodules.leds = GPIOOut(leds)
        self.comb += [
           switches[0].eq(~platform.request("pwrsw")),
           platform.request("hdled").eq(~leds[0]),
           platform.request("pwled").eq(~leds[1]),
        ]

        # generate a reset when power switch is pressed for 1 second
        self.submodules.reset_timer = WaitTimer(clk_freq)
        self.comb += [
            self.reset_timer.wait.eq(switches[0]),
            self.reset.eq(self.reset_timer.done)
        ]
示例#16
0
    def __init__(self, sys_clk_freq=int(200e6), disable_sdram=False, **kwargs):
        platform = ted_tfoil.Platform()

        SoCCore.__init__(self,
                         platform,
                         sys_clk_freq,
                         ident="LiteX SoC on tfoil",
                         ident_version=True,
                         **kwargs)

        self.submodules.crg = _CRG(platform, sys_clk_freq)

        if not disable_sdram:
            if not self.integrated_main_ram_size:
                self.submodules.ddrphy = usddrphy.USPDDRPHY(
                    platform.request("ddram"),
                    memtype="DDR4",
                    sys_clk_freq=sys_clk_freq,
                    iodelay_clk_freq=400e6)
                self.add_sdram("sdram",
                               phy=self.ddrphy,
                               module=MT40A1G8(sys_clk_freq, "1:4"),
                               size=0x40000000,
                               l2_cache_size=kwargs.get("l2_size", 8192))

        self.submodules.leds = LedChaser(pads=platform.request_all("user_led"),
                                         sys_clk_freq=sys_clk_freq)

        i2c_master_pads = [
            platform.request("i2c_tca9555", 0),
            platform.request("i2c_tca9555", 1),
            platform.request("i2c_tca9555", 2),
            platform.request("i2c_tca9555", 3),
            platform.request("i2c_tca9555", 4),
            platform.request("i2c_tca9555", 5),
            platform.request("i2c_tca9555", 6),
            platform.request("i2c_tca9548", 0),
            platform.request("i2c_tca9548", 1),
            platform.request("i2c_tca9548", 2),
            platform.request("i2c_tca9548", 3),
            platform.request("i2c_si5341", 0),
            platform.request("i2c_si5341", 1),
        ]

        self.submodules.i2c = I2CMasterMP(platform, i2c_master_pads)

        self.submodules.sb_tca9548 = GPIOOut(
            pads=platform.request_all("tca9548_reset_n"))

        sb_si5341_o_pads = Cat([
            platform.request("si5341_in_sel_0", 0),
            platform.request("si5341_in_sel_0", 1),
            platform.request("si5341_syncb", 0),
            platform.request("si5341_syncb", 1),
            platform.request("si5341_rstb", 0),
            platform.request("si5341_rstb", 1),
        ])
        sb_si5341_i_pads = Cat([
            platform.request("si5341_lolb", 0),
            platform.request("si5341_lolb", 1),
        ])
        self.submodules.sb_si5341_o = GPIOOut(pads=sb_si5341_o_pads)
        self.submodules.sb_si5341_i = GPIOIn(pads=sb_si5341_i_pads)

        self._add_aurora(platform)
示例#17
0
 def add_leds(self):
     self.submodules.leds = GPIOOut(
         Cat(self.platform.request_all("user_led")))
示例#18
0
    def __init__(self, platform, with_analyzer=False, with_loopback=False):
        clk_freq = int(100e6)
        SoCSDRAM.__init__(self, platform, clk_freq,
            cpu_type=None,
            l2_size=32,
            csr_data_width=32, csr_address_width=15, # required for flash spi
            integrated_rom_size=0,
            integrated_sram_size=0x8000,
            with_uart=False,
            ident="USB2Sniffer design",
            with_timer=False
        )
        self.submodules.crg = _CRG(platform)

        # flash spi
        self.submodules.flash = Flash(platform.request("flash"), div=math.ceil(clk_freq/25e6))

        # sdram
        self.submodules.ddrphy = a7ddrphy.A7DDRPHY(platform.request("ddram"))
        sdram_module = MT41K256M16(self.clk_freq, "1:4")
        self.register_sdram(self.ddrphy,
                            sdram_module.geom_settings,
                            sdram_module.timing_settings)

        # sdram fifo
        depth = 32 * 1024 * 1024
        self.submodules.dramfifo = ResetInserter()(LiteDRAMFIFO([("data", 32)], depth, 0,
                                            self.sdram.crossbar, preserve_first_last=False))

        self.submodules.hugefifo = ResetInserter()(stream.SyncFIFO([("data", 32)], 512))

        # debug wishbone
        self.add_cpu(UARTWishboneBridge(platform.request("serial"), clk_freq, baudrate=3e6))
        self.add_wb_master(self.cpu.wishbone)

        # usb phy
        usb_pads = platform.request("usb_fifo")
        self.submodules.usb_phy = FT601Sync(usb_pads, dw=32, timeout=1024)

        if with_loopback:
            self.submodules.usb_loopback_fifo = stream.SyncFIFO(phy_description(32), 2048)
            self.comb += [
                self.usb_phy.source.connect(self.usb_loopback_fifo.sink),
                self.usb_loopback_fifo.source.connect(self.usb_phy.sink)
            ]
        else:
            # usb core
            self.submodules.usb_core = USBCore(self.usb_phy, clk_freq)

            # usb <--> wishbone
            self.submodules.etherbone = Etherbone(self.usb_core, self.usb_map["wishbone"])
            self.add_wb_master(self.etherbone.master.bus)

            # ulpi switch
            ulpi_sw = platform.request("ulpi_sw")
            self.submodules.ulpi_sw_oe_n = GPIOOut(ulpi_sw.oe_n)
            self.submodules.ulpi_sw_s = GPIOOut(ulpi_sw.s)

            # ulpi 0
            self.submodules.ulpi_phy0 = ULPIPHY(platform.request("ulpi", 0), cd="ulpi0")
            self.submodules.ulpi_core0 = ULPICore(self.ulpi_phy0)

            # packer0
            self.submodules.overflow0 = OverflowMeter(ulpi_cmd_description(8, 1))
            self.submodules.iticore0 = ITICore()
            self.submodules.fifo0 = ResetInserter()(stream.SyncFIFO([("data", 40), ("len", 2)], 16))
            self.submodules.conv40320 = Conv4032()

            # ulpi 1
            self.submodules.ulpi_phy1 = ULPIPHY(platform.request("ulpi", 1), cd="ulpi1")
            self.submodules.ulpi_core1 = ULPICore(self.ulpi_phy1)

            # usb <--> ulpi0
            self.submodules.wrapcore0 = WrapCore(self.usb_core, self.usb_map["ulpi0"])
            self.comb += [
                self.ulpi_core0.source.connect(self.overflow0.sink),
                self.overflow0.source.connect(self.iticore0.sink),
                self.iticore0.source.connect(self.fifo0.sink),
                self.fifo0.source.connect(self.conv40320.sink),
                self.conv40320.source.connect(self.hugefifo.sink),
                self.hugefifo.source.connect(self.dramfifo.sink),
                self.dramfifo.source.connect(self.wrapcore0.sink),
            ]

            # reset manager
            self.rst_manager = ResetManager([self.iticore0, self.fifo0,
                                             self.conv40320, self.hugefifo,
                                             self.dramfifo, self.wrapcore0])

            # leds
            led0 = platform.request("rgb_led", 0)
            self.submodules.blinker0 = BlinkerRGB(led0,
                    self.etherbone.packet.tx.source.valid,
                    0, self.etherbone.packet.rx.sink.valid)

            led1 = platform.request("rgb_led", 1)
            self.submodules.blinker1 = BlinkerRGB(led1,
                    self.ulpi_core0.source.valid,
                    0, self.wrapcore0.sender.source.valid)

        # timing constraints
        self.crg.cd_sys.clk.attr.add("keep")
        self.crg.cd_usb.clk.attr.add("keep")
        self.platform.add_period_constraint(self.crg.cd_sys.clk, 10.0)
        self.platform.add_period_constraint(self.crg.cd_usb.clk, 10.0)

        if with_analyzer:
            analyzer_signals = [
                self.ulpi_core0.source.valid,
                self.ulpi_core0.source.ready,
                self.ulpi_core0.source.data,
                self.iticore0.source.valid,
                self.iticore0.source.ready,
                self.iticore0.source.data,
                self.fifo.source.valid,
                self.fifo.source.ready,
                self.fifo.source.data,
                self.wrapcore0.sender.source.valid,
                self.wrapcore0.sender.source.ready,
                self.wrapcore0.sender.source.data,
            ]
            self.submodules.analyzer = LiteScopeAnalyzer(analyzer_signals, 1024, clock_domain="sys")
示例#19
0
 def __init__(self, **kwargs):
     EthernetSoC.__init__(self, **kwargs)
     self.set_bios_ip("192.168.0.55", "192.168.0.45")
     # flash-rom
     self.add_constant("FLASH_BOOT_ADDRESS",
                       self.mem_map["spiflash"] + FLASH_BOOTROM_OFFSET)
     self.submodules.spiflash = SpiFlash(
         self.platform.request("spiflash4x"),
         dummy=6,  # see datasheet for dummy cycles
         div=2,  # multiple of 2
         with_bitbang=True,
         endianness=self.cpu.endianness,
         addr32bit=True)
     self.spiflash.add_clk_primitive(self.platform.device)
     self.add_memory_region("spiflash",
                            self.mem_map["spiflash"],
                            self.flash_size,
                            type="io")
     self.add_wb_slave(self.mem_map["spiflash"],
                       self.spiflash.bus,
                       size=self.flash_size)
     self.add_csr("spiflash")
     if self.full_board:
         if self.fast_sd:
             self.submodules.sdmmc = SDCard(self.platform, "sdmmc")
             self.add_wb_master(self.sdmmc.master_bus)
             self.add_memory_region("sdmmc",
                                    self.mem_map["sdmmc"],
                                    self.sdmmc.get_size(),
                                    type="io")
             self.add_wb_slave(self.mem_map["sdmmc"],
                               self.sdmmc.slave_bus,
                               size=self.sdmmc.get_size())
             self.sdmmc_cmd_irq = self.sdmmc.cmd_irq
             self.sdmmc_dat_irq = self.sdmmc.dat_irq
             self.add_interrupt("sdmmc_cmd_irq")
             self.add_interrupt("sdmmc_dat_irq")
         else:
             # SPI0: sd-card
             self.submodules.spi0 = SPIMaster(self.platform,
                                              name="sdspi",
                                              busmaster=False)
             if hasattr(self.spi0, "master_bus"):
                 self.add_wb_master(self.spi0.master_bus)
             self.add_memory_region("spi0",
                                    self.mem_map["spi0"],
                                    self.spi0.get_size(),
                                    type="io")
             self.add_wb_slave(self.mem_map["spi0"],
                               self.spi0.slave_bus,
                               size=self.spi0.get_size())
             self.add_csr("spi0")
             self.add_interrupt("spi0")
         sd_reset = self.platform.request("sd_reset")
         sd_cd = self.platform.request("sd_cd")
         self.comb += sd_reset.eq(0)
         # SPI1: waveshare35a
         self.submodules.spi1 = SPIMaster(self.platform,
                                          name="ws35a_spi",
                                          cs_width=2,
                                          busmaster=False)
         if hasattr(self.spi1, "master_bus"):
             self.add_wb_master((self.spi1.master_bus))
         self.add_memory_region("spi1",
                                self.mem_map["spi1"],
                                self.spi1.get_size(),
                                type="io")
         self.add_wb_slave(self.mem_map["spi1"],
                           self.spi1.slave_bus,
                           size=self.spi1.get_size())
         self.add_csr("spi1")
         self.add_interrupt("spi1")
         # waveshare35a
         ws35a_rs = self.platform.request("ws35a_rs")
         ws35a_reset = self.platform.request("ws35a_reset")
         ws35a_pendown = self.platform.request("ws35a_int")
         self.submodules.ws35a = TouchscreenInterrupt(ws35a_pendown)
         self.add_interrupt("ws35a")
         # gpio0: leds, ws35a controls
         board_led = Signal()
         self.comb += self.platform.request("board_led").eq(~board_led)
         gpio0_signals = Cat(
             self.platform.request("user_led", 0),
             self.platform.request("user_led", 1),
             self.platform.request("user_led", 2),
             self.platform.request("user_led", 3),
             board_led,
             self.reset,
             ws35a_rs,
             ws35a_reset,
         )
         self.submodules.gpio0 = GPIOOut(gpio0_signals)
         self.add_csr("gpio0")
         # gpio1: touchscreen pendown, sd-card-detect
         gpio1_signals = Cat(ws35a_pendown, sd_cd)
         self.submodules.gpio1 = GPIOIn(gpio1_signals)
         self.add_csr("gpio1")
         # timer1
         self.submodules.timer1 = Timer()
         self.add_csr("timer1")
         self.add_interrupt("timer1")
         # AES
         self.submodules.aes = AES(self.platform)
         self.add_memory_region("aes",
                                self.mem_map["aes"],
                                self.aes.get_size(),
                                type="io")
         self.add_wb_slave(self.mem_map["aes"],
                           self.aes.bus,
                           size=self.aes.get_size())
         # SHA1
         self.submodules.sha1 = SHA1(self.platform)
         self.add_memory_region("sha1",
                                self.mem_map["sha1"],
                                self.sha1.get_size(),
                                type="io")
         self.add_wb_slave(self.mem_map["sha1"],
                           self.sha1.bus,
                           size=self.sha1.get_size())
         # memirq channels
         # channel 0
         self.submodules.to_sel4_master0 = MemIrq()
         self.add_csr("to_sel4_master0")
         self.add_interrupt("to_sel4_master0")
         self.submodules.to_sel4_slave0 = MemIrq()
         self.add_csr("to_sel4_slave0")
         self.add_interrupt("to_sel4_slave0")
         self.submodules.to_linux_master0 = MemIrq()
         self.add_csr("to_linux_master0")
         self.add_interrupt("to_linux_master0")
         self.submodules.to_linux_slave0 = MemIrq()
         self.add_csr("to_linux_slave0")
         self.add_interrupt("to_linux_slave0")
         # channel 1
         self.submodules.to_sel4_master1 = MemIrq()
         self.add_csr("to_sel4_master1")
         self.add_interrupt("to_sel4_master1")
         self.submodules.to_sel4_slave1 = MemIrq()
         self.add_csr("to_sel4_slave1")
         self.add_interrupt("to_sel4_slave1")
         self.submodules.to_linux_master1 = MemIrq()
         self.add_csr("to_linux_master1")
         self.add_interrupt("to_linux_master1")
         self.submodules.to_linux_slave1 = MemIrq()
         self.add_csr("to_linux_slave1")
         self.add_interrupt("to_linux_slave1")
         # dma test
         self.submodules.dmatest = DMATest()
         self.add_wb_master(self.dmatest.master_bus)
         self.add_csr("dmatest")
     self.dts = None
示例#20
0
 def __init__(self, tofe):
     self.layout = tofe.layout
     for name, size in self.layout:
         setattr(self.submodules, name, GPIOOut(getattr(tofe, name)))
示例#21
0
    def __init__(self, platform, clk_freq):

        # Work out how many LEDs this board has
        user_leds = []
        while True:
            try:
                user_leds.append(platform.request("user_led", len(user_leds)))
            except ConstraintError:
                break

        rgb_leds = []
        while True:
            try:
                rgb_leds.append(platform.request("rgb_led", len(rgb_leds)))
            except ConstraintError:
                break
        for rgb in rgb_leds:
            # TODO: Common anode only for now. Support common cathode.
            r_n = Signal()
            g_n = Signal()
            b_n = Signal()

            self.comb += [
                rgb.r.eq(~r_n),
                rgb.g.eq(~g_n),
                rgb.b.eq(~b_n),
            ]

            user_leds.extend([r_n, g_n, b_n])

        if user_leds:
            leds = Signal(len(user_leds))
            self.submodules.leds = GPIOOut(leds)
            for i in range(0, len(user_leds)):
                self.comb += [
                    user_leds[i].eq(leds[i]),
                ]
        self._leds_count = CSRConstant(len(user_leds))

        # Work out how many switches this board has
        user_sws = []
        while True:
            try:
                user_sws.append(platform.request("user_sw", len(user_sws)))
            except ConstraintError:
                break

        if user_sws:
            switches = Signal(len(user_sws))
            self.submodules.switches = GPIOIn(switches)
            for i in range(0, len(user_sws)):
                self.comb += [
                    switches[i].eq(~user_sws[i]),
                ]
        self._switches_count = CSRConstant(len(user_sws))

        # Work out how many push buttons this board has
        user_btns = []
        while True:
            try:
                user_btns.append(platform.request("user_btn", len(user_btns)))
            except ConstraintError:
                break

        if user_btns:
            self.submodules.buttons_ev = EventManager()

            _10ms = int(clk_freq * (10e-3))

            for i in range(0, len(user_btns)):
                btn_ev = EventSourceProcess()
                btn_timer = WaitTimer(_10ms)

                setattr(self.buttons_ev, "btn_ev{}".format(i), btn_ev)

                self.comb += [
                    btn_timer.wait.eq(user_btns[i]),
                    btn_ev.trigger.eq(~btn_timer.done),
                ]

                self.submodules += [btn_timer]

            self.buttons_ev.finalize()
        self._buttons_count = CSRConstant(len(user_btns))
示例#22
0
    def __init__(self, sys_clk_freq=int(50e6), x5_clk_freq=None, toolchain="trellis", **kwargs):
        from litex.build.generic_platform import Subsignal, Pins, IOStandard
        platform = ecp5_evn.Platform(toolchain=toolchain)
        self._add_extentions(platform)

        # SoCCore ----------------------------------------------------------------------------------
        SoCCore.__init__(self, platform, clk_freq=sys_clk_freq, integrated_main_ram_size=0x8000, **kwargs)

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

        # HyperRam ---------------------------------------------------------------------------------
        self.submodules.hyperram = HyperRAM(platform.request("hyperram"))
        #self.submodules.hyperram = HyperRAMX2(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)

        # ADC RAM
        self.add_ram("adc_sram", self.mem_map["adc_sram"], 8*4*4096)

        # ADC --------------------------------------------------------------------------------------
        adc_ctrl = platform.request("adc_ctrl", 0)
        adc_data = platform.request("adc_data", 0)

        self.add_csr("adc")
        self.submodules.adc = ADC3321_DMA(adc_ctrl, adc_data)
        self.add_wb_master(self.adc.wishbone)


        # Leds -------------------------------------------------------------------------------------
        self.submodules.leds = LedChaser(
            pads         = Cat(*[platform.request("user_led", i) for i in range(8)]),
            sys_clk_freq = sys_clk_freq)
        self.add_csr("leds")

        # Phase noise downconverter, control lines
        self.add_csr("pn_gpio")
        pn_control = platform.request("pn_control")
        self.submodules.pn_gpio = GPIOOut(Cat([pn_control.if_g1, pn_control.if_g2, pn_control.buf_pd, pn_control.synth_ce]))

        # ADC SPI bus ------------------------------------------------------------------------------
        # max SPI frequency is 20 MHz
        self.add_csr("adc_spi")
        self.submodules.adc_spi = SPIMaster(platform.request("adc_spi",1), 24, sys_clk_freq, int(sys_clk_freq/80), with_csr=True)

        # VT ADC SPI bus ------------------------------------------------------------------------------
        # TODO: set payload size
        self.add_csr("vt_spi")
        self.submodules.vt_spi = SPIMaster(platform.request("vt_adc_spi",0), 24, sys_clk_freq, int(sys_clk_freq/80), with_csr=True)

        # synth SPI bus ------------------------------------------------------------------------------
        self.add_csr("synth_spi")
        self.submodules.synth_spi = SPIMaster(platform.request("synth_spi",0), 24, sys_clk_freq, int(sys_clk_freq/80), with_csr=True)

        # Wishbone Debug
        # added io to platform, serial_wb
        self.submodules.bridge = UARTWishboneBridge(platform.request("serial_wb",1), sys_clk_freq, baudrate=3000000)
        self.add_wb_master(self.bridge.wishbone)
        self.add_csr("analyzer")

        analyzer_signals = [
 #           self.adc.adc_frontend.adc_buffer.adc_dout0,
 #           self.adc.adc_frontend.adc_buffer.adc_dout1,
 #           self.adc.adc_frontend.adc_buffer.i_fclk,
           self.adc.adc_frontend_a.i_we,
#            self.adc.adc_frontend.i_re,
#            self.adc.adc_frontend.o_readable,
 #           self.adc.adc_frontend.adc_buffer.o_dout,
 #           self.adc.adc_frontend.adc_buffer.pulser.output,
 #           self.adc.adc_frontend.adc_buffer.fifo.din,
 #           self.adc.adc_frontend.o_dout,
        ]

        #t = Signal()
        #self.comb += [t.eq(clk_outputs.hr_p)]

        analyzer_depth = 512 # samples
        analyzer_clock_domain = "sys"
        self.submodules.analyzer = LiteScopeAnalyzer(analyzer_signals,
                                                     analyzer_depth,
                                                     clock_domain=analyzer_clock_domain)


        # put pulser on pin..
        debug_pins  = platform.request("debug_pins")
        self.comb += debug_pins.dbg1.eq(self.adc.adc_frontend_a.adc_buffer.pulser.output)
示例#23
0
    def __init__(self, iobuf, debug=False, cdc=False):

        self.background = ModuleDoc(title="USB Device Tri-FIFO",
                                    body="""
            This is a three-FIFO USB device.  It presents one FIFO each for ``IN``, ``OUT``, and
            ``SETUP`` data.  This allows for up to 16 ``IN`` and 16 ``OUT`` endpoints
            without sacrificing many FPGA resources.

            USB supports four types of transfers: control, bulk, interrupt, and isochronous.
            This device does not yet support isochronous transfers, however it supports the
            other types of transfers.
            """)

        self.interrupt_bulk_transfers = ModuleDoc(
            title="Interrupt and Bulk Transfers",
            body="""
            Interrupt and bulk transfers are similar from an implementation standpoint --
            they differ only in terms of how often they are transmitted.

            These transfers can be made to any endpoint, and may even be interleaved.  However,
            due to the nature of ``TriEndpointInterface`` any attempt by the host to interleave
            transfers will result in a ``NAK``, and the host will retry later when the buffer
            is empty.

            IN Transfers
            ^^^^^^^^^^^^

            To make an ``IN`` transfer (i.e. to send data to the host), write the data to
            ``IN_DATA``.  This is a FIFO, and each write to this endpoint will advance the
            FIFO pointer automatically.  This FIFO is 64 bytes deep.  USB ``DATA`` packets
            contain a CRC16 checksum, which is automatically added to any ``IN`` transfers.

            ``TriEndpointInterface`` will continue to respond ``NAK`` until you arm the buffer.
            Do this by writing the endpoint number to ``IN_CTRL.EPNO``.  This will tell the device
            that it should send the data the next time the host asks for it.

            Once the data has been transferred, the device will raise an interrupt and you
            can begin re-filling the buffer, or fill it with data for a different endpoint.

            To send an empty packet, avoid writing any data to ``IN_DATA`` and simply write
            the endpoint number to ``IN_CTRL.EPNO``.

            The CRC16 will be automatically appended to the end of the transfer.

            OUT Transfers
            ^^^^^^^^^^^^^

            To respond to an ``OUT`` transfer (i.e. to receive data from the host), enable
            a particular endpoint by writing to ``OUT_CTRL.EPNO`` with the ``OUT_CTRL.ENABLE``
            bit set.  This will tell the device to stop responding ``NAK`` to that particular
            endpoint and to accept any incoming data into a 66-byte FIFO, provided the FIFO
            is empty.

            Once the host sends data, an interrupt will be raised and that particular endpoint's
            ``ENABLE`` will be set to ``0``.  This prevents any additional data from entering
            the FIFO while the device examines the data.

            The FIFO will contain two extra bytes, which are the two-byte CRC16 of the packet.
            You can safely discard these bytes.  Because of this, a zero-byte transfer will
            be two-bytes, and a full 64-byte transfer will be 66 bytes.

            To determine which endpoint the ``OUT`` packet was sent to, refer to
            ``OUT_STATUS.EPNO``.  This field is only updated when a successful packet is received,
            and will not change until the ``OUT`` FIFO is re-armed.

            The ``OUT`` FIFO will continue to respond to the host with with ``NAK`` until the
            ``OUT_EV_PENDING.DONE`` bit is cleared.

            Additionally, to continue receiving data on that particular endpoint, you will need
            to re-enable it by writing the endpoint number, along with the ``OUT_CTRL.ENABLE``
            to ``OUT_CTRL``.
            """)
        self.control_transfers = ModuleDoc(title="Control Transfers",
                                           body="""
            Control transfers are complicated, and are the first sort of transfer that
            the host uses.  Such transfers have three distinct phases.

            The first phase is the ``SETUP`` phase, where the host sends an 8-byte ``SETUP``
            packet.  These ``SETUP`` packets must always be acknowledged, so any such packet
            from the host will get loaded into the ``SETUP`` FIFO immediately, and an interrupt
            event raised.  If, for some reason, the device hasn't drained this ``SETUP``
            FIFO from a previous transaction, the FIFO will be cleared automatically.

            Once the ``SETUP`` packet is handled, the host will send an ``IN`` or ``OUT``
            packet.  If the host sends an ``OUT`` packet, then the ``OUT`` buffer must be
            cleared, the ``OUT.DONE`` interrupt handled, and the ``OUT_CTRL.ENABLE`` bit
            must be set for the appropriate endpoint, usually EP0.  The device will not
            accept any data as long as these three conditions are not met.

            If the host sends an ``IN`` packet, the device will respond with ``NAK`` if
            no data has queued.  To queue data, fill the ``IN_DATA`` buffer, then write
            ``0`` to ``IN_CTRL``.

            You can continue to fill the buffer (for ``IN`` packets) or drain the buffer
            and re-enable the endpoint (for ``OUT`` packets) until the host has finished
            the transfer.

            When the host has finished, it will send the opposite packet type.  If it
            is making ``IN`` transfers, it will send a single ``OUT`` packet, or if it
            is making ``OUT`` transfers it will send a single ``IN`` packet.
            You must handle this transaction yourself.

            Stalling an Endpoint
            ^^^^^^^^^^^^^^^^^^^^

            When the host sends a request that cannot be processed -- for example requesting
            a descriptor that does not exist -- the device must respond with ``STALL``.

            Each endpoint keeps track of its own ``STALL`` state, though a ``SETUP`` packet
            will clear the ``STALL`` state for the specified endpoint (usually EP0).

            To set or clear the ``STALL`` bit of an ``IN`` endpoint, write its endpoint number
            to ``IN_CTRL.EPNO`` with the ``IN_CTRL.STALL`` bit either set or clear.  If
            this bit is set, then the device will respond to the next ``IN`` packet from the
            host to that particular endpoint with ``STALL``.  If the bit is clear, then
            the next ``IN`` packet will be responded to with ``ACK`` and the contents of
            the ``IN`` FIFO.

            To stall an ``OUT`` endpoint, write to ``OUT_CTRL.EPNO`` with the ``OUT_CTRL.STALL``
            bit set.  To unstall, write to ``OUT_CTRL.EPNO`` with the ``OUT_CTRL.STALL`` bit
            cleared.  Note that ``OUT_CTRL.ENABLE`` should not be set at the same time as
            ``OUT_CTRL.STALL``, as this will cause a conflict.
            """)

        # USB Core
        self.submodules.usb_core = usb_core = UsbTransfer(iobuf)

        self.submodules.pullup = GPIOOut(usb_core.iobuf.usb_pullup)
        self.iobuf = usb_core.iobuf

        # Generate debug signals, in case debug is enabled.
        debug_packet_detected = Signal()

        # Wire up debug signals if required
        if debug:
            self.submodules.debug_bridge = debug_bridge = USBWishboneBridge(
                self.usb_core, cdc=cdc)
            self.comb += [
                debug_packet_detected.eq(
                    ~self.debug_bridge.n_debug_in_progress),
            ]

        ems = []

        # When the USB host sends a USB reset, set our address back to 0.
        self.address = ResetInserter()(CSRStorage(
            name="address",
            fields=[
                CSRField(
                    "addr",
                    7,
                    description=
                    "Write the USB address from USB ``SET_ADDRESS`` packets.")
            ],
            description="""
                Sets the USB device address, in order to ignore packets
                going to other devices on the bus. This value is reset when the host
                issues a USB Device Reset condition.
            """))
        self.comb += self.address.reset.eq(usb_core.usb_reset)

        self.next_ev = CSRStatus(
            fields=[
                CSRField(
                    "in",
                    1,
                    description="``1`` if the next event is an ``IN`` event"),
                CSRField(
                    "out",
                    1,
                    description="``1`` if the next event is an ``OUT`` event"),
                CSRField(
                    "setup",
                    1,
                    description="``1`` if the next event is an ``SETUP`` event"
                ),
                CSRField(
                    "reset",
                    1,
                    description="``1`` if the next event is a ``RESET`` event"
                ),
            ],
            description="""
                In ``eptri``, there are three endpoints.  It is possible for an IRQ to fire
                and have all three bits set.  Under these circumstances it can be difficult
                to know which event to process first.  Use this register to determine which
                event needs to be processed first.
                Only one bit will ever be set at a time.
            """,
        )

        # Handlers
        self.submodules.setup = setup_handler = ClockDomainsRenamer("usb_12")(
            SetupHandler(usb_core))
        self.comb += setup_handler.usb_reset.eq(usb_core.usb_reset)
        ems.append(setup_handler.ev)

        in_handler = ClockDomainsRenamer("usb_12")(InHandler(usb_core))
        self.submodules.__setattr__("in", in_handler)
        ems.append(in_handler.ev)

        self.submodules.out = out_handler = ClockDomainsRenamer("usb_12")(
            OutHandler(usb_core))
        ems.append(out_handler.ev)

        self.submodules.ev = ev.SharedIRQ(*ems)

        in_next = Signal()
        out_next = Signal()
        self.sync += [
            If(
                usb_core.usb_reset,
                in_next.eq(0),
                out_next.eq(0),
                # If the in_handler is set but not the out_handler, that one is next
            ).Elif(
                in_handler.ev.packet.pending & ~out_handler.ev.packet.pending,
                in_next.eq(1),
                out_next.eq(0),
                # If the out_handler is set first, mark that as `next`
            ).Elif(
                ~in_handler.ev.packet.pending & out_handler.ev.packet.pending,
                in_next.eq(0),
                out_next.eq(1),
                # If neither is set, then clear the bits.
            ).Elif(
                ~in_handler.ev.packet.pending & ~out_handler.ev.packet.pending,
                in_next.eq(0),
                out_next.eq(0),
            ),
            # If both are set, don't do anything.
        ]
        self.comb += [
            If(
                setup_handler.ev.reset.pending,
                self.next_ev.fields.reset.eq(1),
            ).Elif(
                in_next,
                getattr(self.next_ev.fields, "in").eq(1),
            ).Elif(
                out_next,
                self.next_ev.fields.out.eq(out_next),
            ).Elif(
                setup_handler.ev.packet.pending,
                self.next_ev.fields.setup.eq(1),
            )
        ]

        # If a debug packet comes in, the DTB should be 1.  Otherwise, the DTB should
        # be whatever the in_handler says it is.
        self.comb += usb_core.dtb.eq(in_handler.dtb | debug_packet_detected)
        usb_core_reset = Signal()

        self.submodules.stage = stage = ClockDomainsRenamer("usb_12")(
            ResetInserter()(FSM(reset_state="IDLE")))
        self.comb += stage.reset.eq(usb_core.usb_reset)

        stage.act("IDLE", NextValue(usb_core.addr, self.address.storage),
                  If(usb_core.start, NextState("CHECK_TOK")))

        stage.act(
            "CHECK_TOK",
            If(
                usb_core.idle,
                NextState("IDLE"),
            ).Elif(
                usb_core.tok == PID.SETUP,
                NextState("SETUP"),
                setup_handler.begin.eq(1),
                in_handler.dtb_reset.eq(1),
                # SETUP packets must be ACKed unconditionally
                usb_core.sta.eq(0),
                usb_core.arm.eq(1),
            ).Elif(
                usb_core.tok == PID.IN,
                NextState("IN"),
                usb_core.sta.eq(in_handler.stalled),
                usb_core.arm.eq(in_handler.response),
            ).Elif(
                usb_core.tok == PID.OUT,
                NextState("OUT"),
                usb_core.sta.eq(out_handler.stalled),
                usb_core.arm.eq(out_handler.response),
            ).Else(NextState("IDLE"), ))

        if debug:
            stage.act(
                "DEBUG",
                usb_core.data_send_payload.eq(self.debug_bridge.sink_data),
                usb_core.data_send_have.eq(self.debug_bridge.sink_valid),
                usb_core.sta.eq(0),
                If(
                    usb_core.endp == 0,
                    usb_core.arm.eq(self.debug_bridge.send_ack
                                    | self.debug_bridge.sink_valid),
                ).Else(usb_core.arm.eq(0)),
                If(~debug_packet_detected, NextState("IDLE")))
        else:
            stage.act("DEBUG", NextState("IDLE"))

        stage.act(
            "SETUP",
            # SETUP packet
            setup_handler.data_recv_payload.eq(usb_core.data_recv_payload),
            setup_handler.data_recv_put.eq(usb_core.data_recv_put),

            # We aren't allowed to STALL a SETUP packet
            usb_core.sta.eq(0),

            # Always ACK a SETUP packet
            usb_core.arm.eq(1),
            If(debug_packet_detected, NextState("DEBUG")),
            If(
                usb_core.end,
                NextState("IDLE"),
            ),
        )

        stage.act(
            "IN",
            If(
                usb_core.tok == PID.IN,
                # IN packet (device-to-host)
                usb_core.data_send_have.eq(in_handler.data_out_have),
                usb_core.data_send_payload.eq(in_handler.data_out),
                in_handler.data_out_advance.eq(usb_core.data_send_get),
                usb_core.sta.eq(in_handler.stalled),
                usb_core.arm.eq(in_handler.response),

                # After an IN transfer, the host sends an OUT
                # packet.  We must ACK this and then return to IDLE.
                If(
                    usb_core.end,
                    NextState("IDLE"),
                ),
            ),
        )

        stage.act(
            "OUT",
            If(
                usb_core.tok == PID.OUT,
                # OUT packet (host-to-device)
                out_handler.data_recv_payload.eq(usb_core.data_recv_payload),
                out_handler.data_recv_put.eq(usb_core.data_recv_put),
                usb_core.sta.eq(out_handler.stalled),
                usb_core.arm.eq(out_handler.response),

                # After an OUT transfer, the host sends an IN
                # packet.  We must ACK this and then return to IDLE.
                If(
                    usb_core.end,
                    NextState("IDLE"),
                ),
            ),
        )

        self.comb += usb_core.reset.eq(usb_core.error | usb_core_reset)
示例#24
0
    def __init__(self,
                 variant="cle-215+",
                 sys_clk_freq=int(100e6),
                 with_led_chaser=True,
                 with_pcie=False,
                 with_sata=False,
                 **kwargs):
        platform = acorn.Platform(variant=variant)

        # SoCCore ----------------------------------------------------------------------------------
        SoCCore.__init__(self,
                         platform,
                         sys_clk_freq,
                         ident="LiteX SoC on Acorn CLE-101/215(+)",
                         **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,
                iodelay_clk_freq=200e6)
            self.add_sdram("sdram",
                           phy=self.ddrphy,
                           module=MT41K512M16(sys_clk_freq, "1:4"),
                           l2_cache_size=kwargs.get("l2_size", 8192))

        # PCIe -------------------------------------------------------------------------------------
        if with_pcie:
            self.submodules.pcie_phy = S7PCIEPHY(platform,
                                                 platform.request("pcie_x4"),
                                                 data_width=128,
                                                 bar0_size=0x20000)
            self.add_pcie(phy=self.pcie_phy, ndmas=1)
            # FIXME: Apply it to all targets (integrate it in LitePCIe?).
            platform.add_period_constraint(self.crg.cd_sys.clk,
                                           1e9 / sys_clk_freq)
            platform.toolchain.pre_placement_commands.add(
                "set_clock_groups -group [get_clocks {sys_clk}] -group [get_clocks userclk2] -asynchronous",
                sys_clk=self.crg.cd_sys.clk)
            platform.toolchain.pre_placement_commands.add(
                "set_clock_groups -group [get_clocks {sys_clk}] -group [get_clocks clk_125mhz] -asynchronous",
                sys_clk=self.crg.cd_sys.clk)
            platform.toolchain.pre_placement_commands.add(
                "set_clock_groups -group [get_clocks {sys_clk}] -group [get_clocks clk_250mhz] -asynchronous",
                sys_clk=self.crg.cd_sys.clk)
            platform.toolchain.pre_placement_commands.add(
                "set_clock_groups -group [get_clocks clk_125mhz] -group [get_clocks clk_250mhz] -asynchronous"
            )

            # ICAP (For FPGA reload over PCIe).
            from litex.soc.cores.icap import ICAP
            self.submodules.icap = ICAP()
            self.icap.add_reload()
            self.icap.add_timing_constraints(platform, sys_clk_freq,
                                             self.crg.cd_sys.clk)

            # Flash (For SPIFlash update over PCIe).
            from litex.soc.cores.gpio import GPIOOut
            from litex.soc.cores.spi_flash import S7SPIFlash
            self.submodules.flash_cs_n = GPIOOut(
                platform.request("flash_cs_n"))
            self.submodules.flash = S7SPIFlash(platform.request("flash"),
                                               sys_clk_freq, 25e6)

        # SATA -------------------------------------------------------------------------------------
        if with_sata:
            from litex.build.generic_platform import Subsignal, Pins
            from litesata.phy import LiteSATAPHY

            # IOs
            _sata_io = [
                # PCIe 2 SATA Custom Adapter (With PCIe Riser / SATA cable mod).
                (
                    "pcie2sata",
                    0,
                    Subsignal("tx_p", Pins("B6")),
                    Subsignal("tx_n", Pins("A6")),
                    Subsignal("rx_p", Pins("B10")),
                    Subsignal("rx_n", Pins("A10")),
                ),
            ]
            platform.add_extension(_sata_io)

            # RefClk, Generate 150MHz from PLL.
            self.clock_domains.cd_sata_refclk = ClockDomain()
            self.crg.pll.create_clkout(self.cd_sata_refclk, 150e6)
            sata_refclk = ClockSignal("sata_refclk")
            platform.add_platform_command(
                "set_property SEVERITY {{Warning}} [get_drc_checks REQP-49]")

            # PHY
            self.submodules.sata_phy = LiteSATAPHY(
                platform.device,
                refclk=sata_refclk,
                pads=platform.request("pcie2sata"),
                gen="gen1",
                clk_freq=sys_clk_freq,
                data_width=16)

            # Core
            self.add_sata(phy=self.sata_phy, mode="read+write")

        # Leds -------------------------------------------------------------------------------------
        if with_led_chaser:
            self.submodules.leds = LedChaser(
                pads=platform.request_all("user_led"),
                sys_clk_freq=sys_clk_freq)
示例#25
0
    def __init__(self,
                 iobuf,
                 endpoints=[
                     EndpointType.BIDIR, EndpointType.IN, EndpointType.BIDIR
                 ],
                 debug=False):
        size = 9

        # USB Core
        self.submodules.usb_core = usb_core = UsbTransfer(iobuf)

        self.submodules.pullup = GPIOOut(usb_core.iobuf.usb_pullup)
        self.iobuf = usb_core.iobuf

        # Generate debug signals, in case debug is enabled.
        debug_packet_detected = Signal()
        debug_data_mux = Signal(8)
        debug_data_ready_mux = Signal()
        debug_sink_data = Signal(8)
        debug_sink_data_ready = Signal()
        debug_ack_response = Signal()

        # Delay the "put" signal (and corresponding data) by one cycle, to allow
        # the debug system to inhibit this write.  In practice, this doesn't
        # impact our latency at all as this signal runs at a rate of ~1 MHz.
        data_recv_put_delayed = Signal()
        data_recv_payload_delayed = Signal(8)
        self.sync += [
            data_recv_put_delayed.eq(usb_core.data_recv_put),
            data_recv_payload_delayed.eq(usb_core.data_recv_payload),
        ]

        # Add a signal to EP0OUT to drain it when we get a SETUP packet
        # if it's not empty.
        setup_do_drain = Signal()

        # Endpoint controls
        ems = []
        eps = []
        trigger_all = []
        for i, endp in enumerate(endpoints):
            if endp & EndpointType.OUT:
                exec("self.submodules.ep_%s_out = ep = EndpointOut()" % i)
                oep = getattr(self, "ep_%s_out" % i)
                if i == 0:
                    self.comb += oep.drain_buffer.eq(~iobuf.usb_pullup
                                                     | setup_do_drain)
                else:
                    self.comb += oep.drain_buffer.eq(~iobuf.usb_pullup)
                ems.append(oep.ev)
            else:
                oep = EndpointNone()

            trigger_all.append(oep.trigger.eq(1)),
            eps.append(oep)

            if endp & EndpointType.IN:
                exec("self.submodules.ep_%s_in = ep = EndpointIn()" % i)
                iep = getattr(self, "ep_%s_in" % i)
                ems.append(iep.ev)
            else:
                iep = EndpointNone()

            trigger_all.append(iep.trigger.eq(1)),
            eps.append(iep)

        self.submodules.ev = ev.SharedIRQ(*ems)

        self.eps = eps = Array(eps)
        self.eps_idx = eps_idx = Signal(5)
        self.comb += [
            self.eps_idx.eq(Cat(usb_core.tok == PID.IN, usb_core.endp)),
        ]

        ep0out_addr = EndpointType.epaddr(0, EndpointType.OUT)
        ep0in_addr = EndpointType.epaddr(0, EndpointType.IN)

        # Setup packet causes ep0 in and ep0 out to reset
        self.comb += [
            eps[ep0out_addr].reset.eq(usb_core.setup & ~debug_packet_detected),
            eps[ep0in_addr].reset.eq(usb_core.setup & ~debug_packet_detected),
        ]

        # If we get a SETUP packet, drain the EP0OUT FIFO.
        # This works around a problem where there are two SETUP sequences
        # back-to-back.  Without this, the two-byte CRC from the previous
        # OUT packet will get added to the front of the subsequent DATA
        # packet if the buffer isn't drained quickly enough.
        # To work around this, assert `setup_do_drain` until the buffer
        # is no longer readable.
        last_start = Signal()
        self.sync += [
            last_start.eq(usb_core.start),
            If(
                ~debug_packet_detected,
                If(
                    last_start,
                    If(usb_core.tok == PID.SETUP,
                       If(
                           ~debug_packet_detected,
                           setup_do_drain.eq(1),
                       ))).Elif(
                           setup_do_drain & ~eps[ep0out_addr].obuf.readable,
                           setup_do_drain.eq(0),
                       ))
        ]

        # Wire up debug signals if required
        if debug:
            debug_bridge = USBWishboneBridge(self.usb_core)
            self.submodules.debug_bridge = ClockDomainsRenamer("usb_12")(
                debug_bridge)
            self.comb += [
                debug_packet_detected.eq(
                    ~self.debug_bridge.n_debug_in_progress),
                debug_sink_data.eq(self.debug_bridge.sink_data),
                debug_sink_data_ready.eq(self.debug_bridge.sink_valid),
                debug_ack_response.eq(self.debug_bridge.send_ack
                                      | self.debug_bridge.sink_valid),
            ]

        self.comb += [
            # This needs to be correct *before* token is finished, everything
            # else uses registered outputs.
            usb_core.sta.eq(((eps[eps_idx].response == EndpointResponse.STALL)
                             & ~debug_packet_detected)
                            & ~debug_sink_data_ready),
            usb_core.arm.eq(((eps[eps_idx].response == EndpointResponse.ACK)
                             & ~debug_packet_detected) | debug_ack_response),
            usb_core.dtb.eq(eps[eps_idx].dtb.storage | debug_packet_detected),

            # Control signals
            If(
                ~iobuf.usb_pullup,
                *trigger_all,
            ).Else(
                eps[eps_idx].trigger.eq(usb_core.commit
                                        & ~debug_packet_detected), ),
            If(
                debug_packet_detected,
                debug_data_mux.eq(debug_sink_data),
                debug_data_ready_mux.eq(debug_sink_data_ready),
            ).Else(
                debug_data_mux.eq(eps[eps_idx].ibuf.dout),
                debug_data_ready_mux.eq(eps[eps_idx].ibuf.readable),
            ),
            # FIFO
            # Host->Device[Out Endpoint] pathway
            eps[eps_idx].obuf.we.eq(data_recv_put_delayed
                                    & ~debug_packet_detected),
            eps[eps_idx].obuf.din.eq(data_recv_payload_delayed),
            # [In Endpoint]Device->Host pathway
            usb_core.data_send_have.eq(debug_data_ready_mux),
            usb_core.data_send_payload.eq(debug_data_mux),
            eps[eps_idx].ibuf.re.eq((usb_core.data_send_get
                                     & ~debug_packet_detected)
                                    | ~iobuf.usb_pullup),
        ]

        #w {
        #w   "reg_definition": {
        #w       "reg_name": "ADDRESS",
        #w       "reg_description": "Sets the USB device address, to ignore packets going to other devices.",
        #w       "reg": [
        #w           { "name": "ADDRESS", "bits": 7, "attr": "WO", "description": "Write the USB address from USB `SET_ADDRESS packets.`" },
        #w           {                    "bits": 1 }
        #w       ]
        #w   }
        #w }
        self.address = CSRStorage(7)
        self.comb += usb_core.addr.eq(self.address.storage)

        # self.error_count = CSRStatus(7)
        # error_count = Signal(7)
        # self.comb += self.error_count.status.eq(error_count)
        self.sync += [
            If(
                usb_core.commit & ~debug_packet_detected,
                eps[eps_idx].last_tok.status.eq(usb_core.tok[2:]),
            ),
            # Reset the transfer state machine if it gets into an error
            If(
                usb_core.error,
                # error_count.eq(error_count + 1),
                usb_core.reset.eq(1),
            ),
        ]
 def add_switches(self):
     self.submodules.switches = GPIOOut(
         Cat(platform_request_all(self.platform, "user_sw")))
     self.add_csr("switches")
示例#27
0
    def __init__(self, sys_clk_freq=int(100e6), **kwargs):
        platform = Platform()

        # SoCCore ---------------------------------------------------------------------------------
        SoCCore.__init__(self,
                         platform,
                         clk_freq=sys_clk_freq,
                         cpu_variant="standard+debug",
                         **kwargs)

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

        # CRG --------------------------------------------------------------------------------------
        self.submodules.uartbridge = UARTWishboneBridge(
            platform.request("serial2"), int(sys_clk_freq), baudrate=115200)
        self.add_wb_master(self.uartbridge.wishbone)
        self.register_mem("vexriscv_debug", 0xf00f0000, self.cpu.debug_bus,
                          0x10)

        tp_list = Cat(platform.request("TP1"), platform.request("TP2"),
                      platform.request("TP3"), platform.request("TP4"),
                      platform.request("TP5"), platform.request("TP6"),
                      platform.request("TP7"), platform.request("TP8"))
        print(
            "===================================================================="
        )
        print(tp_list)
        print(
            "===================================================================="
        )
        self.submodules.tp = GPIOTristate(tp_list)
        self.add_csr("tp")
        j1_35_pads = platform.request("J1_35")
        print(
            "===================================================================="
        )
        print(j1_35_pads)
        print(
            "===================================================================="
        )
        self.submodules.j1_35 = GPIOTristate(j1_35_pads)
        self.add_csr("j1_35")
        self.submodules.j1_34 = GPIOTristate(platform.request("J1_34"))
        self.add_csr("j1_34")
        self.submodules.j2_14 = GPIOTristate(platform.request("J2_14"))
        self.add_csr("j2_14")
        self.submodules.j2_16 = GPIOTristate(platform.request("J2_16"))
        self.add_csr("j2_16")
        self.submodules.led = GPIOOut(platform.request("rgb_led").raw_bits())
        self.add_csr("led")
        self.submodules.usba = GPIOTristate(
            platform.request("usb_a").raw_bits())
        self.add_csr("usba")
        self.submodules.usbmicro = GPIOTristate(
            platform.request("usb_micro").raw_bits())
        self.add_csr("usbmicro")
        self.submodules.clk_i2c = I2CMaster(pads=platform.request("clk_i2c"))
        self.add_csr("clk_i2c")
        self.submodules.pcie_ctrl = GPIOTristate(
            platform.request("pcie_ctrl").raw_bits())
        self.add_csr("pcie_ctrl")
        self.submodules.spi_flash = spi_flash.SpiFlashDualQuad(
            platform.request("spiflash4x"),
            with_bitbang=True,
            endianness="little")
        self.spi_flash.add_clk_primitive(platform.device)
        self.add_csr("spi_flash")
        self.submodules.ethernet = Serdes(platform)
示例#28
0
    def __init__(self,
                 pnr_placer="heap",
                 pnr_seed=0,
                 debug=True,
                 boot_vector=0x20020000,
                 **kwargs):
        """Create a basic SoC for iCEBreaker.

        Create a basic SoC for iCEBreaker.  The `sys` frequency will run at 12 MHz.

        Args:
            pnr_placer (str): Which placer to use in nextpnr
            pnr_seed (int): Which seed to use in nextpnr
        Returns:
            Newly-constructed SoC
        """
        platform = Platform()

        if "cpu_type" not in kwargs:
            kwargs["cpu_type"] = None
            kwargs["cpu_variant"] = None
        else:
            kwargs["cpu_reset_address"] = boot_vector

        clk_freq = int(12e6)

        # Force the SRAM size to 0, because we add our own SRAM with SPRAM
        kwargs["integrated_sram_size"] = 0
        kwargs["integrated_rom_size"] = 0

        if debug:
            kwargs["uart_name"] = "crossover"
            if kwargs["cpu_type"] == "vexriscv":
                kwargs["cpu_variant"] = kwargs["cpu_variant"] + "+debug"

        SoCCore.__init__(self,
                         platform,
                         clk_freq,
                         with_uart=True,
                         with_ctrl=True,
                         **kwargs)

        # If there is a VexRiscv CPU, add a fake ROM that simply tells the CPU
        # to jump to the given address.
        if hasattr(self, "cpu") and self.cpu.name == "vexriscv":
            self.add_memory_region("rom", 0, 16)
            self.submodules.rom = JumpToAddressROM(16, boot_vector)

        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)

        # 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.SpiFlash(spi_pads,
                                                   dummy=6,
                                                   endianness="little")
        self.register_mem("spiflash",
                          self.mem_map["spiflash"],
                          self.lxspi.bus,
                          size=16 * 1024 * 1024)
        self.add_csr("lxspi")

        # In debug mode, add a UART bridge.  This takes over from the normal UART bridge,
        # however you can use the "crossover" UART to communicate with this over the bridge.
        if debug:
            self.submodules.uart_bridge = UARTWishboneBridge(
                platform.request("serial"), clk_freq, baudrate=115200)
            self.add_wb_master(self.uart_bridge.wishbone)
            if hasattr(self, "cpu") and self.cpu.name == "vexriscv":
                self.register_mem("vexriscv_debug", 0xf00f0000,
                                  self.cpu.debug_bus, 0x100)

        ledsignals = Signal(2)
        self.submodules.leds = GPIOOut(ledsignals)
        self.comb += platform.request("user_ledr_n").eq(ledsignals[0])
        self.comb += platform.request("user_ledg_n").eq(ledsignals[1])
        self.add_csr("leds")

        # 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 add_leds(self):
     self.submodules.leds = GPIOOut(Cat(platform_request_all(self.platform, "user_led")))
     self.add_csr("leds")
示例#30
0
    def __init__(self, iobuf, auto_crc=True):
        self.submodules.iobuf = iobuf

        self.submodules.tx = tx = TxPipeline()
        self.submodules.txstate = txstate = TxPacketSend(tx, auto_crc=auto_crc)

        self.submodules.rx = rx = RxPipeline()
        self.submodules.rxstate = rxstate = PacketHeaderDecode(rx)

        # ----------------------
        # USB 48MHz bit strobe
        # ----------------------
        self.comb += [
            tx.i_bit_strobe.eq(rx.o_bit_strobe),
        ]

        self.reset = Signal()

        # ----------------------
        # Data paths
        # ----------------------
        self.data_recv_put = Signal()
        self.data_recv_payload = Signal(8)

        self.data_send_get = Signal()
        self.data_send_have = Signal()
        self.data_send_payload = Signal(8)

        # ----------------------
        # State signally
        # ----------------------
        # The value of these signals are generally dependent on endp, so we
        # need to wait for the rdy signal to use them.
        self.rdy = Signal(reset=1)
        self.dtb = Signal()
        self.arm = Signal()
        self.sta = Signal()

        # ----------------------
        # Tristate
        # ----------------------
        self.submodules.iobuf = iobuf
        self.comb += [
            rx.i_usbp.eq(iobuf.usb_p_rx),
            rx.i_usbn.eq(iobuf.usb_n_rx),
            iobuf.usb_tx_en.eq(tx.o_oe),
            iobuf.usb_p_tx.eq(tx.o_usbp),
            iobuf.usb_n_tx.eq(tx.o_usbn),
        ]
        self.submodules.pullup = GPIOOut(iobuf.usb_pullup)

        self.tok = Signal(4)  # Contains the transfer token type
        self.addr = Signal(7)
        self.endp = Signal(4)

        self.start = Signal()  # Asserted when a transfer is starting
        self.setup = Signal()  # Asserted when a transfer is a setup
        self.commit = Signal()  # Asserted when a transfer succeeds
        self.retry = Signal(
        )  # Asserted when the host sends an IN without an ACK
        self.abort = Signal()  # Asserted when a transfer fails
        self.end = Signal()  # Asserted when transfer ends
        self.error = Signal()  # Asserted when in the ERROR state
        self.comb += [
            self.end.eq(self.commit | self.abort),
        ]

        # Host->Device data path (Out + Setup data path)
        #
        # Token
        # Data
        # Handshake
        #
        # Setup --------------------
        # >Setup
        # >Data0[bmRequestType, bRequest, wValue, wIndex, wLength]
        # <Ack
        # --------------------------
        #
        # Data ---------------------
        # >Out        >Out        >Out
        # >DataX[..]  >DataX[..]  >DataX
        # <Ack        <Nak        <Stall
        #
        # Status -------------------
        # >Out
        # >Data0[]
        # <Ack
        # ---------------------------
        #
        # Host<-Device data path (In data path)
        # --------------------------
        # >In         >In     >In
        # <DataX[..]  <Stall  <Nak
        # >Ack
        # ---------------------------
        # >In
        # <Data0[]
        # >Ack
        # ---------------------------
        transfer = FSM(reset_state="WAIT_TOKEN")
        self.submodules.transfer = transfer = ClockDomainsRenamer("usb_12")(
            transfer)
        transfer.act(
            "ERROR",
            self.error.eq(1),
            If(self.reset, NextState("WAIT_TOKEN")),
        )

        transfer.act(
            "WAIT_TOKEN",
            If(
                rx.o_pkt_start,
                NextState("RECV_TOKEN"),
            ),
        )

        transfer.act(
            "RECV_TOKEN",
            If(
                rxstate.o_decoded,
                #If((rxstate.o_pid & PIDTypes.TYPE_MASK) != PIDTypes.TOKEN,
                #    NextState('ERROR'),
                #),
                NextValue(self.tok, rxstate.o_pid),
                NextValue(self.addr, rxstate.o_addr),
                NextValue(self.endp, rxstate.o_endp),
                self.start.eq(1),
                NextState("POLL_RESPONSE"),
            ),
        )

        response_pid = Signal(4)
        transfer.act(
            "POLL_RESPONSE",
            If(
                self.rdy,
                # Work out the response
                If(
                    self.tok == PID.SETUP,
                    NextValue(response_pid, PID.ACK),
                ).Elif(
                    self.sta,
                    NextValue(response_pid, PID.STALL),
                ).Elif(
                    self.arm,
                    NextValue(response_pid, PID.ACK),
                ).Else(NextValue(response_pid, PID.NAK), ),
                If(
                    rxstate.o_pid == PID.SOF,
                    NextState("WAIT_TOKEN"),

                    # Setup transfer
                ).Elif(
                    self.tok == PID.SETUP,
                    NextState("WAIT_DATA"),

                    # Out transfer
                ).Elif(
                    self.tok == PID.OUT,
                    NextState("WAIT_DATA"),

                    # In transfer
                ).Elif(
                    self.tok == PID.IN,
                    If(
                        ~self.arm | self.sta,
                        NextState("SEND_HAND"),
                    ).Else(NextState("SEND_DATA"), ),
                ).Else(NextState("WAIT_TOKEN"), ),
            ),
        )

        # Out + Setup pathway
        transfer.act(
            "WAIT_DATA",
            If(
                rxstate.o_decoded,
                If(
                    (rxstate.o_pid & PIDTypes.TYPE_MASK) == PIDTypes.DATA,
                    NextState("RECV_DATA"),
                ).Elif(
                    rxstate.o_pid == PID.SOF,
                    NextState("WAIT_DATA"),
                ).Else(NextState("ERROR"), )),
        )

        transfer.act(
            "RECV_DATA",
            # If we've indicated that we'll accept the data, put it into
            # `data_recv_payload` and strobe `data_recv_put` every time
            # a full byte comes in.
            If(
                response_pid == PID.ACK,
                self.data_recv_put.eq(rx.o_data_strobe),
            ),
            If(
                rx.o_pkt_end,
                NextState("SEND_HAND"),
            ),
        )
        self.comb += [
            self.data_recv_payload.eq(rx.o_data_payload),
        ]

        # In pathway
        transfer.act(
            "SEND_DATA",
            If(
                self.dtb,
                txstate.i_pid.eq(PID.DATA1),
            ).Else(txstate.i_pid.eq(PID.DATA0), ),
            self.data_send_get.eq(txstate.o_data_ack),
            If(txstate.o_pkt_end, NextState("WAIT_HAND")),
        )
        self.comb += [
            txstate.i_data_payload.eq(self.data_send_payload),
            txstate.i_data_ready.eq(self.data_send_have),
        ]

        # Handshake
        transfer.act(
            "WAIT_HAND",
            If(
                rxstate.o_decoded, self.commit.eq(1),
                If(
                    rxstate.o_pid == PID.ACK,
                    NextState("WAIT_TOKEN"),
                ).Elif(
                    rxstate.o_pid == PID.IN,
                    self.retry.eq(1),
                    NextState("SEND_DATA"),
                ).Else(NextState("ERROR"), )),
        )
        transfer.act(
            "SEND_HAND",
            txstate.i_pid.eq(response_pid),
            If(
                txstate.o_pkt_end,
                self.setup.eq(self.tok == PID.SETUP),
                If(
                    response_pid == PID.ACK,
                    self.commit.eq(1),
                ).Else(self.abort.eq(1), ),
                NextState("WAIT_TOKEN"),
            ),
        )

        # Code to reset header decoder when entering the WAIT_XXX states.
        self.comb += [
            If(
                tx.o_oe,
                rx.reset.eq(1),
            ),
        ]

        # Code to initiate the sending of packets when entering the SEND_XXX
        # states.
        self.comb += [
            If(
                transfer.before_entering("SEND_DATA"),
                If(
                    self.dtb,
                    txstate.i_pid.eq(PID.DATA1),
                ).Else(txstate.i_pid.eq(PID.DATA0), ),
                txstate.i_pkt_start.eq(1),
            ),
            If(
                transfer.before_entering("SEND_HAND"),
                txstate.i_pid.eq(response_pid),
                txstate.i_pkt_start.eq(1),
            ),
        ]