Exemplo n.º 1
0
    def elaborate(self, platform):
        m = Module()
        m.submodules += self.ila

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

        # Clock divider / counter.
        m.d.fast += self.counter.eq(self.counter + 1)

        # Set our ILA to trigger each time the counter is at a random value.
        # This shows off our example a bit better than counting at zero.
        m.d.comb += self.ila.trigger.eq(self.counter == 7)

        # Grab our I/O connectors.
        leds    = [platform.request("led", i, dir="o") for i in range(0, 6)]
        spi_bus = synchronize(m, platform.request('debug_spi'), o_domain='fast')

        # Attach the LEDs and User I/O to the MSBs of our counter.
        m.d.comb += Cat(leds).eq(self.counter[-7:-1])

        # Connect our ILA up to our board's aux SPI.
        m.d.comb += self.ila.spi.connect(spi_bus)

        # Return our elaborated module.
        return m
Exemplo n.º 2
0
    def elaborate(self, platform):
        m = Module()
        m.submodules += self.ila

        # Clock divider / counter.
        m.d.sync += self.counter.eq(self.counter + 1)

        # Set our ILA to trigger each time the counter is at a random value.
        # This shows off our example a bit better than counting at zero.
        m.d.comb += self.ila.trigger.eq(self.counter == 7)

        # Grab our I/O connectors.
        leds = [
            platform.request_optional("led", i, default=NullPin(), dir="o")
            for i in range(0, 6)
        ]
        spi_bus = synchronize(m, platform.request('debug_spi'))

        # Attach the LEDs and User I/O to the MSBs of our counter.
        m.d.comb += Cat(leds).eq(self.counter[-7:-1])

        # Connect our ILA up to our board's aux SPI.
        m.d.comb += self.ila.spi.connect(spi_bus)

        # Return our elaborated module.
        return m
Exemplo n.º 3
0
    def elaborate(self, platform):
        m = Module()
        board_spi = platform.request("debug_spi")

        # Create a set of registers, and expose them over SPI.
        spi_registers = SPIRegisterInterface(
            default_read_value=0x4C554E41)  #default read = u'LUNA'
        m.submodules.spi_registers = spi_registers

        # Fill in some example registers.
        # (Register 0 is reserved for size autonegotiation).
        spi_registers.add_read_only_register(1, read=0xc001cafe)
        led_reg = spi_registers.add_register(2, size=6, name="leds")
        spi_registers.add_read_only_register(3, read=0xdeadbeef)

        # ... and tie our LED register to our LEDs.
        led_out = Cat(
            [platform.request("led", i, dir="o") for i in range(0, 6)])
        m.d.comb += led_out.eq(led_reg)

        # Connect up our synchronized copies of the SPI registers.
        spi = synchronize(m, board_spi)
        m.d.comb += spi_registers.spi.connect(spi)

        return m
Exemplo n.º 4
0
    def elaborate(self, platform):
        m = Module()
        m.submodules += self.ila

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

        # Clock divider / counter.
        m.d.sync += self.counter.eq(self.counter + 1)

        # Another example signal, for variety.
        m.d.sync += self.toggle.eq(~self.toggle)

        # Create an SPI bus for our ILA.
        ila_spi = SPIBus()
        m.d.comb += [
            self.ila.spi .connect(ila_spi),

            # For sharing, we'll connect the _inverse_ of the primary
            # chip select to our ILA bus. This will allow us to send
            # ILA data when CS is un-asserted, and register data when
            # CS is asserted.
            ila_spi.cs  .eq(~board_spi.cs)
        ]

        # Create a set of registers...
        spi_registers = SPIRegisterInterface()
        m.submodules.spi_registers = spi_registers

        # ... and an SPI bus for them.
        reg_spi = SPIBus()
        m.d.comb += [
            spi_registers.spi .connect(reg_spi),
            reg_spi.cs        .eq(board_spi.cs)
        ]

        # Multiplex our ILA and register SPI busses.
        m.submodules.mux = SPIMultiplexer([ila_spi, reg_spi])
        m.d.comb += m.submodules.mux.shared_lines.connect(board_spi)

        # Add a simple ID register to demonstrate our registers.
        spi_registers.add_read_only_register(REGISTER_ID, read=0xDEADBEEF)

        # Create a simple SFR that will trigger an ILA capture when written,
        # and which will display our sample status read.
        spi_registers.add_sfr(REGISTER_ILA,
            read=self.ila.complete,
            write_strobe=self.ila.trigger
        )

        # Attach the LEDs and User I/O to the MSBs of our counter.
        leds    = [platform.request("led", i, dir="o") for i in range(0, 6)]
        m.d.comb += Cat(leds).eq(self.counter[-7:-1])

        # Return our elaborated module.
        return m
Exemplo n.º 5
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 our SPI-connected registers.
        m.submodules.spi_registers = spi_registers = SPIRegisterInterface(
            7, 32)
        m.d.comb += spi_registers.spi.connect(board_spi)

        # Create our UMTI translator.
        ulpi = platform.request("sideband_phy")
        m.submodules.umti = umti = UMTITranslator(ulpi=ulpi)

        # Strap our power controls to be in VBUS passthrough by default,
        # on the target port.
        m.d.comb += [
            platform.request("power_a_port").eq(0),
            platform.request("pass_through_vbus").eq(1),
        ]

        # Hook up our LEDs to status signals.
        m.d.comb += [
            platform.request("led", 0).eq(umti.vbus_valid),
            platform.request("led", 1).eq(umti.session_valid),
            platform.request("led", 2).eq(umti.session_end),
            platform.request("led", 3).eq(umti.rx_active),
            platform.request("led", 4).eq(umti.rx_error)
        ]

        spi_registers.add_read_only_register(1, read=umti.last_rx_command)

        # For debugging: mirror some ULPI signals on the UIO.
        user_io = Cat(
            platform.request("user_io", i, dir="o") for i in range(0, 4))
        m.d.comb += [
            user_io[0].eq(ClockSignal("ulpi")),
            user_io[1].eq(ulpi.dir),
            user_io[2].eq(ulpi.nxt),
            user_io[3].eq(ulpi.stp),
        ]

        # Return our elaborated module.
        return m
Exemplo n.º 6
0
    def elaborate(self, platform):
        m = Module()

        # 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

        # Identify ourselves as the SPI flash bridge.
        spi_registers.add_read_only_register(REGISTER_ID, read=0x53504946)

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

        #
        # Structural connections.
        #
        spi = synchronize(m, board_spi)

        # Select the passthrough or gateware SPI based on our chip-select values.
        gateware_sdo = Signal()
        with m.If(board_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
Exemplo n.º 7
0
    def elaborate(self, platform):
        m = Module()
        board_spi = platform.request("debug_spi")

        # Use command interface.
        m.submodules.interface = self.interface

        # Synchronize and connect SPI.
        spi = synchronize(m, board_spi)
        m.d.comb += self.interface.spi.connect(spi)

        # Turn on a single LED, to show something's running.
        led = platform.request('led', 0)
        m.d.comb += led.eq(1)

        # Echo back the last received data.
        m.d.comb += self.interface.word_out.eq(self.interface.word_in)

        return m
Exemplo n.º 8
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
Exemplo n.º 9
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
Exemplo n.º 10
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 our SPI-connected registers.
        m.submodules.spi_registers = spi_registers = SPIRegisterInterface(7, 8)
        m.d.comb += spi_registers.spi.connect(board_spi)

        # Create our UMTI translator.
        ulpi = platform.request("target_phy")
        m.submodules.umti = umti = UMTITranslator(ulpi=ulpi)

        # Strap our power controls to be in VBUS passthrough by default,
        # on the target port.
        m.d.comb += [
            platform.request("power_a_port").eq(0),
            platform.request("pass_through_vbus").eq(1),
        ]

        # Set up our parameters.
        m.d.comb += [

            # Set our mode to non-driving and to the desired speed.
            umti.op_mode.eq(0b01),
            umti.xcvr_select.eq(self.usb_speed),

            # Disable all of our terminations, as we want to participate in
            # passive observation.
            umti.dm_pulldown.eq(0),
            umti.dm_pulldown.eq(0),
            umti.term_select.eq(0)
        ]

        read_strobe = Signal()

        # Create a USB analyzer, and connect a register up to its output.
        m.submodules.analyzer = analyzer = USBAnalyzer(umti_interface=umti)

        # Provide registers that indicate when there's data ready, and what the result is.
        spi_registers.add_read_only_register(DATA_AVAILABLE,
                                             read=analyzer.data_available)
        spi_registers.add_read_only_register(ANALYZER_RESULT,
                                             read=analyzer.data_out,
                                             read_strobe=read_strobe)

        m.d.comb += [

            # Internal connections.
            analyzer.next.eq(read_strobe),

            # LED indicators.
            platform.request("led", 0).eq(analyzer.capturing),
            platform.request("led", 1).eq(analyzer.data_available),
            platform.request("led", 2).eq(analyzer.overrun),
            platform.request("led", 3).eq(umti.session_valid),
            platform.request("led", 4).eq(umti.rx_active),
            platform.request("led", 5).eq(umti.rx_error),
        ]

        # Return our elaborated module.
        return m
Exemplo n.º 11
0
 def elaborate(self, platform):
     m = Module()
     if platform and self.top:
         board_spi = platform.request("debug_spi")
         spi2 = synchronize(m, board_spi)
         m.d.comb += self.spi.connect(spi2)
     if self.platform:
         platform = self.platform
     spi = self.spi
     interf = SPICommandInterface(command_size=COMMAND_BYTES*8,
                                  word_size=WORD_BYTES*8)
     m.d.comb += interf.spi.connect(spi)
     m.submodules.interf = interf
     # FIFO connection
     fifo = TransactionalizedFIFO(width=MEMWIDTH,
                                  depth=platform.memdepth)
     if platform.name == 'Test':
         self.fifo = fifo
     m.submodules.fifo = fifo
     m.d.comb += [self.read_data.eq(fifo.read_data),
                  fifo.read_commit.eq(self.read_commit),
                  fifo.read_discard.eq(self.read_discard),
                  fifo.read_en.eq(self.read_en),
                  self.empty.eq(fifo.empty)]
     # Parser
     mtrcntr = Signal(range(platform.motors))
     wordsreceived = Signal(range(wordsinmove(platform.motors)+1))
     error = Signal()
     # Peripheral state
     state = Signal(8)
     m.d.sync += [state[STATE.PARSING].eq(self.execute),
                  state[STATE.FULL].eq(fifo.space_available <= 1),
                  state[STATE.ERROR].eq(self.dispatcherror | error)]
     # remember which word we are processing
     instruction = Signal(8)
     with m.FSM(reset='RESET', name='parser'):
         with m.State('RESET'):
             m.d.sync += [self.execute.eq(1), wordsreceived.eq(0),
                          error.eq(0)]
             m.next = 'WAIT_COMMAND'
         with m.State('WAIT_COMMAND'):
             with m.If(interf.command_ready):
                 word = Cat(state[::-1], self.pinstate[::-1])
                 with m.If(interf.command == COMMANDS.EMPTY):
                     m.next = 'WAIT_COMMAND'
                 with m.Elif(interf.command == COMMANDS.START):
                     m.next = 'WAIT_COMMAND'
                     m.d.sync += self.execute.eq(1)
                 with m.Elif(interf.command == COMMANDS.STOP):
                     m.next = 'WAIT_COMMAND'
                     m.d.sync += self.execute.eq(0)
                 with m.Elif(interf.command == COMMANDS.WRITE):
                     m.d.sync += interf.word_to_send.eq(word)
                     with m.If(state[STATE.FULL] == 0):
                         m.next = 'WAIT_WORD'
                     with m.Else():
                         m.next = 'WAIT_COMMAND'
                 with m.Elif(interf.command == COMMANDS.READ):
                     m.d.sync += interf.word_to_send.eq(word)
                     m.next = 'WAIT_COMMAND'
                 with m.Elif(interf.command == COMMANDS.POSITION):
                     # position is requested multiple times for multiple
                     # motors
                     with m.If(mtrcntr < platform.motors-1):
                         m.d.sync += mtrcntr.eq(mtrcntr+1)
                     with m.Else():
                         m.d.sync += mtrcntr.eq(0)
                     m.d.sync += interf.word_to_send.eq(
                                             self.position[mtrcntr])
                     m.next = 'WAIT_COMMAND'
         with m.State('WAIT_WORD'):
             with m.If(interf.word_complete):
                 byte0 = interf.word_received[:8]
                 with m.If(wordsreceived == 0):
                     with m.If((byte0 > 0) & (byte0 < 6)):
                         m.d.sync += [instruction.eq(byte0),
                                      fifo.write_en.eq(1),
                                      wordsreceived.eq(wordsreceived+1),
                                      fifo.write_data.eq(
                                          interf.word_received)]
                         m.next = 'WRITE'
                     with m.Else():
                         m.d.sync += error.eq(1)
                         m.next = 'WAIT_COMMAND'
                 with m.Else():
                     m.d.sync += [fifo.write_en.eq(1),
                                  wordsreceived.eq(wordsreceived+1),
                                  fifo.write_data.eq(interf.word_received)]
                     m.next = 'WRITE'
         with m.State('WRITE'):
             m.d.sync += fifo.write_en.eq(0)
             wordslaser = wordsinscanline(
                 params(platform)['BITSINSCANLINE'])
             wordsmotor = wordsinmove(platform.motors)
             with m.If(((instruction == INSTRUCTIONS.MOVE) &
                       (wordsreceived >= wordsmotor))
                       | (instruction == INSTRUCTIONS.WRITEPIN)
                       | (instruction == INSTRUCTIONS.LASTSCANLINE)
                       | ((instruction == INSTRUCTIONS.SCANLINE) &
                       (wordsreceived >= wordslaser)
                       )):
                 m.d.sync += [wordsreceived.eq(0),
                              fifo.write_commit.eq(1)]
                 m.next = 'COMMIT'
             with m.Else():
                 m.next = 'WAIT_COMMAND'
         with m.State('COMMIT'):
             m.d.sync += fifo.write_commit.eq(0)
             m.next = 'WAIT_COMMAND'
     return m
Exemplo n.º 12
0
 def elaborate(self, platform):
     m = Module()
     # Parser
     parser = SPIParser(self.platform)
     m.submodules.parser = parser
     # Busy used to detect move or scanline in action
     # disabled "dispatching"
     busy = Signal()
     # Polynomal Move
     polynomal = Polynomal(self.platform, self.divider)
     m.submodules.polynomal = polynomal
     if platform:
         board_spi = platform.request("debug_spi")
         spi = synchronize(m, board_spi)
         m.submodules.car = platform.clock_domain_generator()
         laserheadpins = platform.request("laserscanner")
         steppers = [res for res in get_all_resources(platform, "stepper")]
         assert len(steppers) != 0
     else:
         platform = self.platform
         self.spi = SPIBus()
         self.parser = parser
         self.pol = polynomal
         spi = synchronize(m, self.spi)
         self.laserheadpins = platform.laserhead
         self.steppers = steppers = platform.steppers
         self.busy = busy
         laserheadpins = self.platform.laserhead
     # Local laser signal clones
     enable_prism = Signal()
     lasers = Signal(2)
     # Laserscan Head
     if self.simdiode:
         laserhead = DiodeSimulator(platform=platform,
                                    addfifo=False)
         lh = laserhead
         m.d.comb += [lh.enable_prism_in.eq(enable_prism |
                      lh.enable_prism),
                      lh.laser0in.eq(lasers[0]
                      | lh.lasers[0]),
                      laserhead.laser1in.eq(lasers[1]
                      | lh.lasers[1])]
     else:
         laserhead = Laserhead(platform=platform)
         m.d.comb += laserhead.photodiode.eq(laserheadpins.photodiode)
     m.submodules.laserhead = laserhead
     if platform.name == 'Test':
         self.laserhead = laserhead
     # position adder
     busy_d = Signal()
     m.d.sync += busy_d.eq(polynomal.busy)
     coeffcnt = Signal(range(len(polynomal.coeff)))
     # connect laserhead
     m.d.comb += [
         laserheadpins.pwm.eq(laserhead.pwm),
         laserheadpins.en.eq(laserhead.enable_prism | enable_prism),
         laserheadpins.laser0.eq(laserhead.lasers[0] | lasers[0]),
         laserheadpins.laser1.eq(laserhead.lasers[1] | lasers[1]),
     ]
     # connect Parser
     m.d.comb += [
         self.read_data.eq(parser.read_data),
         laserhead.read_data.eq(parser.read_data),
         laserhead.empty.eq(parser.empty),
         self.empty.eq(parser.empty),
         parser.read_commit.eq(self.read_commit | laserhead.read_commit),
         parser.read_en.eq(self.read_en | laserhead.read_en),
         parser.read_discard.eq(self.read_discard | laserhead.read_discard)
     ]
     # connect motors
     for idx, stepper in enumerate(steppers):
         if idx != (list(platform.stepspermm.keys())
                    .index(platform.laser_axis)):
             step = (polynomal.step[idx] &
                     ((stepper.limit == 0) | stepper.dir))
             direction = polynomal.dir[idx]
         # connect the motor in which the laserhead moves to laser core
         else:
             step = ((polynomal.step[idx] | laserhead.step)
                     & ((stepper.limit == 0) | stepper.dir))
             direction = ((polynomal.dir[idx] & polynomal.busy)
                          | (laserhead.dir & laserhead.process_lines))
         m.d.comb += [stepper.step.eq(step),
                      stepper.dir.eq(direction),
                      parser.pinstate[idx].eq(stepper.limit)]
     m.d.comb += (parser.pinstate[len(steppers):].
                  eq(Cat(laserhead.photodiode_t, laserhead.synchronized)))
     # Busy signal
     m.d.comb += busy.eq(polynomal.busy | laserhead.process_lines)
     # connect spi
     m.d.comb += parser.spi.connect(spi)
     with m.If((busy_d == 1) & (busy == 0)):
         for idx, position in enumerate(parser.position):
             m.d.sync += position.eq(position+polynomal.totalsteps[idx])
     # pins you can write to
     pins = Cat(lasers, enable_prism, laserhead.synchronize)
     with m.FSM(reset='RESET', name='dispatcher'):
         with m.State('RESET'):
             m.next = 'WAIT_INSTRUCTION'
             m.d.sync += pins.eq(0)
         with m.State('WAIT_INSTRUCTION'):
             m.d.sync += [self.read_commit.eq(0), polynomal.start.eq(0)]
             with m.If((self.empty == 0) & parser.execute & (busy == 0)):
                 m.d.sync += self.read_en.eq(1)
                 m.next = 'PARSEHEAD'
         # check which instruction we r handling
         with m.State('PARSEHEAD'):
             byte0 = self.read_data[:8]
             m.d.sync += self.read_en.eq(0)
             with m.If(byte0 == INSTRUCTIONS.MOVE):
                 m.d.sync += [polynomal.ticklimit.eq(self.read_data[8:]),
                              coeffcnt.eq(0)]
                 m.next = 'MOVE_POLYNOMAL'
             with m.Elif(byte0 == INSTRUCTIONS.WRITEPIN):
                 m.d.sync += [pins.eq(self.read_data[8:]),
                              self.read_commit.eq(1)]
                 m.next = 'WAIT'
             with m.Elif((byte0 == INSTRUCTIONS.SCANLINE) |
                         (byte0 == INSTRUCTIONS.LASTSCANLINE)):
                 m.d.sync += [self.read_discard.eq(1),
                              laserhead.synchronize.eq(1),
                              laserhead.expose_start.eq(1)]
                 m.next = 'SCANLINE'
             with m.Else():
                 m.next = 'ERROR'
                 m.d.sync += parser.dispatcherror.eq(1)
         with m.State('MOVE_POLYNOMAL'):
             with m.If(coeffcnt < len(polynomal.coeff)):
                 with m.If(self.read_en == 0):
                     m.d.sync += self.read_en.eq(1)
                 with m.Else():
                     m.d.sync += [polynomal.coeff[coeffcnt].eq(
                                  self.read_data),
                                  coeffcnt.eq(coeffcnt+1),
                                  self.read_en.eq(0)]
             with m.Else():
                 m.next = 'WAIT'
                 m.d.sync += [polynomal.start.eq(1),
                              self.read_commit.eq(1)]
         with m.State('SCANLINE'):
             m.d.sync += [self.read_discard.eq(0),
                          laserhead.expose_start.eq(0)]
             m.next = 'WAIT'
         # NOTE: you need to wait for busy to be raised
         #       in time
         with m.State('WAIT'):
             m.d.sync += polynomal.start.eq(0)
             m.next = 'WAIT_INSTRUCTION'
         # NOTE: system never recovers user must reset
         with m.State('ERROR'):
             m.next = 'ERROR'
     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
Exemplo n.º 14
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").i)

        # Create our SPI-connected registers.
        m.submodules.spi_registers = spi_registers = SPIRegisterInterface(7, 8)
        m.d.comb += spi_registers.spi.connect(board_spi)

        # Create our UTMI translator.
        ulpi = platform.request(platform.default_usb_connection)
        m.submodules.utmi = utmi = UTMITranslator(ulpi=ulpi)

        # Strap our power controls to be in VBUS passthrough by default,
        # on the target port.
        m.d.comb += [
            platform.request("power_a_port").o.eq(0),
            platform.request("pass_through_vbus").o.eq(1),
        ]

        # Hook up our LEDs to status signals.
        m.d.comb += [
            platform.request("led", 2).o.eq(utmi.session_valid),
            platform.request("led", 3).o.eq(utmi.rx_active),
            platform.request("led", 4).o.eq(utmi.rx_error)
        ]

        # Set up our parameters.
        m.d.comb += [

            # Set our mode to non-driving and full speed.
            utmi.op_mode.eq(0b01),
            utmi.xcvr_select.eq(0b01),

            # Disable the DP/DM pull resistors.
            utmi.dm_pulldown.eq(0),
            utmi.dm_pulldown.eq(0),
            utmi.term_select.eq(0)
        ]

        read_strobe = Signal()

        # Create a USB analyzer, and connect a register up to its output.
        m.submodules.analyzer = analyzer = USBAnalyzer(utmi_interface=utmi)

        # Provide registers that indicate when there's data ready, and what the result is.
        spi_registers.add_read_only_register(DATA_AVAILABLE,
                                             read=analyzer.data_available)
        spi_registers.add_read_only_register(ANALYZER_RESULT,
                                             read=analyzer.data_out,
                                             read_strobe=read_strobe)

        m.d.comb += [
            platform.request("led", 0).o.eq(analyzer.capturing),
            platform.request("led", 1).o.eq(analyzer.data_available),
            platform.request("led", 5).o.eq(analyzer.overrun),
            analyzer.next.eq(read_strobe)
        ]

        # Debug output.
        m.d.comb += [
            platform.request("user_io", 0, dir="o").eq(ClockSignal("usb")),
            platform.request("user_io", 1, dir="o").eq(ulpi.dir),
            platform.request("user_io", 2, dir="o").eq(ulpi.nxt),
            platform.request("user_io", 3, dir="o").eq(analyzer.sampling),
        ]

        # Return our elaborated module.
        return m
Exemplo n.º 15
0
    def elaborate(self, platform):
        m = Module()
        # Parser
        parser = SPIParser(self.platform)
        m.submodules.parser = parser
        # Busy used to detect move or scanline in action
        # disabled "dispatching"
        busy = Signal()
        # Polynomal Move
        polynomal = Polynomal(self.platform)
        m.submodules.polynomal = polynomal
        if platform:
            board_spi = platform.request("debug_spi")
            spi = synchronize(m, board_spi)
            laserheadpins = platform.request("laserscanner")
            steppers = [res for res in get_all_resources(platform, "stepper")]
            bldc = platform.request("bldc")
            leds = [res.o for res in get_all_resources(platform, "led")]
            assert len(steppers) != 0
        else:
            platform = self.platform
            self.spi = SPIBus()
            self.parser = parser
            self.pol = polynomal
            spi = synchronize(m, self.spi)
            self.laserheadpins = platform.laserhead
            self.steppers = steppers = platform.steppers
            self.busy = busy
            laserheadpins = platform.laserhead
            bldc = platform.bldc
            leds = platform.leds
        # Local laser signal clones
        enable_prism = Signal()
        lasers = Signal(2)
        # Laserscan Head
        if self.simdiode:
            laserhead = DiodeSimulator(platform=platform, addfifo=False)
            lh = laserhead
            m.d.comb += [
                lh.enable_prism_in.eq(enable_prism | lh.enable_prism),
                lh.laser0in.eq(lasers[0]
                               | lh.lasers[0]),
                laserhead.laser1in.eq(lasers[1]
                                      | lh.lasers[1])
            ]
        else:
            laserhead = Laserhead(platform=platform)
            m.d.comb += laserhead.photodiode.eq(laserheadpins.photodiode)
        m.submodules.laserhead = laserhead
        if platform.name == 'Test':
            self.laserhead = laserhead
        # polynomal iterates over count
        coeffcnt = Signal(range(len(polynomal.coeff) + 1))
        # Prism motor
        prism_driver = Driver(platform)
        m.submodules.prism_driver = prism_driver
        # connect prism motor
        for idx in range(len(leds)):
            m.d.comb += leds[idx].eq(prism_driver.leds[idx])

        m.d.comb += prism_driver.enable_prism.eq(enable_prism)
        m.d.comb += [
            bldc.uL.eq(prism_driver.uL),
            bldc.uH.eq(prism_driver.uH),
            bldc.vL.eq(prism_driver.vL),
            bldc.vH.eq(prism_driver.vH),
            bldc.wL.eq(prism_driver.wL),
            bldc.wH.eq(prism_driver.wH)
        ]
        m.d.comb += [
            prism_driver.hall[0].eq(bldc.sensor0),
            prism_driver.hall[1].eq(bldc.sensor1),
            prism_driver.hall[2].eq(bldc.sensor2)
        ]
        # connect laserhead
        m.d.comb += [
            # TODO: fix removal
            # laserheadpins.pwm.eq(laserhead.pwm),
            # laserheadpins.en.eq(laserhead.enable_prism | enable_prism),
            laserheadpins.laser0.eq(laserhead.lasers[0] | lasers[0]),
            laserheadpins.laser1.eq(laserhead.lasers[1] | lasers[1]),
        ]
        # connect Parser
        m.d.comb += [
            self.read_data.eq(parser.read_data),
            laserhead.read_data.eq(parser.read_data),
            laserhead.empty.eq(parser.empty),
            self.empty.eq(parser.empty),
            parser.read_commit.eq(self.read_commit | laserhead.read_commit),
            parser.read_en.eq(self.read_en | laserhead.read_en),
            parser.read_discard.eq(self.read_discard | laserhead.read_discard)
        ]
        # connect motors
        for idx, stepper in enumerate(steppers):
            step = (polynomal.step[idx] & ((stepper.limit == 0) | stepper.dir))
            if idx != (list(platform.stepspermm.keys()).index(
                    platform.laser_axis)):
                direction = polynomal.dir[idx]
                m.d.comb += [
                    stepper.step.eq(step),
                    stepper.dir.eq(direction),
                    parser.pinstate[idx].eq(stepper.limit)
                ]
            # connect the motor in which the laserhead moves to laser core
            else:
                m.d.comb += [
                    parser.pinstate[idx].eq(stepper.limit),
                    stepper.step.eq((step & (~laserhead.process_lines))
                                    | (laserhead.step
                                       & (laserhead.process_lines))),
                    stepper.dir.eq(
                        (polynomal.dir[idx] & (~laserhead.process_lines))
                        | (laserhead.dir & (laserhead.process_lines)))
                ]
        m.d.comb += (parser.pinstate[len(steppers):].eq(
            Cat(laserhead.photodiode_t, laserhead.synchronized)))

        # update position
        stepper_d = Array(Signal() for _ in range(len(steppers)))
        for idx, stepper in enumerate(steppers):
            pos = parser.position[idx]
            m.d.sync += stepper_d[idx].eq(stepper.step)
            with m.If(stepper.limit == 1):
                m.d.sync += parser.position[idx].eq(0)
            # assuming position is signed
            # TODO: this might eat LUT, optimize
            pos_max = pow(2, pos.width - 1) - 2
            with m.Elif((pos > pos_max) | (pos < -pos_max)):
                m.d.sync += parser.position[idx].eq(0)
            with m.Elif((stepper.step == 1) & (stepper_d[idx] == 0)):
                with m.If(stepper.dir):
                    m.d.sync += pos.eq(pos + 1)
                with m.Else():
                    m.d.sync += pos.eq(pos - 1)

        # Busy signal
        m.d.comb += busy.eq(polynomal.busy | laserhead.process_lines)
        # connect spi
        m.d.comb += parser.spi.connect(spi)
        # pins you can write to
        pins = Cat(lasers, enable_prism, laserhead.synchronize)
        with m.FSM(reset='RESET', name='dispatcher'):
            with m.State('RESET'):
                m.next = 'WAIT_INSTRUCTION'
                m.d.sync += pins.eq(0)
            with m.State('WAIT_INSTRUCTION'):
                m.d.sync += [self.read_commit.eq(0), polynomal.start.eq(0)]
                with m.If((self.empty == 0) & parser.parse & (busy == 0)):
                    m.d.sync += self.read_en.eq(1)
                    m.next = 'PARSEHEAD'
            # check which instruction we r handling
            with m.State('PARSEHEAD'):
                byte0 = self.read_data[:8]
                m.d.sync += self.read_en.eq(0)
                with m.If(byte0 == INSTRUCTIONS.MOVE):
                    m.d.sync += [
                        polynomal.ticklimit.eq(self.read_data[8:]),
                        coeffcnt.eq(0)
                    ]
                    m.next = 'MOVE_POLYNOMAL'
                with m.Elif(byte0 == INSTRUCTIONS.WRITEPIN):
                    m.d.sync += [
                        pins.eq(self.read_data[8:]),
                        self.read_commit.eq(1)
                    ]
                    m.next = 'WAIT'
                with m.Elif((byte0 == INSTRUCTIONS.SCANLINE)
                            | (byte0 == INSTRUCTIONS.LASTSCANLINE)):
                    m.d.sync += [
                        self.read_discard.eq(1),
                        laserhead.synchronize.eq(1),
                        laserhead.expose_start.eq(1)
                    ]
                    m.next = 'SCANLINE'
                with m.Else():
                    m.next = 'ERROR'
                    m.d.sync += parser.dispatcherror.eq(1)
            with m.State('MOVE_POLYNOMAL'):
                with m.If(coeffcnt < len(polynomal.coeff)):
                    with m.If(self.read_en == 0):
                        m.d.sync += self.read_en.eq(1)
                    with m.Else():
                        m.d.sync += [
                            polynomal.coeff[coeffcnt].eq(self.read_data),
                            coeffcnt.eq(coeffcnt + 1),
                            self.read_en.eq(0)
                        ]
                with m.Else():
                    m.next = 'WAIT'
                    m.d.sync += [polynomal.start.eq(1), self.read_commit.eq(1)]
            with m.State('SCANLINE'):
                m.d.sync += [
                    self.read_discard.eq(0),
                    laserhead.expose_start.eq(0)
                ]
                m.next = 'WAIT'
            # NOTE: you need to wait for busy to be raised
            #       in time
            with m.State('WAIT'):
                m.d.sync += polynomal.start.eq(0)
                m.next = 'WAIT_INSTRUCTION'
            # NOTE: system never recovers user must reset
            with m.State('ERROR'):
                m.next = 'ERROR'
        return m
Exemplo n.º 16
0
    def elaborate(self, platform):
        m = Module()
        state = Signal(3)

        def get_all_resources(name):
            resources = []
            for number in itertools.count():
                try:
                    resources.append(platform.request(name, number))
                except ResourceError:
                    break
            return resources

        if platform and self.top:
            board_spi = platform.request("debug_spi")
            spi2 = synchronize(m, board_spi)

            leds = [res.o for res in get_all_resources("led")]
            bldc = platform.request("bldc")
            m.d.comb += self.spi.connect(spi2)

            m.d.comb += [
                leds[0].eq(bldc.sensor0), leds[1].eq(bldc.sensor1),
                leds[2].eq(bldc.sensor2)
            ]
            # tested by trying out all possibilities
            m.d.sync += state.eq(Cat(bldc.sensor0, bldc.sensor1, bldc.sensor2))
        else:
            platform = self.platform
            bldc = platform.bldc

        target = 200000
        max_measurement = target * 10
        measurement = Signal(range(max_measurement))
        timer = Signal().like(measurement)
        statefilter = Signal(3)
        stateold = Signal(3)
        max_delay = 1000
        delay = Signal(range(max_delay))

        # Statefilter
        with m.If((state >= 1) & (state <= 6)):
            m.d.sync += statefilter.eq(state)

        m.d.sync += stateold.eq(statefilter)

        # PID controller
        step = max_delay // 100
        with m.If((measurement > target) & (delay >= step)):
            m.d.sync += delay.eq(delay - step)
        with m.Elif((measurement < target) & (delay < (max_delay - step))):
            m.d.sync += delay.eq(delay + step)
        with m.Else():
            m.d.sync += delay.eq(0)

        # Measure Cycle
        with m.If(timer >= max_measurement - 1):
            m.d.sync += [timer.eq(0), measurement.eq(timer)]
        with m.Elif((statefilter == 1) & (stateold != 1)):
            m.d.sync += [measurement.eq(timer), timer.eq(0)]
        with m.Else():
            m.d.sync += timer.eq(timer + 1)

        spi = self.spi
        interf = SPICommandInterface(command_size=1 * 8, word_size=4 * 8)
        m.d.comb += interf.spi.connect(spi)
        m.submodules.interf = interf
        m.d.sync += interf.word_to_send.eq(measurement)

        off = Signal()
        duty = Signal(range(max_delay))

        # Duty timer
        with m.If(duty < max_delay):
            m.d.sync += duty.eq(0)
        with m.Else():
            m.d.sync += duty.eq(duty + 1)

        # Motor On / Off
        with m.If(duty < delay):
            m.d.sync += off.eq(1)
        with m.Else():
            m.d.sync += off.eq(0)

        # https://www.mathworks.com/help/mcb/ref/sixstepcommutation.html
        with m.If(off):
            m.d.comb += [
                bldc.uL.eq(0),
                bldc.uH.eq(0),
                bldc.vL.eq(0),
                bldc.vH.eq(0),
                bldc.wL.eq(0),
                bldc.wH.eq(0)
            ]
        with m.Elif(statefilter == 1):  # V --> W, 001
            m.d.comb += [
                bldc.uL.eq(0),
                bldc.uH.eq(0),
                bldc.vL.eq(0),
                bldc.vH.eq(1),
                bldc.wL.eq(1),
                bldc.wH.eq(0)
            ]
        with m.Elif(statefilter == 3):  # V --> U, 011
            m.d.comb += [
                bldc.uL.eq(1),
                bldc.uH.eq(0),
                bldc.vL.eq(0),
                bldc.vH.eq(1),
                bldc.wL.eq(0),
                bldc.wH.eq(0)
            ]
        with m.Elif(statefilter == 2):  # W --> U, 010
            m.d.comb += [
                bldc.uL.eq(1),
                bldc.uH.eq(0),
                bldc.vL.eq(0),
                bldc.vH.eq(0),
                bldc.wL.eq(0),
                bldc.wH.eq(1)
            ]
        with m.Elif(statefilter == 6):  # W --> V, 110
            m.d.comb += [
                bldc.uL.eq(0),
                bldc.uH.eq(0),
                bldc.vL.eq(1),
                bldc.vH.eq(0),
                bldc.wL.eq(0),
                bldc.wH.eq(1)
            ]
        with m.Elif(statefilter == 4):  # U --> V, 100
            m.d.comb += [
                bldc.uL.eq(0),
                bldc.uH.eq(1),
                bldc.vL.eq(1),
                bldc.vH.eq(0),
                bldc.wL.eq(0),
                bldc.wH.eq(0)
            ]
        with m.Elif(statefilter == 5):  # U --> W, 101
            m.d.comb += [
                bldc.uL.eq(0),
                bldc.uH.eq(1),
                bldc.vL.eq(0),
                bldc.vH.eq(0),
                bldc.wL.eq(1),
                bldc.wH.eq(0)
            ]
        # with m.Else():         # disabled
        #     m.d.comb += [bldc.uL.eq(0),
        #                  bldc.uH.eq(0),
        #                  bldc.vL.eq(0),
        #                  bldc.vH.eq(0),
        #                  bldc.wL.eq(0),
        #                  bldc.wH.eq(0)]
        return m