예제 #1
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
예제 #2
0
    def elaborate(self, platform):
        m = Module()

        # Generate our domain clocks/resets.
        m.submodules.car = platform.clock_domain_generator()

        # Create our USB device interface...
        ulpi = platform.request("target_phy")
        m.submodules.usb = usb = USBDevice(bus=ulpi)

        # Add our standard control endpoint to the device.
        descriptors = self.create_descriptors()
        usb.add_standard_control_endpoint(descriptors)

        # Add a stream endpoint to our device.
        stream_ep = USBStreamOutEndpoint(
            endpoint_number=self.BULK_ENDPOINT_NUMBER,
            max_packet_size=self.MAX_BULK_PACKET_SIZE,
            buffer_size=self.MAX_BULK_PACKET_SIZE)
        usb.add_endpoint(stream_ep)

        leds = Cat(platform.request("led", i) for i in range(6))
        user_io = Cat(
            platform.request("user_io", i, dir="o") for i in range(4))

        # Always stream our USB data directly onto our User I/O and LEDS.
        with m.If(stream_ep.stream.valid):
            m.d.usb += [
                leds.eq(stream_ep.stream.payload),
                user_io.eq(stream_ep.stream.payload),
            ]

        # Always accept data as it comes in.
        m.d.comb += stream_ep.stream.ready.eq(1)

        # Connect our device as a high speed device by default.
        m.d.comb += [
            usb.connect.eq(1),
            usb.full_speed_only.eq(1 if os.getenv('LUNA_FULL_ONLY') else 0),
        ]

        return m
예제 #3
0
파일: bios_example.py 프로젝트: ymz000/luna
    def elaborate(self, platform):
        m = Module()
        m.submodules.bridge = self._bridge

        # Grab our LEDS...
        leds = Cat(platform.request("led", i) for i in range(6))

        # ... and update them on each register write.
        with m.If(self._output.w_stb):
            m.d.sync += leds.eq(self._output.w_data)

        return m
예제 #4
0
    def elaborate(self, platform):
        m = Module()

        interface         = self.interface
        setup             = self.interface.setup

        # Grab a reference to the board's LEDs.
        leds  = Cat(platform.request("led", i) for i in range(6))

        #
        # Vendor request handlers.
        #
        with m.If(setup.type == USBRequestType.VENDOR):
            with m.Switch(setup.request):

                # SET_LEDS request handler: handler that sets the board's LEDS
                # to a user provided value
                with m.Case(self.REQUEST_SET_LEDS):

                    # If we have an active data byte, splat it onto the LEDs.
                    #
                    # For simplicity of this example, we'll accept any byte in
                    # the packet; and not just the first one; each byte will
                    # cause an update. This is fun; we can PWM the LEDs with
                    # USB packets. :)
                    with m.If(interface.rx.valid & interface.rx.next):
                        m.d.usb += leds.eq(interface.rx.payload)

                    # Once the receive is complete, respond with an ACK.
                    with m.If(interface.rx_ready_for_response):
                        m.d.comb += interface.handshakes_out.ack.eq(1)

                    # If we reach the status stage, send a ZLP.
                    with m.If(interface.status_requested):
                        m.d.comb += self.send_zlp()


                with m.Case():

                    #
                    # Stall unhandled requests.
                    #
                    with m.If(interface.status_requested | interface.data_requested):
                        m.d.comb += interface.handshakes_out.stall.eq(1)

                return m
예제 #5
0
    def elaborate(self, platform):
        m = Module()
        uart = platform.request("uart")

        clock_freq = int(60e6)
        char_freq  = int(6e6)

        # Create our UART transmitter.
        transmitter = UARTTransmitter(divisor=int(clock_freq // 115200))
        m.submodules.transmitter = transmitter
        stream = transmitter.stream

        # Create a counter that will let us transmit ten times per second.
        counter = Signal(range(0, char_freq))
        with m.If(counter == (char_freq - 1)):
            m.d.sync += counter.eq(0)
        with m.Else():
            m.d.sync += counter.eq(counter + 1)

        # Create a simple ROM with a message for ourselves...
        letters = Array(ord(i) for i in "Hello, world! \r\n")

        # ... and count through it whenever we send a letter.
        current_letter = Signal(range(0, len(letters)))
        with m.If(stream.ready):
            m.d.sync += current_letter.eq(current_letter + 1)

        # Hook everything up.
        m.d.comb += [
            stream.payload  .eq(letters[current_letter]),
            stream.valid    .eq(counter == 0),

            uart.tx.o       .eq(transmitter.tx),
        ]

        # If this platform has an output-enable control on its UART, drive it iff
        # we're actively driving a transmission.
        if hasattr(uart.tx, 'oe'):
            m.d.comb += uart.tx.oe.eq(transmitter.driving),


        # Turn on a single LED, just to show something's running.
        led = Cat(platform.request('led', i) for i in range(6))
        m.d.comb += led.eq(~transmitter.tx)

        return m
    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)

        #
        # Structural connections.
        #
        sck = Signal()
        sdi = Signal()
        sdo = Signal()
        cs = Signal()

        #
        # Synchronize each of our I/O SPI signals, where necessary.
        #
        m.submodules += FFSynchronizer(board_spi.sck, sck)
        m.submodules += FFSynchronizer(board_spi.sdi, sdi)
        m.submodules += FFSynchronizer(board_spi.cs, cs)
        m.d.comb += board_spi.sdo.eq(sdo)

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

        return m
예제 #7
0
    def elaborate(self, platform):
        m = Module()

        # Generate our domain clocks/resets.
        m.submodules.car = LunaECP5DomainGenerator()

        # Create our USB device interface...
        ulpi = platform.request("target_phy")
        m.submodules.usb = usb = USBDevice(bus=ulpi)

        # Connect our device by default.
        m.d.comb += usb.connect.eq(1)

        # ... and for now, attach our LEDs to our most recent control request.
        leds = Cat(platform.request("led", i) for i in range(6))
        m.d.comb += leds.eq(usb.last_request)

        return m
예제 #8
0
    def elaborate(self, platform):
        m = Module()
        uart = platform.request("uart")

        clock_freq = int(60e6)
        char_freq = int(6e6)

        # Create our UART transmitter.
        transmitter = UARTTransmitter(divisor=int(clock_freq // 115200))
        m.submodules.transmitter = transmitter

        # Create a counter that will let us transmit ten times per second.
        counter = Signal(range(0, char_freq))
        with m.If(counter == (char_freq - 1)):
            m.d.sync += counter.eq(0)
        with m.Else():
            m.d.sync += counter.eq(counter + 1)

        # Create a simple ROM with a message for ourselves...
        letters = Array(ord(i) for i in "Hello, world! \r\n")

        # ... and count through it whenever we send a letter.
        current_letter = Signal(range(0, len(letters)))
        with m.If(transmitter.accepted):
            m.d.sync += current_letter.eq(current_letter + 1)

        # Hook everything up.
        m.d.comb += [
            transmitter.data.eq(letters[current_letter]),
            transmitter.send.eq(counter == 0),
            uart.tx.eq(transmitter.tx)
        ]

        # Turn on a single LED, just to show something's running.
        led = Cat(platform.request('led', i) for i in range(6))
        m.d.comb += led.eq(~transmitter.tx)

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

        clk_60MHz = platform.request(platform.default_clk)

        # Drive the sync clock domain with our main clock.
        m.domains.sync = ClockDomain()
        m.d.comb += ClockSignal().eq(clk_60MHz)

        # 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_ddr = 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_ddr[i]), user_io_in[i].eq(pin.i),
                pin.o.eq(user_io_out[i])
            ]

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

        #
        # 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.
        #
        sck = Signal()
        sdi = Signal()
        cs = Signal()
        gateware_sdo = Signal()

        #
        # Synchronize each of our I/O SPI signals, where necessary.
        #
        m.submodules += FFSynchronizer(board_spi.sck, sck)
        m.submodules += FFSynchronizer(board_spi.sdi, sdi)
        m.submodules += FFSynchronizer(board_spi.cs, cs)

        # Select the passthrough or gateware SPI based on our chip-select values.
        with m.If(spi_registers.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.sck.eq(sck),
            spi_registers.sdi.eq(sdi),
            gateware_sdo.eq(spi_registers.sdo),
            spi_registers.cs.eq(cs)
        ]

        return m
예제 #10
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)
        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
예제 #11
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
예제 #12
0
파일: alu8.py 프로젝트: typingArtist/n6800
    def elaborate(self, platform: Platform) -> Module:
        m = Module()

        m.d.comb += self._ccs.eq(self.ccs)
        m.d.ph1 += self.ccs.eq(self._ccs)

        # intermediates
        carry4 = Signal()
        carry7 = Signal()
        carry8 = Signal()
        overflow = Signal()

        with m.Switch(self.func):
            with m.Case(ALU8Func.LD):
                m.d.comb += self.output.eq(self.input2)
                m.d.comb += self._ccs[Flags.Z].eq(self.output == 0)
                m.d.comb += self._ccs[Flags.N].eq(self.output[7])
                m.d.comb += self._ccs[Flags.V].eq(0)

            with m.Case(ALU8Func.LDCHAIN):
                m.d.comb += self.output.eq(self.input2)
                m.d.comb += self._ccs[Flags.Z].eq((self.output == 0)
                                                  & self.ccs[Flags.Z])
                m.d.comb += self._ccs[Flags.V].eq(0)

            with m.Case(ALU8Func.ADD, ALU8Func.ADC):
                no_carry = (self.func == ALU8Func.ADD)
                carry_in = Mux(no_carry, 0, self.ccs[Flags.C])

                sum0_3 = Cat(self.output[:4], carry4)
                m.d.comb += sum0_3.eq(self.input1[:4] + self.input2[:4] +
                                      carry_in)
                sum4_6 = Cat(self.output[4:7], carry7)
                m.d.comb += sum4_6.eq(self.input1[4:7] + self.input2[4:7] +
                                      carry4)
                sum7 = Cat(self.output[7], carry8)
                m.d.comb += sum7.eq(self.input1[7] + self.input2[7] + carry7)
                m.d.comb += overflow.eq(carry7 ^ carry8)

                m.d.comb += self._ccs[Flags.H].eq(carry4)
                m.d.comb += self._ccs[Flags.N].eq(self.output[7])
                m.d.comb += self._ccs[Flags.Z].eq(self.output == 0)
                m.d.comb += self._ccs[Flags.V].eq(overflow)
                m.d.comb += self._ccs[Flags.C].eq(carry8)

            with m.Case(ALU8Func.SUB, ALU8Func.SBC, ALU8Func.CPXHI,
                        ALU8Func.CPXLO):
                carry_in = Mux(self.func != ALU8Func.SBC, 0, self.ccs[Flags.C])

                sum0_6 = Cat(self.output[:7], carry7)
                m.d.comb += sum0_6.eq(self.input1[:7] + ~self.input2[:7] +
                                      ~carry_in)
                sum7 = Cat(self.output[7], carry8)
                m.d.comb += sum7.eq(self.input1[7] + ~self.input2[7] + carry7)
                m.d.comb += overflow.eq(carry7 ^ carry8)

                with m.If(self.func != ALU8Func.CPXLO):
                    m.d.comb += self._ccs[Flags.N].eq(self.output[7])
                    m.d.comb += self._ccs[Flags.Z].eq(self.output == 0)
                    m.d.comb += self._ccs[Flags.V].eq(overflow)
                    with m.If(self.func != ALU8Func.CPXHI):
                        m.d.comb += self._ccs[Flags.C].eq(~carry8)
                with m.Else():
                    m.d.comb += self._ccs[Flags.Z].eq((self.output == 0)
                                                      & self.ccs[Flags.Z])

            with m.Case(ALU8Func.AND):
                m.d.comb += self.output.eq(self.input1 & self.input2)
                m.d.comb += self._ccs[Flags.Z].eq(self.output == 0)
                m.d.comb += self._ccs[Flags.N].eq(self.output[7])
                m.d.comb += self._ccs[Flags.V].eq(0)

            with m.Case(ALU8Func.EOR):
                m.d.comb += self.output.eq(self.input1 ^ self.input2)
                m.d.comb += self._ccs[Flags.Z].eq(self.output == 0)
                m.d.comb += self._ccs[Flags.N].eq(self.output[7])
                m.d.comb += self._ccs[Flags.V].eq(0)

            with m.Case(ALU8Func.ORA):
                m.d.comb += self.output.eq(self.input1 | self.input2)
                m.d.comb += self._ccs[Flags.Z].eq(self.output == 0)
                m.d.comb += self._ccs[Flags.N].eq(self.output[7])
                m.d.comb += self._ccs[Flags.V].eq(0)

            with m.Case(ALU8Func.INC):
                m.d.comb += self.output.eq(self.input2 + 1)
                m.d.comb += self._ccs[Flags.Z].eq(self.output == 0)
                m.d.comb += self._ccs[Flags.N].eq(self.output[7])
                m.d.comb += self._ccs[Flags.V].eq(self.output == 0x80)

            with m.Case(ALU8Func.DEC):
                m.d.comb += self.output.eq(self.input2 - 1)
                m.d.comb += self._ccs[Flags.Z].eq(self.output == 0)
                m.d.comb += self._ccs[Flags.N].eq(self.output[7])
                m.d.comb += self._ccs[Flags.V].eq(self.output == 0x7F)

            with m.Case(ALU8Func.COM):
                m.d.comb += self.output.eq(0xFF ^ self.input2)
                m.d.comb += self._ccs[Flags.Z].eq(self.output == 0)
                m.d.comb += self._ccs[Flags.N].eq(self.output[7])
                m.d.comb += self._ccs[Flags.V].eq(0)
                m.d.comb += self._ccs[Flags.C].eq(1)

            with m.Case(ALU8Func.ROL):
                # IIIIIIIIC ->
                # COOOOOOOO
                m.d.comb += [
                    LCat(self._ccs[Flags.C],
                         self.output).eq(LCat(self.input2, self.ccs[Flags.C])),
                    self._ccs[Flags.Z].eq(self.output == 0),
                    self._ccs[Flags.N].eq(self.output[7]),
                    self._ccs[Flags.V].eq(self._ccs[Flags.N]
                                          ^ self._ccs[Flags.C]),
                ]

            with m.Case(ALU8Func.ROR):
                # CIIIIIIII ->
                # OOOOOOOOC
                m.d.comb += [
                    LCat(self.output, self._ccs[Flags.C]).eq(
                        LCat(self.ccs[Flags.C], self.input2)),
                    self._ccs[Flags.Z].eq(self.output == 0),
                    self._ccs[Flags.N].eq(self.output[7]),
                    self._ccs[Flags.V].eq(self._ccs[Flags.N]
                                          ^ self._ccs[Flags.C]),
                ]

            with m.Case(ALU8Func.ASL):
                # IIIIIIII0 ->
                # COOOOOOOO
                m.d.comb += [
                    LCat(self._ccs[Flags.C],
                         self.output).eq(LCat(self.input2, Const(0))),
                    self._ccs[Flags.Z].eq(self.output == 0),
                    self._ccs[Flags.N].eq(self.output[7]),
                    self._ccs[Flags.V].eq(self._ccs[Flags.N]
                                          ^ self._ccs[Flags.C]),
                ]

            with m.Case(ALU8Func.ASR):
                # 7IIIIIIII ->  ("7" is the repeat of input[7])
                # OOOOOOOOC
                m.d.comb += [
                    LCat(self.output, self._ccs[Flags.C]).eq(
                        LCat(self.input2[7], self.input2)),
                    self._ccs[Flags.Z].eq(self.output == 0),
                    self._ccs[Flags.N].eq(self.output[7]),
                    self._ccs[Flags.V].eq(self._ccs[Flags.N]
                                          ^ self._ccs[Flags.C]),
                ]

            with m.Case(ALU8Func.LSR):
                # 0IIIIIIII ->
                # OOOOOOOOC
                m.d.comb += [
                    LCat(self.output,
                         self._ccs[Flags.C]).eq(LCat(Const(0), self.input2)),
                    self._ccs[Flags.Z].eq(self.output == 0),
                    self._ccs[Flags.N].eq(self.output[7]),
                    self._ccs[Flags.V].eq(self._ccs[Flags.N]
                                          ^ self._ccs[Flags.C]),
                ]

            with m.Case(ALU8Func.CLC):
                m.d.comb += self._ccs[Flags.C].eq(0)

            with m.Case(ALU8Func.SEC):
                m.d.comb += self._ccs[Flags.C].eq(1)

            with m.Case(ALU8Func.CLV):
                m.d.comb += self._ccs[Flags.V].eq(0)

            with m.Case(ALU8Func.SEV):
                m.d.comb += self._ccs[Flags.V].eq(1)

            with m.Case(ALU8Func.CLI):
                m.d.comb += self._ccs[Flags.I].eq(0)

            with m.Case(ALU8Func.SEI):
                m.d.comb += self._ccs[Flags.I].eq(1)

            with m.Case(ALU8Func.CLZ):
                m.d.comb += self._ccs[Flags.Z].eq(0)

            with m.Case(ALU8Func.SEZ):
                m.d.comb += self._ccs[Flags.Z].eq(1)

            with m.Case(ALU8Func.TAP):
                m.d.comb += self._ccs.eq(self.input1 | 0b11000000)

            with m.Case(ALU8Func.TPA):
                m.d.comb += self.output.eq(self.ccs | 0b11000000)

            with m.Case(ALU8Func.SEF):
                m.d.comb += self._ccs.eq(self.input1 | 0b11000000)

            with m.Case(ALU8Func.DAA):
                adjust = Signal(8)
                low = self.input1[:4]
                high = self.input1[4:]
                low_ten_or_more = low >= 0xA
                high_ten_or_more = high >= 0xA

                with m.If(low_ten_or_more | self.ccs[Flags.H]):
                    m.d.comb += adjust[:4].eq(6)
                with m.If(high_ten_or_more
                          | self.ccs[Flags.C]
                          | (low_ten_or_more & (high == 9))):
                    m.d.comb += adjust[4:].eq(6)
                sum9 = LCat(carry8, self.output)

                m.d.comb += sum9.eq(self.input1 + adjust)
                m.d.comb += self._ccs[Flags.N].eq(self.output[7])
                m.d.comb += self._ccs[Flags.Z].eq(self.output == 0)
                m.d.comb += self._ccs[Flags.C].eq(carry8 | self.ccs[Flags.C])

            with m.Default():
                m.d.comb += self.output.eq(self.input1)

        return m
예제 #13
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
예제 #14
0
파일: alu8.py 프로젝트: GuzTech/n6800
    def elaborate(self, platform: Platform) -> Module:
        m = Module()

        m.d.comb += self._ccs.eq(self.ccs)
        m.d.ph1 += self.ccs.eq(self._ccs)

        # intermediates
        carry4 = Signal()
        carry7 = Signal()
        carry8 = Signal()
        overflow = Signal()

        with m.Switch(self.func):
            with m.Case(ALU8Func.LD):
                m.d.comb += self.output.eq(self.input2)
                m.d.comb += self._ccs[_Z].eq(self.output == 0)
                m.d.comb += self._ccs[_N].eq(self.output[7])
                m.d.comb += self._ccs[_V].eq(0)

            with m.Case(ALU8Func.ADD, ALU8Func.ADC):
                carry_in = Mux(self.func == ALU8Func.ADD, 0, self.ccs[_C])

                sum0_3 = Cat(self.output[:4], carry4)
                m.d.comb += sum0_3.eq(self.input1[:4] + self.input2[:4] +
                                      carry_in)
                sum4_6 = Cat(self.output[4:7], carry7)
                m.d.comb += sum4_6.eq(self.input1[4:7] + self.input2[4:7] +
                                      carry4)
                sum7 = Cat(self.output[7], carry8)
                m.d.comb += sum7.eq(self.input1[7] + self.input2[7] + carry7)
                m.d.comb += overflow.eq(carry7 ^ carry8)
                m.d.comb += self._ccs[_H].eq(carry4)
                m.d.comb += self._ccs[_N].eq(self.output[7])
                m.d.comb += self._ccs[_Z].eq(self.output == 0)
                m.d.comb += self._ccs[_V].eq(overflow)
                m.d.comb += self._ccs[_C].eq(carry8)

            with m.Case(ALU8Func.SUB, ALU8Func.SBC):
                carry_in = Mux(self.func == ALU8Func.SUB, 0, self.ccs[_C])

                sum0_6 = Cat(self.output[:7], carry7)
                m.d.comb += sum0_6.eq(self.input1[:7] + ~self.input2[:7] +
                                      ~carry_in)
                sum7 = Cat(self.output[7], carry8)
                m.d.comb += sum7.eq(self.input1[7] + ~self.input2[7] + carry7)
                m.d.comb += overflow.eq(carry7 ^ carry8)
                m.d.comb += self._ccs[_N].eq(self.output[7])
                m.d.comb += self._ccs[_Z].eq(self.output == 0)
                m.d.comb += self._ccs[_V].eq(overflow)
                m.d.comb += self._ccs[_C].eq(~carry8)

            with m.Case(ALU8Func.AND):
                m.d.comb += self.output.eq(self.input1 & self.input2)
                m.d.comb += self._ccs[_Z].eq(self.output == 0)
                m.d.comb += self._ccs[_N].eq(self.output[7])
                m.d.comb += self._ccs[_V].eq(0)

            with m.Case(ALU8Func.EOR):
                m.d.comb += self.output.eq(self.input1 ^ self.input2)
                m.d.comb += self._ccs[_Z].eq(self.output == 0)
                m.d.comb += self._ccs[_N].eq(self.output[7])
                m.d.comb += self._ccs[_V].eq(0)

            with m.Case(ALU8Func.ORA):
                m.d.comb += self.output.eq(self.input1 | self.input2)
                m.d.comb += self._ccs[_Z].eq(self.output == 0)
                m.d.comb += self._ccs[_N].eq(self.output[7])
                m.d.comb += self._ccs[_V].eq(0)

        return m
예제 #15
0
파일: ila.py 프로젝트: zyp/luna
    def elaborate(self, platform):
        m = Module()
        m.submodules.ila = ila = self.ila

        if self._o_domain == self.domain:
            in_domain_stream = self.stream
        else:
            in_domain_stream = StreamInterface(
                payload_width=self.bits_per_sample)

        # Count where we are in the current transmission.
        current_sample_number = Signal(range(0, ila.sample_depth))

        # Always present the current sample number to our ILA, and the current
        # sample value to the UART.
        m.d.comb += [
            ila.captured_sample_number.eq(current_sample_number),
            in_domain_stream.payload.eq(ila.captured_sample)
        ]

        with m.FSM():

            # IDLE -- we're currently waiting for a trigger before capturing samples.
            with m.State("IDLE"):

                # Always allow triggering, as we're ready for the data.
                m.d.comb += self.ila.trigger.eq(self.trigger)

                # Once we're triggered, move onto the SAMPLING state.
                with m.If(self.trigger):
                    m.next = "SAMPLING"

            # SAMPLING -- the internal ILA is sampling; we're now waiting for it to
            # complete. This state is similar to IDLE; except we block triggers in order
            # to cleanly avoid a race condition.
            with m.State("SAMPLING"):

                # Once our ILA has finished sampling, prepare to read out our samples.
                with m.If(self.ila.complete):
                    m.d.sync += [
                        current_sample_number.eq(0),
                        in_domain_stream.first.eq(1)
                    ]
                    m.next = "SENDING"

            # SENDING -- we now have a valid buffer of samples to send up to the host;
            # we'll transmit them over our stream interface.
            with m.State("SENDING"):
                m.d.comb += [
                    # While we're sending, we're always providing valid data to the UART.
                    in_domain_stream.valid.eq(1),

                    # Indicate when we're on the last sample.
                    in_domain_stream.last.eq(
                        current_sample_number == (self.sample_depth - 1))
                ]

                # Each time the UART accepts a valid word, move on to the next one.
                with m.If(in_domain_stream.ready):
                    m.d.sync += [
                        current_sample_number.eq(current_sample_number + 1),
                        in_domain_stream.first.eq(0)
                    ]

                    # If this was the last sample, we're done! Move back to idle.
                    with m.If(self.stream.last):
                        m.next = "IDLE"

        # If we're not streaming out of the same domain we're capturing from,
        # we'll add some clock-domain crossing hardware.
        if self._o_domain != self.domain:
            in_domain_signals = Cat(in_domain_stream.first,
                                    in_domain_stream.payload,
                                    in_domain_stream.last)
            out_domain_signals = Cat(self.stream.first, self.stream.payload,
                                     self.stream.last)

            # Create our async FIFO...
            m.submodules.cdc = fifo = AsyncFIFOBuffered(
                width=len(in_domain_signals),
                depth=16,
                w_domain="sync",
                r_domain=self._o_domain)

            m.d.comb += [
                # ... fill it from our in-domain stream...
                fifo.w_data.eq(in_domain_signals),
                fifo.w_en.eq(in_domain_stream.valid),
                in_domain_stream.ready.eq(fifo.w_rdy),

                # ... and output it into our outupt stream.
                out_domain_signals.eq(fifo.r_data),
                self.stream.valid.eq(fifo.r_rdy),
                fifo.r_en.eq(self.stream.ready)
            ]

        # Convert our sync domain to the domain requested by the user, if necessary.
        if self.domain != "sync":
            m = DomainRenamer({"sync": self.domain})(m)

        return m
예제 #16
0
파일: ila.py 프로젝트: zyp/luna
 def provide_all_signals(self, value):
     all_signals = Cat(self.input_a, self.input_b, self.input_c)
     yield all_signals.eq(value)
예제 #17
0
    def elaborate(self, platform: Platform) -> Module:
        m = Module()

        m.d.sync += self.PSW.eq(self._psw)
        m.d.comb += self._psw.eq(self.PSW)

        with m.Switch(self.oper):
            with m.Case(Operation.NOP):
                if self.verification is Operation.NOP:
                    with m.If(~Initial()):
                        m.d.comb += [
                            Assert(self._psw.N == self.PSW.N),
                            Assert(self._psw.V == self.PSW.V),
                            Assert(self._psw.P == self.PSW.P),
                            Assert(self._psw.B == self.PSW.B),
                            Assert(self._psw.H == self.PSW.H),
                            Assert(self._psw.I == self.PSW.I),
                            Assert(self._psw.Z == self.PSW.Z),
                            Assert(self._psw.C == self.PSW.C),
                        ]

            with m.Case(Operation.ADC):
                low = Cat(self.result[:4], self._psw.H)
                high = Cat(self.result[4:], self._psw.C)

                m.d.comb += [
                    low.eq(self.inputa[:4] + self.inputb[:4] + self.PSW.C),
                    high.eq(self.inputa[4:] + self.inputb[4:] + self._psw.H),
                    self._psw.N.eq(self.result.as_signed() < 0),
                    self._psw.Z.eq(self.result == 0),
                    self._psw.V.eq(self.result[7] != self._psw.C),
                ]
                if self.verification is Operation.ADC:
                    r = Signal(8)
                    f = Signal(9)
                    h = Signal(5)
                    m.d.comb += [
                        r.eq(self.inputa.as_signed() +
                             self.inputb.as_signed() + self.PSW.C),
                        f.eq(self.inputa + self.inputb + self.PSW.C),
                        h.eq(self.inputa[:4] + self.inputb[:4] + self.PSW.C),
                    ]
                    with m.If(~Initial()):
                        m.d.comb += [
                            Assert(self.result == r),
                            Assert(self.result == f[:8]),
                            Assert(self._psw.N == f[7]),
                            Assert(self._psw.V == (f[7] ^ f[8])),
                            Assert(self._psw.P == self.PSW.P),
                            Assert(self._psw.B == self.PSW.B),
                            Assert(self._psw.H == h[4]),
                            Assert(self._psw.I == self.PSW.I),
                            Assert(self._psw.Z == ~(f[:8].bool())),
                            Assert(self._psw.C == f[8]),
                        ]

            with m.Case(Operation.SBC):
                low = Cat(self.result[:4], self._psw.H)
                high = Cat(self.result[4:], self._psw.C)

                m.d.comb += [
                    low.eq(self.inputa[:4] - self.inputb[:4] - self.PSW.C),
                    high.eq(self.inputa[4:] - self.inputb[4:] - self._psw.H),
                    self._psw.N.eq(self.result.as_signed() < 0),
                    self._psw.Z.eq(self.result == 0),
                    self._psw.V.eq(self.result[7] != self._psw.C),
                ]
                if self.verification is Operation.SBC:
                    r = Signal(8)
                    f = Signal(9)
                    h = Signal(5)
                    m.d.comb += [
                        r.eq(self.inputa.as_signed() -
                             self.inputb.as_signed() - self.PSW.C),
                        f.eq(self.inputa - self.inputb - self.PSW.C),
                        h.eq(self.inputa[:4] - self.inputb[:4] - self.PSW.C),
                    ]
                    with m.If(~Initial()):
                        m.d.comb += [
                            Assert(self.result == r),
                            Assert(self.result == f[:8]),
                            Assert(self._psw.N == f[7]),
                            Assert(self._psw.V == (f[7] ^ f[8])),
                            Assert(self._psw.P == self.PSW.P),
                            Assert(self._psw.B == self.PSW.B),
                            Assert(self._psw.H == h[4]),
                            Assert(self._psw.I == self.PSW.I),
                            Assert(self._psw.Z == ~(f[:8].bool())),
                            Assert(self._psw.C == f[8]),
                        ]

            with m.Case(Operation.CMP):
                full = Cat(self.result, self._psw.C)

                m.d.comb += [
                    full.eq(self.inputa.as_signed() - self.inputb.as_signed()),
                    self._psw.N.eq(self.result.as_signed() < 0),
                    self._psw.Z.eq(self.result == 0),
                    self._psw.V.eq(self.result[7] != self._psw.C),
                ]
                if self.verification is Operation.CMP:
                    r = Signal(9)
                    m.d.comb += r.eq(self.inputa.as_signed() -
                                     self.inputb.as_signed())
                    with m.If(~Initial()):
                        m.d.comb += [
                            Assert(self.result == r[:8]),
                            Assert(self._psw.N == r[7]),
                            Assert(self._psw.V == (r[7] ^ r[8])),
                            Assert(self._psw.P == self.PSW.P),
                            Assert(self._psw.B == self.PSW.B),
                            Assert(self._psw.H == self.PSW.H),
                            Assert(self._psw.I == self.PSW.I),
                            Assert(self._psw.Z == ~(r[:8].bool())),
                            Assert(self._psw.C == r[8]),
                        ]

            with m.Case(Operation.AND):
                m.d.comb += [
                    self.result.eq(self.inputa & self.inputb),
                    self._psw.N.eq(self.result.as_signed() < 0),
                    self._psw.Z.eq(self.result == 0),
                ]
                if self.verification is Operation.AND:
                    r = Signal(8)
                    m.d.comb += r.eq(self.inputa & self.inputb)
                    with m.If(~Initial()):
                        m.d.comb += [
                            Assert(self.result == r),
                            Assert(self._psw.N == r[7]),
                            Assert(self._psw.V == self.PSW.V),
                            Assert(self._psw.P == self.PSW.P),
                            Assert(self._psw.B == self.PSW.B),
                            Assert(self._psw.H == self.PSW.H),
                            Assert(self._psw.I == self.PSW.I),
                            Assert(self._psw.Z == ~(r.bool())),
                            Assert(self._psw.C == self.PSW.C),
                        ]

            with m.Case(Operation.OOR):
                m.d.comb += [
                    self.result.eq(self.inputa | self.inputb),
                    self._psw.N.eq(self.result.as_signed() < 0),
                    self._psw.Z.eq(self.result == 0),
                ]
                if self.verification is Operation.OOR:
                    r = Signal(8)
                    m.d.comb += [
                        r.eq(self.inputa | self.inputb),
                    ]
                    with m.If(~Initial()):
                        m.d.comb += [
                            Assert(self.result == r),
                            Assert(self._psw.N == r[7]),
                            Assert(self._psw.V == self.PSW.V),
                            Assert(self._psw.P == self.PSW.P),
                            Assert(self._psw.B == self.PSW.B),
                            Assert(self._psw.H == self.PSW.H),
                            Assert(self._psw.I == self.PSW.I),
                            Assert(self._psw.Z == ~(r.bool())),
                            Assert(self._psw.C == self.PSW.C),
                        ]

            with m.Case(Operation.EOR):
                m.d.comb += [
                    self.result.eq(self.inputa ^ self.inputb),
                    self._psw.N.eq(self.result.as_signed() < 0),
                    self._psw.Z.eq(self.result == 0),
                ]
                if self.verification is Operation.EOR:
                    r = Signal(8)
                    m.d.comb += [
                        r.eq(self.inputa ^ self.inputb),
                    ]
                    with m.If(~Initial()):
                        m.d.comb += [
                            Assert(self.result == r),
                            Assert(self._psw.N == r[7]),
                            Assert(self._psw.V == self.PSW.V),
                            Assert(self._psw.P == self.PSW.P),
                            Assert(self._psw.B == self.PSW.B),
                            Assert(self._psw.H == self.PSW.H),
                            Assert(self._psw.I == self.PSW.I),
                            Assert(self._psw.Z == ~(r.bool())),
                            Assert(self._psw.C == self.PSW.C),
                        ]

            with m.Case(Operation.INC):
                m.d.comb += [
                    self.result.eq(self.inputa + 1),
                    self._psw.N.eq(self.result.as_signed() < 0),
                    self._psw.Z.eq(self.result == 0),
                ]
                if self.verification is Operation.INC:
                    r = Signal(8)
                    m.d.comb += [
                        r.eq(self.inputa + 1),
                    ]
                    with m.If(~Initial()):
                        m.d.comb += [
                            Assert(self.result == r),
                            Assert(self._psw.N == r[7]),
                            Assert(self._psw.V == self.PSW.V),
                            Assert(self._psw.P == self.PSW.P),
                            Assert(self._psw.B == self.PSW.B),
                            Assert(self._psw.H == self.PSW.H),
                            Assert(self._psw.I == self.PSW.I),
                            Assert(self._psw.Z == ~(r.bool())),
                            Assert(self._psw.C == self.PSW.C),
                        ]

            with m.Case(Operation.DEC):
                m.d.comb += [
                    self.result.eq(self.inputa - 1),
                    self._psw.N.eq(self.result.as_signed() < 0),
                    self._psw.Z.eq(self.result == 0),
                ]
                if self.verification is Operation.DEC:
                    r = Signal(8)
                    m.d.comb += [
                        r.eq(self.inputa - 1),
                    ]
                    with m.If(~Initial()):
                        m.d.comb += [
                            Assert(self.result == r),
                            Assert(self._psw.N == r[7]),
                            Assert(self._psw.V == self.PSW.V),
                            Assert(self._psw.P == self.PSW.P),
                            Assert(self._psw.B == self.PSW.B),
                            Assert(self._psw.H == self.PSW.H),
                            Assert(self._psw.I == self.PSW.I),
                            Assert(self._psw.Z == ~(r.bool())),
                            Assert(self._psw.C == self.PSW.C),
                        ]

            with m.Case(Operation.ASL):
                m.d.comb += [
                    Cat(self.result,
                        self._psw.C).eq(Cat(Const(0), self.inputa)),
                    self._psw.N.eq(self.result.as_signed() < 0),
                    self._psw.Z.eq(self.result == 0),
                ]
                if self.verification is Operation.ASL:
                    r = Signal(8)
                    m.d.comb += [
                        r.eq(self.inputa * 2),
                    ]
                    with m.If(~Initial()):
                        m.d.comb += [
                            Assert(self.result == r),
                            Assert(self._psw.N == self.inputa[6]),
                            Assert(self._psw.V == self.PSW.V),
                            Assert(self._psw.P == self.PSW.P),
                            Assert(self._psw.B == self.PSW.B),
                            Assert(self._psw.H == self.PSW.H),
                            Assert(self._psw.I == self.PSW.I),
                            Assert(self._psw.Z == ~(r.bool())),
                            Assert(self._psw.C == self.inputa[7]),
                        ]

            with m.Case(Operation.LSR):
                m.d.comb += [
                    Cat(self._psw.C,
                        self.result).eq(Cat(self.inputa, Const(0))),
                    self._psw.N.eq(self.result.as_signed() < 0),
                    self._psw.Z.eq(self.result == 0),
                ]
                if self.verification is Operation.LSR:
                    r = Signal(8)
                    m.d.comb += [
                        r.eq(self.inputa // 2),
                    ]
                    with m.If(~Initial()):
                        m.d.comb += [
                            Assert(self.result == r),
                            Assert(self._psw.N == 0),
                            Assert(self._psw.V == self.PSW.V),
                            Assert(self._psw.P == self.PSW.P),
                            Assert(self._psw.B == self.PSW.B),
                            Assert(self._psw.H == self.PSW.H),
                            Assert(self._psw.I == self.PSW.I),
                            Assert(self._psw.Z == ~(r.bool())),
                            Assert(self._psw.C == self.inputa[0]),
                        ]

            with m.Case(Operation.ROL):
                m.d.comb += [
                    Cat(self.result,
                        self._psw.C).eq(Cat(self.PSW.C, self.inputa)),
                    self._psw.N.eq(self.result.as_signed() < 0),
                    self._psw.Z.eq(self.result == 0),
                ]
                if self.verification is Operation.ROL:
                    r = Signal(8)
                    m.d.comb += [
                        r.eq(self.inputa * 2 + self.PSW.C),
                    ]
                    with m.If(~Initial()):
                        m.d.comb += [
                            Assert(self.result == r),
                            Assert(self._psw.N == self.inputa[6]),
                            Assert(self._psw.V == self.PSW.V),
                            Assert(self._psw.P == self.PSW.P),
                            Assert(self._psw.B == self.PSW.B),
                            Assert(self._psw.H == self.PSW.H),
                            Assert(self._psw.I == self.PSW.I),
                            Assert(self._psw.Z == ~(r.bool())),
                            Assert(self._psw.C == self.inputa[7]),
                        ]

            with m.Case(Operation.ROR):
                m.d.comb += [
                    Cat(self._psw.C,
                        self.result).eq(Cat(self.inputa, self.PSW.C)),
                    self._psw.N.eq(self.result.as_signed() < 0),
                    self._psw.Z.eq(self.result == 0),
                ]
                if self.verification is Operation.ROR:
                    r = Signal(8)
                    m.d.comb += [
                        r.eq(self.inputa // 2 + Cat(Signal(7), self.PSW.C)),
                    ]
                    with m.If(~Initial()):
                        m.d.comb += [
                            Assert(self.result == r),
                            Assert(self._psw.N == self.PSW.C),
                            Assert(self._psw.V == self.PSW.V),
                            Assert(self._psw.P == self.PSW.P),
                            Assert(self._psw.B == self.PSW.B),
                            Assert(self._psw.H == self.PSW.H),
                            Assert(self._psw.I == self.PSW.I),
                            Assert(self._psw.Z == ~(r.bool())),
                            Assert(self._psw.C == self.inputa[0]),
                        ]

            with m.Case(Operation.XCN):
                m.d.comb += [
                    self.result.eq(Cat(self.inputa[4:], self.inputa[:4])),
                    self._psw.N.eq(self.result.as_signed() < 0),
                    self._psw.Z.eq(self.result == 0),
                ]
                if self.verification is Operation.XCN:
                    r = Signal(8)
                    m.d.comb += [
                        r.eq(self.inputa * 16 + self.inputa // 16),
                    ]
                    with m.If(~Initial()):
                        m.d.comb += [
                            Assert(self.result == r),
                            Assert(self._psw.N == self.inputa[3]),
                            Assert(self._psw.V == self.PSW.V),
                            Assert(self._psw.P == self.PSW.P),
                            Assert(self._psw.B == self.PSW.B),
                            Assert(self._psw.H == self.PSW.H),
                            Assert(self._psw.I == self.PSW.I),
                            Assert(self._psw.Z == ~(self.inputa.bool())),
                            Assert(self._psw.C == self.PSW.C),
                        ]

            with m.Case(Operation.DAA):
                temp = Signal().like(self.inputa)
                with m.If(self.PSW.C | (self.inputa > 0x99)):
                    m.d.comb += self._psw.C.eq(1)
                    m.d.comb += temp.eq(self.inputa + 0x60)
                with m.Else():
                    m.d.comb += temp.eq(self.inputa)

                with m.If(self.PSW.H | (temp[:4] > 0x09)):
                    m.d.comb += self.result.eq(temp + 0x06)

                m.d.comb += [
                    self._psw.N.eq(self.result & 0x80),
                    self._psw.Z.eq(self.result == 0),
                ]
                if self.verification is Operation.DAA:
                    with m.If(~Initial()):
                        m.d.comb += [Assert(False)]

            with m.Case(Operation.DAS):
                temp = Signal().like(self.inputa)
                with m.If(~self.PSW.C | (self.inputa > 0x99)):
                    m.d.comb += self._psw.C.eq(0)
                    m.d.comb += temp.eq(self.inputa - 0x60)
                with m.Else():
                    m.d.comb += temp.eq(self.inputa)

                with m.If(~self.PSW.H | (temp[:4] > 0x09)):
                    m.d.comb += self.result.eq(temp - 0x06)

                m.d.comb += [
                    self._psw.N.eq(self.result & 0x80),
                    self._psw.Z.eq(self.result == 0),
                ]
                if self.verification is Operation.DAS:
                    with m.If(~Initial()):
                        m.d.comb += [Assert(False)]

            # could be optimized with shift to right
            with m.Case(Operation.MUL):
                with m.Switch(self.count):
                    for i in range(0, 8):
                        with m.Case(i):
                            prod = self.inputa * self.inputb[i]
                            if i == 0:
                                prod = Cat(prod[0:7], ~prod[7], Const(1))
                            elif i == 7:
                                prod = Cat(~prod[0:7], prod[7], Const(1))
                            else:
                                prod = Cat(prod[0:7], ~prod[7])
                            m.d.sync += self.partial.eq(self.partial +
                                                        (prod << i))
                            m.d.sync += self.count.eq(i + 1)
                    with m.Case(8):
                        m.d.sync += self.partial_hi.eq(self.partial_lo)
                        m.d.sync += self.count.eq(9)
                        m.d.comb += [
                            self.result.eq(self.partial_hi),
                            self._psw.N.eq(self.partial_hi.as_signed() < 0),
                            self._psw.Z.eq(self.partial_hi == 0),
                        ]
                    with m.Case(9):
                        m.d.sync += self.partial.eq(0)
                        m.d.sync += self.count.eq(0)
                        m.d.comb += [
                            self.result.eq(self.partial_hi),
                        ]
                if self.verification is Operation.MUL:
                    r = Signal(16)
                    m.d.comb += [
                        r.eq(self.inputa.as_signed() *
                             self.inputb.as_signed()),
                        Cover(self.count == 9),
                    ]
                    with m.If(self.count == 9):
                        m.d.comb += [
                            Assert(Past(self.result) == r[8:16]),
                            Assert(self.result == r[0:8]),
                            Assert(self._psw.N == r[15]),
                            Assert(self._psw.V == self.PSW.V),
                            Assert(self._psw.P == self.PSW.P),
                            Assert(self._psw.B == self.PSW.B),
                            Assert(self._psw.H == self.PSW.H),
                            Assert(self._psw.I == self.PSW.I),
                            Assert(self._psw.Z == ~(r[8:16].bool())),
                            Assert(self._psw.C == self.PSW.C),
                        ]
                    with m.If(~Initial() & (self.count == 0)):
                        m.d.comb += [
                            Assert(self.partial == 0),
                            Assert((Past(self.count) == 0)
                                   | (Past(self.count) == 9)),
                        ]
                    with m.If(~Initial() & (self.count != 0)):
                        m.d.comb += [
                            Assert(self.count == Past(self.count) + 1),
                            Assume(self.inputa == Past(self.inputa)),
                            Assume(self.inputb == Past(self.inputb)),
                        ]

            with m.Case(Operation.DIV):
                over = Signal(reset=0)
                with m.Switch(self.count):
                    with m.Case(0):
                        m.d.sync += self.partial_hi.eq(self.inputa)  # Y
                        m.d.sync += self.count.eq(1)

                    with m.Case(1):
                        m.d.sync += self.partial_lo.eq(self.inputa)  # A
                        m.d.sync += self.count.eq(2)
                        m.d.comb += self._psw.H.eq(
                            Mux(self.partial_hi[0:4] >= self.inputb[0:4], 1,
                                0))

                    for i in range(2, 11):
                        with m.Case(i):
                            tmp1_w = Cat(self.partial << 1, over)
                            tmp1_x = Signal(17)
                            tmp1_y = Signal(17)
                            tmp1_z = Signal(17)
                            tmp2 = self.inputb << 9

                            m.d.comb += tmp1_x.eq(tmp1_w)
                            with m.If(tmp1_w & 0x20000):
                                m.d.comb += tmp1_x.eq((tmp1_w & 0x1FFFF) | 1)

                            m.d.comb += tmp1_y.eq(tmp1_x)
                            with m.If(tmp1_x >= tmp2):
                                m.d.comb += tmp1_y.eq(tmp1_x ^ 1)

                            m.d.comb += tmp1_z.eq(tmp1_y)
                            with m.If(tmp1_y & 1):
                                m.d.comb += tmp1_z.eq((tmp1_y - tmp2)
                                                      & 0x1FFFF)

                            m.d.sync += Cat(self.partial, over).eq(tmp1_z)

                            m.d.sync += self.count.eq(i + 1)

                    with m.Case(11):
                        m.d.sync += self.count.eq(12)
                        m.d.comb += [
                            self.result.eq(
                                (Cat(self.partial, over) >> 9)),  # Y %
                        ]

                    with m.Case(12):
                        m.d.sync += self.partial.eq(0)
                        m.d.sync += over.eq(0)
                        m.d.sync += self.count.eq(0)
                        m.d.comb += [
                            self.result.eq(self.partial_lo),  # A /
                            self._psw.N.eq(self.partial_lo.as_signed() < 0),
                            self._psw.V.eq(over),
                            self._psw.Z.eq(self.partial_lo == 0),
                        ]

                if self.verification is Operation.DIV:
                    m.d.comb += [
                        Cover(self.count == 12),
                    ]
                    with m.If(self.count == 12):
                        m.d.comb += [Assert(False)]

        return m
예제 #18
0
파일: request.py 프로젝트: zyp/luna
    def elaborate(self, platform):
        m = Module()

        # If we're standalone, generate the things we need.
        if self.standalone:

            # Create our tokenizer...
            m.submodules.tokenizer = tokenizer = USBTokenDetector(
                utmi=self.utmi)
            m.d.comb += tokenizer.interface.connect(self.tokenizer)

            # ... and our timer.
            m.submodules.timer = timer = USBInterpacketTimer()
            timer.add_interface(self.timer)

            m.d.comb += timer.speed.eq(self.speed)

        # Create a data-packet-deserializer, which we'll use to capture the
        # contents of the setup data packets.
        m.submodules.data_handler = data_handler = \
            USBDataPacketDeserializer(utmi=self.utmi, max_packet_size=8, create_crc_generator=self.standalone)
        m.d.comb += self.data_crc.connect(data_handler.data_crc)

        # Instruct our interpacket timer to begin counting when we complete receiving
        # our setup packet. This will allow us to track interpacket delays.
        m.d.comb += self.timer.start.eq(data_handler.new_packet)

        # Keep our output signals de-asserted unless specified.
        m.d.usb += [
            self.packet.received.eq(0),
        ]

        with m.FSM(domain="usb"):

            # IDLE -- we haven't yet detected a SETUP transaction directed at us
            with m.State('IDLE'):
                pid_matches = (self.tokenizer.pid == self.SETUP_PID)

                # If we're just received a new SETUP token addressed to us,
                # the next data packet is going to be for us.
                with m.If(pid_matches & self.tokenizer.new_token):
                    m.next = 'READ_DATA'

            # READ_DATA -- we've just seen a SETUP token, and are waiting for the
            # data payload of the transaction, which contains the setup packet.
            with m.State('READ_DATA'):

                # If we receive a token packet before we receive a DATA packet,
                # this is a PID mismatch. Bail out and start over.
                with m.If(self.tokenizer.new_token):
                    m.next = 'IDLE'

                # If we have a new packet, parse it as setup data.
                with m.If(data_handler.new_packet):

                    # If we got exactly eight bytes, this is a valid setup packet.
                    with m.If(data_handler.length == 8):

                        # Collect the signals that make up our bmRequestType [USB2, 9.3].
                        request_type = Cat(self.packet.recipient,
                                           self.packet.type,
                                           self.packet.is_in_request)

                        m.d.usb += [

                            # Parse the setup data itself...
                            request_type.eq(data_handler.packet[0]),
                            self.packet.request.eq(data_handler.packet[1]),
                            self.packet.value.eq(
                                Cat(data_handler.packet[2],
                                    data_handler.packet[3])),
                            self.packet.index.eq(
                                Cat(data_handler.packet[4],
                                    data_handler.packet[5])),
                            self.packet.length.eq(
                                Cat(data_handler.packet[6],
                                    data_handler.packet[7])),

                            # ... and indicate that we have new data.
                            self.packet.received.eq(1),
                        ]

                        # We'll now need to wait a receive-transmit delay before initiating our ACK.
                        # Per the USB 2.0 and ULPI 1.1 specifications:
                        #   - A HS device needs to wait 8 HS bit periods before transmitting [USB2, 7.1.18.2].
                        #     Each ULPI cycle is 8 HS bit periods, so we'll only need to wait one cycle.
                        #   - We'll use our interpacket delay timer for everything else.
                        with m.If(self.timer.tx_allowed
                                  | (self.speed == USBSpeed.HIGH)):

                            # If we're a high speed device, we only need to wait for a single ULPI cycle.
                            # Processing delays mean we've already met our interpacket delay; and we can ACK
                            # immediately.
                            m.d.comb += self.ack.eq(1)
                            m.next = "IDLE"

                        # For other cases, handle the interpacket delay by waiting.
                        with m.Else():
                            m.next = "INTERPACKET_DELAY"

                    # Otherwise, this isn't; and we should ignore it. [USB2, 8.5.3]
                    with m.Else():
                        m.next = "IDLE"

            # INTERPACKET -- wait for an inter-packet delay before responding
            with m.State('INTERPACKET_DELAY'):

                # ... and once it equals zero, ACK and return to idle.
                with m.If(self.timer.tx_allowed):
                    m.d.comb += self.ack.eq(1)
                    m.next = "IDLE"

        return m
예제 #19
0
    def elaborate(self, platform: Platform) -> Module:
        m = Module()

        m.d.comb += self._ccs.eq(self.ccs)
        m.d.ph1 += self.ccs.eq(self._ccs)

        # intermediates
        carry4 = Signal()
        carry7 = Signal()
        carry8 = Signal()
        overflow = Signal()

        with m.Switch(self.func):
            with m.Case(ALU8Func.LD):
                m.d.comb += self.output.eq(self.input2)
                m.d.comb += self._ccs[Flags.Z].eq(self.output == 0)
                m.d.comb += self._ccs[Flags.N].eq(self.output[7])
                m.d.comb += self._ccs[Flags.V].eq(0)

            with m.Case(ALU8Func.ADD, ALU8Func.ADC):
                carry_in = Mux(self.func == ALU8Func.ADD, 0, self.ccs[Flags.C])

                sum0_3 = Cat(self.output[:4], carry4)
                m.d.comb += sum0_3.eq(self.input1[:4] +
                                      self.input2[:4] + carry_in)
                sum4_6 = Cat(self.output[4:7], carry7)
                m.d.comb += sum4_6.eq(self.input1[4:7] +
                                      self.input2[4:7] + carry4)
                sum7 = Cat(self.output[7], carry8)
                m.d.comb += sum7.eq(self.input1[7] + self.input2[7] + carry7)
                m.d.comb += overflow.eq(carry7 ^ carry8)
                m.d.comb += self._ccs[Flags.H].eq(carry4)
                m.d.comb += self._ccs[Flags.N].eq(self.output[7])
                m.d.comb += self._ccs[Flags.Z].eq(self.output == 0)
                m.d.comb += self._ccs[Flags.V].eq(overflow)
                m.d.comb += self._ccs[Flags.C].eq(carry8)

            with m.Case(ALU8Func.SUB, ALU8Func.SBC):
                carry_in = Mux(self.func == ALU8Func.SUB, 0, self.ccs[Flags.C])

                sum0_6 = Cat(self.output[:7], carry7)
                m.d.comb += sum0_6.eq(self.input1[:7] +
                                      ~self.input2[:7] + ~carry_in)
                sum7 = Cat(self.output[7], carry8)
                m.d.comb += sum7.eq(self.input1[7] + ~self.input2[7] + carry7)
                m.d.comb += overflow.eq(carry7 ^ carry8)
                m.d.comb += self._ccs[Flags.N].eq(self.output[7])
                m.d.comb += self._ccs[Flags.Z].eq(self.output == 0)
                m.d.comb += self._ccs[Flags.V].eq(overflow)
                m.d.comb += self._ccs[Flags.C].eq(~carry8)

            with m.Case(ALU8Func.AND):
                m.d.comb += self.output.eq(self.input1 & self.input2)
                m.d.comb += self._ccs[Flags.Z].eq(self.output == 0)
                m.d.comb += self._ccs[Flags.N].eq(self.output[7])
                m.d.comb += self._ccs[Flags.V].eq(0)

            with m.Case(ALU8Func.EOR):
                m.d.comb += self.output.eq(self.input1 ^ self.input2)
                m.d.comb += self._ccs[Flags.Z].eq(self.output == 0)
                m.d.comb += self._ccs[Flags.N].eq(self.output[7])
                m.d.comb += self._ccs[Flags.V].eq(0)

            with m.Case(ALU8Func.ORA):
                m.d.comb += self.output.eq(self.input1 | self.input2)
                m.d.comb += self._ccs[Flags.Z].eq(self.output == 0)
                m.d.comb += self._ccs[Flags.N].eq(self.output[7])
                m.d.comb += self._ccs[Flags.V].eq(0)

            with m.Case(ALU8Func.INC):
                m.d.comb += self.output.eq(self.input2 + 1)
                m.d.comb += self._ccs[Flags.Z].eq(self.output == 0)
                m.d.comb += self._ccs[Flags.N].eq(self.output[7])
                m.d.comb += self._ccs[Flags.V].eq(self.output == 0x80)

            with m.Case(ALU8Func.DEC):
                m.d.comb += self.output.eq(self.input2 - 1)
                m.d.comb += self._ccs[Flags.Z].eq(self.output == 0)
                m.d.comb += self._ccs[Flags.N].eq(self.output[7])
                m.d.comb += self._ccs[Flags.V].eq(self.output == 0x7F)

            with m.Case(ALU8Func.COM):
                m.d.comb += self.output.eq(0xFF ^ self.input2)
                m.d.comb += self._ccs[Flags.Z].eq(self.output == 0)
                m.d.comb += self._ccs[Flags.N].eq(self.output[7])
                m.d.comb += self._ccs[Flags.V].eq(0)
                m.d.comb += self._ccs[Flags.C].eq(1)

            with m.Case(ALU8Func.ROL):
                # IIIIIIIIC ->
                # COOOOOOOO
                m.d.comb += [
                    LCat(self._ccs[Flags.C], self.output).eq(
                        LCat(self.input2, self.ccs[Flags.C])),
                    self._ccs[Flags.Z].eq(self.output == 0),
                    self._ccs[Flags.N].eq(self.output[7]),
                    self._ccs[Flags.V].eq(
                        self._ccs[Flags.N] ^ self._ccs[Flags.C])
                ]

            with m.Case(ALU8Func.ROR):
                # CIIIIIIII ->
                # OOOOOOOOC
                m.d.comb += [
                    LCat(self.output, self._ccs[Flags.C]).eq(
                        LCat(self.ccs[Flags.C], self.input2)),
                    self._ccs[Flags.Z].eq(self.output == 0),
                    self._ccs[Flags.N].eq(self.output[7]),
                    self._ccs[Flags.V].eq(
                        self._ccs[Flags.N] ^ self._ccs[Flags.C])
                ]

            with m.Case(ALU8Func.ASL):
                # IIIIIIII0 ->
                # COOOOOOOO
                m.d.comb += [
                    LCat(self._ccs[Flags.C], self.output).eq(
                        LCat(self.input2, Const(0))),
                    self._ccs[Flags.Z].eq(self.output == 0),
                    self._ccs[Flags.N].eq(self.output[7]),
                    self._ccs[Flags.V].eq(
                        self._ccs[Flags.N] ^ self._ccs[Flags.C])
                ]

            with m.Case(ALU8Func.ASR):
                # 7IIIIIIII ->  ("7" is the repeat of input[7])
                # OOOOOOOOC
                m.d.comb += [
                    LCat(self.output, self._ccs[Flags.C]).eq(
                        LCat(self.input2[7], self.input2)),
                    self._ccs[Flags.Z].eq(self.output == 0),
                    self._ccs[Flags.N].eq(self.output[7]),
                    self._ccs[Flags.V].eq(
                        self._ccs[Flags.N] ^ self._ccs[Flags.C])
                ]

            with m.Case(ALU8Func.LSR):
                # 0IIIIIIII ->
                # OOOOOOOOC
                m.d.comb += [
                    LCat(self.output, self._ccs[Flags.C]).eq(
                        LCat(Const(0), self.input2)),
                    self._ccs[Flags.Z].eq(self.output == 0),
                    self._ccs[Flags.N].eq(self.output[7]),
                    self._ccs[Flags.V].eq(
                        self._ccs[Flags.N] ^ self._ccs[Flags.C])
                ]

            with m.Case(ALU8Func.CLC):
                m.d.comb += self._ccs[Flags.C].eq(0)

            with m.Case(ALU8Func.SEC):
                m.d.comb += self._ccs[Flags.C].eq(1)

            with m.Case(ALU8Func.CLV):
                m.d.comb += self._ccs[Flags.V].eq(0)

            with m.Case(ALU8Func.SEV):
                m.d.comb += self._ccs[Flags.V].eq(1)

            with m.Case(ALU8Func.CLI):
                m.d.comb += self._ccs[Flags.I].eq(0)

            with m.Case(ALU8Func.SEI):
                m.d.comb += self._ccs[Flags.I].eq(1)

            with m.Case(ALU8Func.CLZ):
                m.d.comb += self._ccs[Flags.Z].eq(0)

            with m.Case(ALU8Func.SEZ):
                m.d.comb += self._ccs[Flags.Z].eq(1)

            with m.Case(ALU8Func.TAP):
                m.d.comb += self._ccs.eq(self.input1 | 0b11000000)

            with m.Case(ALU8Func.TPA):
                m.d.comb += self.output.eq(self.ccs | 0b11000000)

        return m