Пример #1
0
    def elaborate(self, platform):
        m = Module()
        m.submodules.bridge = self._bridge

        #
        # HyperRAM interface window.
        #
        ram_bus = platform.request('ram')
        m.submodules.psram = psram = HyperRAMInterface(
            bus=ram_bus, clock_skew=platform.ram_timings['clock_skew'])

        # Hook up our PSRAM.
        m.d.comb += [
            ram_bus.reset.eq(0),
            psram.single_page.eq(0),
            psram.perform_write.eq(0),
            psram.register_space.eq(1),
            psram.final_word.eq(1),
        ]

        #
        # Address register logic.
        #

        # Perform a read request whenever the user writes the address register...
        m.d.sync += psram.start_transfer.eq(self._address.w_stb)

        # And update the register address accordingly.
        with m.If(self._address.w_stb):
            m.d.sync += psram.address.eq(self._address.w_data)

        #
        # Value register logic.
        #

        # Always report back the last read data.
        with m.If(psram.new_data_ready):
            m.d.sync += self._value.r_data.eq(psram.read_data)

        #
        # Busy register logic.
        #
        m.d.comb += self._busy.r_data.eq(~psram.idle)

        return m
Пример #2
0
    def elaborate(self, platform):
        m = Module()

        # Generate our clock domains.
        clocking = LunaECP5DomainGenerator()
        m.submodules.clocking = clocking

        # Grab a reference to our debug-SPI bus.
        board_spi = synchronize(m, platform.request("debug_spi"))

        # Create a set of registers...
        spi_registers = SPIRegisterInterface(7, 32)
        m.submodules.spi_registers = spi_registers
        m.d.comb += spi_registers.spi.connect(board_spi)

        #
        # HyperRAM test connections.
        #
        ram_bus = platform.request('ram')
        psram = HyperRAMInterface(bus=ram_bus, **platform.ram_timings)
        m.submodules += psram

        psram_address_changed = Signal()
        psram_address = spi_registers.add_register(
            REGISTER_RAM_REG_ADDR, write_strobe=psram_address_changed)

        spi_registers.add_sfr(REGISTER_RAM_VALUE, read=psram.read_data)

        # Hook up our PSRAM.
        m.d.comb += [
            ram_bus.reset.eq(0),
            psram.single_page.eq(0),
            psram.perform_write.eq(0),
            psram.register_space.eq(1),
            psram.final_word.eq(1),
            psram.start_transfer.eq(psram_address_changed),
            psram.address.eq(psram_address),
        ]

        # Return our elaborated module.
        return m
Пример #3
0
    def elaborate(self, platform):
        m = Module()

        # Generate our clock domains.
        clocking = LunaECP5DomainGenerator()
        m.submodules.clocking = clocking

        # Create a set of registers...
        registers = JTAGRegisterInterface(address_size=7,
                                          default_read_value=0xDEADBEEF)
        m.submodules.registers = registers

        #
        # HyperRAM test connections.
        #
        ram_bus = platform.request('ram')
        psram = HyperRAMInterface(bus=ram_bus, **platform.ram_timings)
        m.submodules += psram

        psram_address_changed = Signal()
        psram_address = registers.add_register(
            REGISTER_RAM_REG_ADDR, write_strobe=psram_address_changed)

        registers.add_sfr(REGISTER_RAM_VALUE, read=psram.read_data)

        # Hook up our PSRAM.
        m.d.comb += [
            ram_bus.reset.eq(0),
            psram.single_page.eq(0),
            psram.perform_write.eq(0),
            psram.register_space.eq(1),
            psram.final_word.eq(1),
            psram.start_transfer.eq(psram_address_changed),
            psram.address.eq(psram_address),
        ]

        # Return our elaborated module.
        return m
Пример #4
0
    def elaborate(self, platform):
        m = Module()

        # Generate our clock domains.
        clocking = LunaECP5DomainGenerator(clock_frequencies=CLOCK_FREQUENCIES)
        m.submodules.clocking = clocking

        # Create a set of registers, and expose them over SPI.
        board_spi = platform.request("debug_spi")
        spi_registers = SPIRegisterInterface(default_read_value=-1)
        m.submodules.spi_registers = spi_registers

        # Simple applet ID register.
        spi_registers.add_read_only_register(REGISTER_ID, read=0x54455354)

        # LED test register.
        led_reg = spi_registers.add_register(REGISTER_LEDS, size=6, name="leds", reset=0b10)
        led_out   = Cat([platform.request("led", i, dir="o") for i in range(0, 6)])
        m.d.comb += led_out.eq(led_reg)

        #
        # Target power test register.
        # Note: these values assume you've populated the correct AP22814 for
        #       your revision (AP22814As for rev0.2+, and AP22814Bs for rev0.1).
        #     bits [1:0]: 0 = power off
        #                 1 = provide A-port VBUS
        #                 2 = pass through target VBUS
        #
        power_test_reg          = Signal(3)
        power_test_write_strobe = Signal()
        power_test_write_value  = Signal(2)
        spi_registers.add_sfr(REGISTER_TARGET_POWER,
            read=power_test_reg,
            write_strobe=power_test_write_strobe,
            write_signal=power_test_write_value
        )

        # Store the values for our enable bits.
        with m.If(power_test_write_strobe):
            m.d.sync += power_test_reg[0:2].eq(power_test_write_value)

        # Decode the enable bits and control the two power supplies.
        power_a_port      = platform.request("power_a_port")
        power_passthrough = platform.request("pass_through_vbus")
        with m.If(power_test_reg[0:2] == 1):
            m.d.comb += [
                power_a_port       .eq(1),
                power_passthrough  .eq(0)
            ]
        with m.Elif(power_test_reg[0:2] == 2):
            m.d.comb += [
                power_a_port       .eq(0),
                power_passthrough  .eq(1)
            ]
        with m.Else():
            m.d.comb += [
                power_a_port       .eq(0),
                power_passthrough  .eq(0)
            ]

        #
        # User IO GPIO registers.
        #

        # Data direction register.
        user_io_dir = spi_registers.add_register(REGISTER_USER_IO_DIR, size=4)

        # Pin (input) state register.
        user_io_in  = Signal(4)
        spi_registers.add_sfr(REGISTER_USER_IO_IN, read=user_io_in)

        # Output value register.
        user_io_out = spi_registers.add_register(REGISTER_USER_IO_OUT, size=4)

        # Grab and connect each of our user-I/O ports our GPIO registers.
        for i in range(4):
            pin = platform.request("user_io", i)
            m.d.comb += [
                pin.oe         .eq(user_io_dir[i]),
                user_io_in[i]  .eq(pin.i),
                pin.o          .eq(user_io_out[i])
            ]


        #
        # ULPI PHY windows
        #
        self.add_ulpi_registers(m, platform,
            ulpi_bus="target_phy",
            register_base=REGISTER_TARGET_ADDR
        )
        self.add_ulpi_registers(m, platform,
            ulpi_bus="host_phy",
            register_base=REGISTER_HOST_ADDR
        )
        self.add_ulpi_registers(m, platform,
            ulpi_bus="sideband_phy",
            register_base=REGISTER_SIDEBAND_ADDR
        )


        #
        # HyperRAM test connections.
        #
        ram_bus = platform.request('ram')
        psram = HyperRAMInterface(bus=ram_bus)
        m.submodules += psram

        psram_address_changed = Signal()
        psram_address = spi_registers.add_register(REGISTER_RAM_REG_ADDR, write_strobe=psram_address_changed)

        spi_registers.add_sfr(REGISTER_RAM_VALUE, read=psram.read_data)

        # Hook up our PSRAM.
        m.d.comb += [
            ram_bus.reset          .eq(0),
            psram.single_page      .eq(0),
            psram.perform_write    .eq(0),
            psram.register_space   .eq(1),
            psram.final_word       .eq(1),
            psram.start_transfer   .eq(psram_address_changed),
            psram.address          .eq(psram_address),
        ]


        #
        # SPI flash passthrough connections.
        #
        flash_sdo = Signal()

        spi_flash_bus = platform.request('spi_flash')
        spi_flash_passthrough = ECP5ConfigurationFlashInterface(bus=spi_flash_bus)

        m.submodules += spi_flash_passthrough
        m.d.comb += [
            spi_flash_passthrough.sck   .eq(board_spi.sck),
            spi_flash_passthrough.sdi   .eq(board_spi.sdi),
            flash_sdo                   .eq(spi_flash_passthrough.sdo),
        ]

        #
        # Synchronize each of our I/O SPI signals, where necessary.
        #
        spi = synchronize(m, board_spi)

        # Select the passthrough or gateware SPI based on our chip-select values.
        gateware_sdo = Signal()
        with m.If(spi_registers.spi.cs):
            m.d.comb += board_spi.sdo.eq(gateware_sdo)
        with m.Else():
            m.d.comb += board_spi.sdo.eq(flash_sdo)

        # Connect our register interface to our board SPI.
        m.d.comb += [
            spi_registers.spi.sck .eq(spi.sck),
            spi_registers.spi.sdi .eq(spi.sdi),
            gateware_sdo          .eq(spi_registers.spi.sdo),
            spi_registers.spi.cs  .eq(spi.cs)
        ]

        return m
Пример #5
0
    def elaborate(self, platform):
        m = Module()

        # Generate our clock domains.
        clocking = LunaECP5DomainGenerator(clock_frequencies=CLOCK_FREQUENCIES)
        m.submodules.clocking = clocking

        registers = JTAGRegisterInterface(default_read_value=0xDEADBEEF)
        m.submodules.registers = registers

        # Simple applet ID register.
        registers.add_read_only_register(REGISTER_ID, read=0x54455354)

        # LED test register.
        led_reg = registers.add_register(REGISTER_LEDS,
                                         size=6,
                                         name="leds",
                                         reset=0b111111)
        led_out = Cat(
            [platform.request("led", i, dir="o") for i in range(0, 6)])
        m.d.comb += led_out.eq(led_reg)

        #
        # Target power test register.
        # Note: these values assume you've populated the correct AP22814 for
        #       your revision (AP22814As for rev0.2+, and AP22814Bs for rev0.1).
        #     bits [1:0]: 0 = power off
        #                 1 = provide A-port VBUS
        #                 2 = pass through target VBUS
        #
        power_test_reg = Signal(3)
        power_test_write_strobe = Signal()
        power_test_write_value = Signal(2)
        registers.add_sfr(REGISTER_TARGET_POWER,
                          read=power_test_reg,
                          write_strobe=power_test_write_strobe,
                          write_signal=power_test_write_value)

        # Store the values for our enable bits.
        with m.If(power_test_write_strobe):
            m.d.sync += power_test_reg[0:2].eq(power_test_write_value)

        # Decode the enable bits and control the two power supplies.
        power_a_port = platform.request("power_a_port")
        power_passthrough = platform.request("pass_through_vbus")
        with m.If(power_test_reg[0:2] == 1):
            m.d.comb += [power_a_port.eq(1), power_passthrough.eq(0)]
        with m.Elif(power_test_reg[0:2] == 2):
            m.d.comb += [power_a_port.eq(0), power_passthrough.eq(1)]
        with m.Else():
            m.d.comb += [power_a_port.eq(0), power_passthrough.eq(0)]

        #
        # User IO GPIO registers.
        #

        # Data direction register.
        user_io_dir = registers.add_register(REGISTER_USER_IO_DIR, size=2)

        # Pin (input) state register.
        user_io_in = Signal(2)
        registers.add_sfr(REGISTER_USER_IO_IN, read=user_io_in)

        # Output value register.
        user_io_out = registers.add_register(REGISTER_USER_IO_OUT, size=2)

        # Grab and connect each of our user-I/O ports our GPIO registers.
        for i in range(2):
            pin = platform.request("user_io", i)
            m.d.comb += [
                pin.oe.eq(user_io_dir[i]), user_io_in[i].eq(pin.i),
                pin.o.eq(user_io_out[i])
            ]

        #
        # ULPI PHY windows
        #
        self.add_ulpi_registers(m,
                                platform,
                                ulpi_bus="target_phy",
                                register_base=REGISTER_TARGET_ADDR)
        self.add_ulpi_registers(m,
                                platform,
                                ulpi_bus="host_phy",
                                register_base=REGISTER_HOST_ADDR)
        self.add_ulpi_registers(m,
                                platform,
                                ulpi_bus="sideband_phy",
                                register_base=REGISTER_SIDEBAND_ADDR)

        #
        # HyperRAM test connections.
        #
        ram_bus = platform.request('ram')
        psram = HyperRAMInterface(bus=ram_bus, **platform.ram_timings)
        m.submodules += psram

        psram_address_changed = Signal()
        psram_address = registers.add_register(
            REGISTER_RAM_REG_ADDR, write_strobe=psram_address_changed)

        registers.add_sfr(REGISTER_RAM_VALUE, read=psram.read_data)

        # Hook up our PSRAM.
        m.d.comb += [
            ram_bus.reset.eq(0),
            psram.single_page.eq(0),
            psram.perform_write.eq(0),
            psram.register_space.eq(1),
            psram.final_word.eq(1),
            psram.start_transfer.eq(psram_address_changed),
            psram.address.eq(psram_address),
        ]

        return m
    def elaborate(self, platform):
        m = Module()

        # Generate our clock domains.
        clocking = LunaECP5DomainGenerator(clock_frequencies=CLOCK_FREQUENCIES)
        m.submodules.clocking = clocking

        # Create a set of registers, and expose them over SPI.
        board_spi = platform.request("debug_spi")
        spi_registers = SPIRegisterInterface(default_read_value=-1)
        m.submodules.spi_registers = spi_registers

        # Simple applet ID register.
        spi_registers.add_read_only_register(REGISTER_ID, read=0x54455354)

        # LED test register.
        led_reg = spi_registers.add_register(REGISTER_LEDS,
                                             size=5,
                                             name="leds",
                                             reset=0b1)
        led_out = Cat(
            [platform.request("led", i, dir="o") for i in range(0, 6)])
        m.d.comb += led_out[1:].eq(led_reg)

        #
        # User IO GPIO registers.
        #

        # Data direction register.
        user_io_dir = spi_registers.add_register(REGISTER_USER_IO_DIR, size=4)

        # Pin (input) state register.
        user_io_in = Signal(4)
        spi_registers.add_sfr(REGISTER_USER_IO_IN, read=user_io_in)

        # Output value register.
        user_io_out = spi_registers.add_register(REGISTER_USER_IO_OUT, size=4)

        # Grab and connect each of our user-I/O ports our GPIO registers.
        for i in range(4):
            pin = platform.request("user_io", i)
            m.d.comb += [
                pin.oe.eq(user_io_dir[i]), user_io_in[i].eq(pin.i),
                pin.o.eq(user_io_out[i])
            ]

        #
        # ULPI PHY windows
        #
        self.add_ulpi_registers(m,
                                platform,
                                ulpi_bus="host_phy",
                                register_base=REGISTER_HOST_ADDR)
        self.add_ulpi_registers(m,
                                platform,
                                ulpi_bus="sideband_phy",
                                register_base=REGISTER_SIDEBAND_ADDR)

        #
        # HyperRAM test connections.
        #
        ram_bus = platform.request('ram')
        psram = HyperRAMInterface(bus=ram_bus)
        m.submodules += psram

        psram_address_changed = Signal()
        psram_address = spi_registers.add_register(
            REGISTER_RAM_REG_ADDR, write_strobe=psram_address_changed)

        spi_registers.add_sfr(REGISTER_RAM_VALUE, read=psram.read_data)

        # Hook up our PSRAM.
        m.d.comb += [
            ram_bus.reset.eq(0),
            psram.single_page.eq(0),
            psram.perform_write.eq(0),
            psram.register_space.eq(1),
            psram.final_word.eq(1),
            psram.start_transfer.eq(psram_address_changed),
            psram.address.eq(psram_address),
        ]

        #
        # SPI flash passthrough connections.
        #
        flash_sdo = Signal()

        spi_flash_bus = platform.request('spi_flash')
        spi_flash_passthrough = ECP5ConfigurationFlashInterface(
            bus=spi_flash_bus)

        m.submodules += spi_flash_passthrough
        m.d.comb += [
            spi_flash_passthrough.sck.eq(board_spi.sck),
            spi_flash_passthrough.sdi.eq(board_spi.sdi),
            flash_sdo.eq(spi_flash_passthrough.sdo),
        ]

        #
        # Synchronize each of our I/O SPI signals, where necessary.
        #
        spi = synchronize(m, board_spi)

        # Select the passthrough or gateware SPI based on our chip-select values.
        gateware_sdo = Signal()
        with m.If(spi_registers.spi.cs):
            m.d.comb += board_spi.sdo.eq(gateware_sdo)
        with m.Else():
            m.d.comb += board_spi.sdo.eq(flash_sdo)

        # Connect our register interface to our board SPI.
        m.d.comb += [
            spi_registers.spi.sck.eq(spi.sck),
            spi_registers.spi.sdi.eq(spi.sdi),
            gateware_sdo.eq(spi_registers.spi.sdo),
            spi_registers.spi.cs.eq(spi.cs)
        ]

        # Radio SPI window
        radio = platform.request("radio")
        radio_spi = RadioSPI(clk_freq=CLOCK_FREQUENCIES["sync"] * 1e6)
        m.submodules += radio_spi

        radio_address_changed = Signal()
        radio_address = spi_registers.add_register(
            REGISTER_RADIO_ADDR, write_strobe=radio_address_changed)

        radio_value_changed = Signal()
        spi_registers.add_sfr(
            REGISTER_RADIO_VALUE,
            read=radio_spi.read_value,
            write_signal=radio_spi.write_value,
            write_strobe=radio_value_changed,
        )

        # Hook up our radio.
        m.d.comb += [
            radio.rst.eq(0),

            # SPI outputs
            radio.sel.eq(radio_spi.sel),
            radio.sclk.eq(radio_spi.sclk),
            radio.mosi.eq(radio_spi.mosi),

            # SPI inputs
            radio_spi.miso.eq(radio.miso),
            radio_spi.write.eq(radio_value_changed),
            radio_spi.start.eq(radio_address_changed | radio_value_changed),
            radio_spi.address.eq(radio_address),
        ]

        # Radio LVDS loop-back

        # Set up radio clock domain from rxclk, and pass it through to txclk
        m.domains.radio = ClockDomain()
        m.d.comb += [
            ClockSignal("radio").eq(radio.rxclk),
            ResetSignal("radio").eq(ResetSignal()),
            radio.txclk.eq(ClockSignal("radio")),
        ]

        # TX a pattern
        tx = Signal(8, reset=0x2e)
        m.d.radio += [
            tx.eq(Cat(tx[7], tx[:-1])),
            radio.txd.eq(tx[7]),
        ]

        # ... and receive it back.
        rx = Signal(8)
        rx_counter = Signal(range(8))
        m.d.radio += rx.eq(Cat(radio.rxd09, rx[:-1]))
        m.d.radio += rx_counter.eq(rx_counter - 1)

        # Sync up to the pattern
        got_sync = Signal()
        with m.FSM() as fsm:
            with m.State("start"):
                with m.If(rx == 0x2e):
                    m.next = "sync"
                    m.d.radio += got_sync.eq(1)
                    m.d.radio += rx_counter.eq(7)

            with m.State("sync"):
                with m.If(rx_counter == 0):
                    with m.If(rx != 0x2e):
                        m.next = "start"
                        m.d.radio += got_sync.eq(0)

            with m.State("error"):
                pass

        got_sync_reg = Signal()
        m.submodules += FFSynchronizer(got_sync, got_sync_reg)
        spi_registers.add_read_only_register(REGISTER_RADIO_SYNC,
                                             read=got_sync_reg)
        m.d.comb += led_out[0].eq(got_sync)

        return m