Example #1
0
File: blinky.py Project: zyp/luna
    def elaborate(self, platform):
        """ Generate the Blinky tester. """

        m = Module()

        # Grab our I/O connectors.
        leds = [
            platform.request_optional("led", i, default=NullPin()).o
            for i in range(0, 8)
        ]
        user_io = [
            platform.request_optional("user_io", i, default=NullPin()).o
            for i in range(0, 8)
        ]

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

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

        # Return our elaborated module.
        return m
Example #2
0
File: mac.py Project: ret/daqnet
    def elaborate(self, platform):
        m = Module()

        # Create RMII clock domain from RMII clock input
        cd = ClockDomain("rmii", reset_less=True)
        m.d.comb += cd.clk.eq(self.rmii.ref_clk)
        m.domains.rmii = cd

        # Create RX write and TX read ports for RMII use
        rx_port_w = self.rx_mem.write_port(domain="rmii")
        tx_port_r = self.tx_mem.read_port(domain="rmii", transparent=False)
        m.submodules += [self.rx_port, rx_port_w, self.tx_port, tx_port_r]
        m.d.comb += [self.rx_port.en.eq(1), tx_port_r.en.eq(1)]

        # Create submodules for PHY and RMII
        m.submodules.phy_manager = phy_manager = PHYManager(
            self.clk_freq, self.phy_addr, self.phy_rst, self.mdio.mdio,
            self.mdio.mdc)
        m.submodules.stretch = stretch = PulseStretch(int(1e6))

        rmii_rx = RMIIRx(self.mac_addr, rx_port_w, self.rmii.crs_dv,
                         self.rmii.rxd0, self.rmii.rxd1)
        rmii_tx = RMIITx(tx_port_r, self.rmii.txen, self.rmii.txd0,
                         self.rmii.txd1)

        # Create FIFOs to interface to RMII modules
        rx_fifo = AsyncFIFO(width=11 + self.rx_port.addr.nbits, depth=4)
        tx_fifo = AsyncFIFO(width=11 + self.tx_port.addr.nbits, depth=4)

        m.d.comb += [
            # RX FIFO
            rx_fifo.din.eq(Cat(rmii_rx.rx_offset, rmii_rx.rx_len)),
            rx_fifo.we.eq(rmii_rx.rx_valid),
            Cat(self.rx_offset, self.rx_len).eq(rx_fifo.dout),
            rx_fifo.re.eq(self.rx_ack),
            self.rx_valid.eq(rx_fifo.readable),

            # TX FIFO
            tx_fifo.din.eq(Cat(self.tx_offset, self.tx_len)),
            tx_fifo.we.eq(self.tx_start),
            Cat(rmii_tx.tx_offset, rmii_tx.tx_len).eq(tx_fifo.dout),
            tx_fifo.re.eq(rmii_tx.tx_ready),
            rmii_tx.tx_start.eq(tx_fifo.readable),

            # Other submodules
            phy_manager.phy_reset.eq(self.phy_reset),
            self.link_up.eq(phy_manager.link_up),
            stretch.trigger.eq(self.rx_valid),
            self.eth_led.eq(stretch.pulse),
        ]

        rdr = DomainRenamer({"read": "sync", "write": "rmii"})
        wdr = DomainRenamer({"write": "sync", "read": "rmii"})
        rr = DomainRenamer("rmii")
        m.submodules.rx_fifo = rdr(rx_fifo)
        m.submodules.tx_fifo = wdr(tx_fifo)
        m.submodules.rmii_rx = rr(rmii_rx)
        m.submodules.rmii_tx = rr(rmii_tx)

        return m
Example #3
0
    def synth(core, m: Module):
        with m.If(core.cycle == 1):
            m.d.comb += core.alu.oper.eq(Operation.NOP)
            m.d.sync += [
                core.reg.PC.eq(add16(core.reg.PC, 1)),
                core.enable.eq(1),
                core.addr.eq(add16(core.reg.PC, 1)),
                core.RWB.eq(1),
                core.cycle.eq(2),
            ]
        with m.If(core.cycle == 2):
            m.d.comb += core.alu.oper.eq(Operation.NOP)
            m.d.sync += [
                core.tmp.eq(core.dout),
                core.reg.PC.eq(add16(core.reg.PC, 1)),
                core.enable.eq(1),
                core.addr.eq(add16(core.reg.PC, 1)),
                core.RWB.eq(1),
                core.cycle.eq(3),
            ]

        with m.If(core.cycle == 3):
            m.d.comb += core.alu.oper.eq(Operation.NOP)
            m.d.sync += [
                core.reg.PC.eq(Cat(core.tmp, core.dout)),
                core.enable.eq(1),
                core.addr.eq(Cat(core.tmp, core.dout)),
                core.RWB.eq(1),
                core.cycle.eq(1),
            ]
Example #4
0
    def elaborate(self, platform: Platform) -> Module:
        m = Module()

        a = Signal(signed(33))
        b = Signal(signed(33))
        result_ll = Signal(32)
        result_lh = Signal(33)
        result_hl = Signal(33)
        result_hh = Signal(33)
        result_3 = Signal(64)
        result_4 = Signal(64)
        active = Signal(5)
        is_signed = Signal()
        a_is_signed = Signal()
        b_is_signed = Signal()
        low = Signal()

        m.d.sync += [
            is_signed.eq(a_is_signed ^ b_is_signed),
            active.eq(Cat(self.valid & (active == 0), active)),
            low.eq(self.op == Funct3.MUL)
        ]
        # ----------------------------------------------------------------------
        # fist state
        m.d.comb += [
            a_is_signed.eq((
                (self.op == Funct3.MULH) | (self.op == Funct3.MULHSU))
                           & self.dat1[-1]),
            b_is_signed.eq((self.op == Funct3.MULH) & self.dat2[-1])
        ]
        m.d.sync += [
            a.eq(Mux(a_is_signed, -Cat(self.dat1, 1), self.dat1)),
            b.eq(Mux(b_is_signed, -Cat(self.dat2, 1), self.dat2)),
        ]
        # ----------------------------------------------------------------------
        # second state
        m.d.sync += [
            result_ll.eq(a[0:16] * b[0:16]),
            result_lh.eq(a[0:16] * b[16:33]),
            result_hl.eq(a[16:33] * b[0:16]),
            result_hh.eq(a[16:33] * b[16:33])
        ]
        # ----------------------------------------------------------------------
        # third state
        m.d.sync += [
            result_3.eq(
                Cat(result_ll, result_hh) +
                Cat(Repl(0, 16), (result_lh + result_hl)))
        ]
        # ----------------------------------------------------------------------
        # fourth state
        m.d.sync += [
            result_4.eq(Mux(is_signed, -result_3, result_3)),
            self.result.eq(Mux(low, result_4[:32], result_4[32:64]))
        ]
        m.d.comb += self.ready.eq(active[-1])

        return m
Example #5
0
    def verify_btype(self, m):
        sig = self.build_signal(m, "B", [(0, 6, "1001011"), (7, 7, "1"),
                                         (8, 11, "0000"), (12, 14, "001"),
                                         (15, 19, "00010"), (20, 24, "00011"),
                                         (25, 30, "011111"), (31, 31, "1")])
        b = BType("btype")
        b.elaborate(m.d.comb, sig)
        m.d.comb += Assert(b.opcode == Const(0b1001011, 7))
        m.d.comb += Assert(b.funct3 == Const(1, 3))
        m.d.comb += Assert(b.rs1 == Const(2, 5))
        m.d.comb += Assert(b.rs2 == Const(3, 5))
        m.d.comb += Assert(
            b.imm == Cat(Const(0b1101111100000, 13), Repl(1, 19)))

        m.d.comb += Assert(b.match(opcode=0b1001011))
        m.d.comb += Assert(b.match(rs1=2))
        m.d.comb += Assert(b.match(rs2=3))
        m.d.comb += Assert(b.match(funct3=1))
        m.d.comb += Assert(b.match(imm=0b11111111111111111111101111100000))
        m.d.comb += Assert(
            b.match(opcode=0b1001011,
                    funct3=1,
                    rs1=2,
                    rs2=3,
                    imm=0b11111111111111111111101111100000))
        m.d.comb += Assert(~b.match(opcode=0b1001011,
                                    funct3=3,
                                    rs1=1,
                                    rs2=5,
                                    imm=0b11111111111111111111101111100000))

        b_builder_check = Signal(32)
        b_builder_opcode = Signal(7)
        b_builder_f3 = Signal(3)
        b_builder_rs1 = Signal(5)
        b_builder_rs2 = Signal(5)
        b_builder_imm = Signal(13)
        m.d.comb += Assume(b_builder_imm[0] == 0)

        built_btype = BType.build_i32(opcode=b_builder_opcode,
                                      funct3=b_builder_f3,
                                      rs1=b_builder_rs1,
                                      rs2=b_builder_rs2,
                                      imm=b_builder_imm)
        m.d.comb += b_builder_check.eq(built_btype)
        b = BType("btype.build")
        b.elaborate(m.d.comb, built_btype)
        m.d.comb += Assert(b_builder_opcode == b.opcode)
        m.d.comb += Assert(b_builder_imm == Cat(Const(0, 1), b.imm[1:13]))
        m.d.comb += Assert(b.imm[13:32] == Repl(b_builder_imm[12], 32 - 13))

        return [
            b_builder_check, b_builder_opcode, b_builder_f3, b_builder_rs1,
            b_builder_rs2, b_builder_imm
        ]
Example #6
0
    def elaborate(self, platform):
        m = Module()
        x = Signal()
        tap = LFSR.TAPS[self.k]
        m.d.comb += x.eq(self.state[self.k - 1] ^ self.state[tap - 1])
        with m.If(self.reset):
            m.d.sync += self.state.eq(1)
        with m.Else():
            m.d.sync += Cat(self.state).eq(Cat(x, self.state))

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

        # create the byte selector
        with m.Switch(self.x_funct3):
            with m.Case(Funct3.B):
                m.d.comb += self.x_byte_sel.eq(0b0001 << self.x_offset)
            with m.Case(Funct3.H):
                m.d.comb += self.x_byte_sel.eq(0b0011 << self.x_offset)
            with m.Case(Funct3.W):
                m.d.comb += self.x_byte_sel.eq(0b1111)

        # format output data
        with m.Switch(self.x_funct3):
            with m.Case(Funct3.B):
                m.d.comb += self.x_data_w.eq(Repl(self.x_store_data[:8], 4))
            with m.Case(Funct3.H):
                m.d.comb += self.x_data_w.eq(Repl(self.x_store_data[:16], 2))
            with m.Case(Funct3.W):
                m.d.comb += self.x_data_w.eq(self.x_store_data)

        # format input data
        _byte = Signal((8, True))
        _half = Signal((16, True))

        m.d.comb += [
            _byte.eq(self.m_data_r.word_select(self.m_offset, 8)),
            _half.eq(self.m_data_r.word_select(self.m_offset[1], 16)),
        ]

        with m.Switch(self.m_funct3):
            with m.Case(Funct3.B):
                m.d.comb += self.m_load_data.eq(_byte)
            with m.Case(Funct3.BU):
                m.d.comb += self.m_load_data.eq(Cat(_byte,
                                                    0))  # make sign bit = 0
            with m.Case(Funct3.H):
                m.d.comb += self.m_load_data.eq(_half)
            with m.Case(Funct3.HU):
                m.d.comb += self.m_load_data.eq(Cat(_half,
                                                    0))  # make sign bit = 0
            with m.Case(Funct3.W):
                m.d.comb += self.m_load_data.eq(self.m_data_r)

        # misalignment
        with m.Switch(self.x_funct3):
            with m.Case(Funct3.H, Funct3.HU):
                m.d.comb += self.x_misaligned.eq(self.x_offset[0])
            with m.Case(Funct3.W):
                m.d.comb += self.x_misaligned.eq(self.x_offset != 0)

        return m
Example #8
0
    def populate_ulpi_registers(self, m):
        """ Creates translator objects that map our control signals to ULPI registers. """

        # Function control.
        function_control = Cat(self.xcvr_select, self.term_select, self.op_mode, Const(0), ~self.suspend, Const(0))
        self.add_composite_register(m, 0x04, function_control, reset_value=0b01000001)

        # OTG control.
        otg_control = Cat(
            self.id_pullup, self.dp_pulldown, self.dm_pulldown, self.dischrg_vbus,
            self.chrg_vbus, Const(0), Const(0), self.use_external_vbus_indicator
        )
        self.add_composite_register(m, 0x0A, otg_control, reset_value=0b00000110)
Example #9
0
    def elaborate(self, platform: Platform) -> Module:
        m = Module()

        m.submodules.big = big = ALU_big(self.verification)

        m.d.comb += [
            big.inputa.eq(Cat(self.inputa[:4], self.inputa[4:])),
            big.inputb.eq(Cat(self.inputb[:4], self.inputb[4:])),
            big.oper.eq(self.oper),
            self.result.eq(Cat(big.result[:4], big.result[4:])),
            self.PSW.eq(big.PSW),
        ]

        return m
Example #10
0
    def elaborate(self, platform: Platform) -> Module:
        m = Module()
        # From: http://teaching.idallen.com/cst8214/08w/notes/overflow.txt
        with m.If(self.sub):
            m.d.comb += [
                Cat(self.result, self.carry).eq(self.dat1 - self.dat2),
                self.overflow.eq((self.dat1[-1] != self.dat2[-1]) & (self.dat2[-1] == self.result[-1]))
            ]
        with m.Else():
            m.d.comb += [
                Cat(self.result, self.carry).eq(self.dat1 + self.dat2),
                self.overflow.eq((self.dat1[-1] == self.dat2[-1]) & (self.dat2[-1] != self.result[-1]))
            ]

        return m
Example #11
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
Example #12
0
 def check(m: Module, data: Snapshot, alu: Signal):
     m.d.comb += [
         Assert(data.read_data[0].matches(MOV_A_read.opcode)),
     ]
     m.d.comb += [
         Assert(Past(alu.oper, 4) == Operation.NOP),
         Assert(Past(alu.oper, 3) == Operation.NOP),
         Assert(Past(alu.oper, 2) == Operation.NOP),
         Assert(Past(alu.oper, 1) == Operation.OOR),
         Assert(Past(alu.inputa) == data.read_data[3]),
         Assert(Past(alu.inputb) == 0),
         Assert(Past(alu.result) == data.read_data[3]),
     ]
     m.d.comb += [
         Assert(data.post.A == Past(alu.result)),
         Assert(data.post.X == data.pre.X),
         Assert(data.post.Y == data.pre.Y),
         Assert(data.post.SP == data.pre.SP),
         Assert(data.post.PC == add16(data.pre.PC, 3)),
     ]
     m.d.comb += [
         Assert(data.addresses_read == 4),
         Assert(data.addresses_written == 0),
         Assert(data.read_addr[0] == add16(data.pre.PC, 0)),
         Assert(data.read_addr[1] == add16(data.pre.PC, 1)),
         Assert(data.read_addr[2] == add16(data.pre.PC, 2)),
         Assert(data.read_addr[3] == Cat(data.read_data[1], data.read_data[2])),
     ]
Example #13
0
 def check(m: Module, data: Snapshot, alu: Signal):
     m.d.comb += [
         Assert(data.read_data[0].matches(MOV_A_write.opcode)),
     ]
     m.d.comb += [
         Assert(Past(alu.oper, 5) == Operation.NOP),
         Assert(Past(alu.oper, 4) == Operation.NOP),
         Assert(Past(alu.oper, 3) == Operation.NOP),
         Assert(Past(alu.oper, 2) == Operation.NOP),
         Assert(Past(alu.oper, 1) == Operation.NOP),
     ]
     m.d.comb += [
         Assert(data.post.A == data.pre.A),
         Assert(data.post.X == data.pre.X),
         Assert(data.post.Y == data.pre.Y),
         Assert(data.post.SP == data.pre.SP),
         Assert(data.post.PC == add16(data.pre.PC, 3)),
         Assert(data.post.PSW == data.pre.PSW),
     ]
     m.d.comb += [
         Assert(data.addresses_read == 3),
         Assert(data.addresses_written == 1),
         Assert(data.read_addr[0] == add16(data.pre.PC, 0)),
         Assert(data.read_addr[1] == add16(data.pre.PC, 1)),
         Assert(data.read_addr[2] == add16(data.pre.PC, 2)),
         Assert(data.write_addr[0] == Cat(data.read_data[1], data.read_data[2])),
         Assert(data.write_data[0] == data.pre.A),
     ]
Example #14
0
    def elaborate(self, platform):
        m = Module()

        # Create our core USB device, and add a standard control endpoint.
        m.submodules.usb = usb = USBDevice(bus=self._bus)
        _control_ep = usb.add_standard_control_endpoint(
            self.create_descriptors())

        # Cram all the registers into a single report
        statuses = Cat(
            [signal for (signal, _input_range, _usage) in self.inputs])

        # Create an endpoint to emit our report every time we get polled
        status_ep = USBSignalInEndpoint(width=statuses.shape().width,
                                        endpoint_number=1,
                                        endianness="little")
        usb.add_endpoint(status_ep)

        # Connect our USB device
        m.d.comb += [
            status_ep.signal.eq(statuses),
            usb.connect.eq(self.connect)
        ]

        return m
Example #15
0
File: ila.py Project: zyp/luna
    def __init__(self,
                 *,
                 signals,
                 sample_depth,
                 domain="sync",
                 sample_rate=60e6,
                 samples_pretrigger=1):
        self.domain = domain
        self.signals = signals
        self.inputs = Cat(*signals)
        self.sample_width = len(self.inputs)
        self.sample_depth = sample_depth
        self.samples_pretrigger = samples_pretrigger
        self.sample_rate = sample_rate
        self.sample_period = 1 / sample_rate

        #
        # Create a backing store for our samples.
        #
        self.mem = Memory(width=self.sample_width,
                          depth=sample_depth,
                          name="ila_buffer")

        #
        # I/O port
        #
        self.trigger = Signal()
        self.sampling = Signal()
        self.complete = Signal()

        self.captured_sample_number = Signal(range(0, self.sample_depth))
        self.captured_sample = Signal(self.sample_width)
Example #16
0
 def process_load(self, input_value):
     lh_value = Signal(32)
     comb = self.core.current_module.d.comb
     
     bit_to_replicate=Mux(self.core.itype.funct3[2], Const(0,1), input_value[15])
     comb += lh_value.eq(Cat(input_value[0:16], Repl(bit_to_replicate, 16)))
     return lh_value
Example #17
0
File: standard.py Project: zyp/luna
    def handle_simple_data_request(self, m, transmitter, data, length=1):
        """ Fills in a given current state with a request that returns a given piece of data.

        For e.g. GET_CONFIGURATION and GET_STATUS requests.

        Parameters:
            transmitter -- The transmitter module we're working with.
            data        -- The data to be returned.
        """

        # Connect our transmitter up to the output stream...
        m.d.comb += [
            transmitter.stream.attach(self.interface.tx),
            Cat(transmitter.data[0:1]).eq(data),
            transmitter.max_length.eq(length)
        ]

        # ... trigger it to respond when data's requested...
        with m.If(self.interface.data_requested):
            m.d.comb += transmitter.start.eq(1)

        # ... and ACK our status stage.
        with m.If(self.interface.status_requested):
            m.d.comb += self.interface.handshakes_out.ack.eq(1)
            m.next = 'IDLE'
Example #18
0
    def _elab_read(self, m, dps, r_full):
        r_curr_buf = Signal()
        # Address within current buffer
        r_addr = Signal.like(self.input_depth)

        # Create and connect sequential memory readers
        smrs = [
            SequentialMemoryReader(
                max_depth=self.max_depth // 2,
                width=32) for _ in range(4)]
        for (n, dp, smr) in zip(range(4), dps, smrs):
            m.submodules[f"smr_{n}"] = smr
            m.d.comb += [
                dp.r_addr.eq(Cat(smr.mem_addr, r_curr_buf)),
                smr.mem_data.eq(dp.r_data),
                smr.limit.eq((self.input_depth + 3 - n) >> 2),
            ]

        smr_nexts = Array(smr.next for smr in smrs)

        # Ready if current buffer is full
        full = Signal()
        m.d.comb += full.eq(r_full[r_curr_buf])
        last_full = Signal()
        m.d.sync += last_full.eq(full)
        with m.If(full & ~last_full):
            m.d.sync += self.r_ready.eq(1)
            m.d.comb += [smr.restart.eq(1) for smr in smrs]

        # Increment address
        with m.If(self.r_next & self.r_ready):
            with m.If(r_addr == self.input_depth - 1):
                m.d.sync += r_addr.eq(0)
            with m.Else():
                m.d.sync += r_addr.eq(r_addr + 1)
            m.d.comb += smr_nexts[r_addr[:2]].eq(1)

        # Get data
        smr_datas = Array(smr.data for smr in smrs)
        m.d.comb += self.r_data.eq(smr_datas[r_addr[:2]])

        # On finished (overrides r_next)
        with m.If(self.r_finished):
            m.d.sync += [
                r_addr.eq(0),
                r_full[r_curr_buf].eq(0),
                last_full.eq(0),
                self.r_ready.eq(0),
                r_curr_buf.eq(~r_curr_buf),
            ]

        # On restart, reset addresses and Sequential Memory readers, go to not
        # ready
        with m.If(self.restart):
            m.d.sync += [
                r_addr.eq(0),
                last_full.eq(0),
                self.r_ready.eq(0),
                r_curr_buf.eq(0),
            ]
Example #19
0
def LCat(*args) -> Value:
    """Left or logical concatenation.

    Concatenates arguments such that the first argument is placed in the
    highest bit positions, and the last is placed in the lowest bit positions.
    """
    return Cat(*args[::-1])
Example #20
0
    def elaborate_right(self, m: Module):
        comb = m.d.comb
        last_round = self.input
        for i in range(self.xlen.bit_length() - 1):
            next_round = Signal(self.xlen, name=f"{self.prefix}_r{i}")
            with m.If(self.shamt[i]):
                # 00 AAAA
                # 01 0AAA
                # 10 00AA
                # 11 000A

                shift_by = 2**i
                shift_end = self.xlen - shift_by

                comb += next_round[0:shift_end].eq(last_round >> shift_by)
                comb += next_round[shift_end:self.xlen].eq(
                    Cat([self.msb for _ in range(shift_by)]))

            with m.Else():
                comb += next_round.eq(last_round)
            last_round = next_round

        comb += self.output.eq(last_round)

        return
Example #21
0
    def _elab_write(self, m, dps, r_full):
        w_curr_buf = Signal()
        # Address within current buffer
        w_addr = Signal.like(self.input_depth)

        # Connect to memory write port
        for n, dp in enumerate(dps):
            m.d.comb += [
                dp.w_addr.eq(Cat(w_addr[2:], w_curr_buf)),
                dp.w_data.eq(self.w_data),
                dp.w_en.eq(self.w_en & self.w_ready & (n == w_addr[:2])),
            ]
        # Ready to write current buffer if reading is not allowed
        m.d.comb += self.w_ready.eq(~r_full[w_curr_buf])

        # Write address increment
        with m.If(self.w_en & self.w_ready):
            with m.If(w_addr == self.input_depth - 1):
                # at end of buffer - mark buffer ready for reading and go to
                # next
                m.d.sync += [
                    w_addr.eq(0),
                    r_full[w_curr_buf].eq(1),
                    w_curr_buf.eq(~w_curr_buf),
                ]
            with m.Else():
                m.d.sync += w_addr.eq(w_addr + 1)

        with m.If(self.restart):
            m.d.sync += [
                w_addr.eq(0),
                w_curr_buf.eq(0),
            ]
Example #22
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
Example #23
0
    def elaborate(self, platform: Platform) -> Module:
        m = Module()

        sign_fill   = Signal()
        operand     = Signal(32)
        r_direction = Signal()
        r_result    = Signal(32)

        shdata      = Signal(64)  # temp data

        # pre-invert the value, if needed
        # Direction:  1 = right. 0 = left.
        m.d.comb += [
            operand.eq(Mux(self.direction, self.dat, self.dat[::-1])),
            sign_fill.eq(Mux(self.direction & self.sign_ext, self.dat[-1], 0)),

            shdata.eq(Cat(operand, Repl(sign_fill, 32)))
        ]

        with m.If(~self.stall):
            m.d.sync += [
                r_direction.eq(self.direction),
                r_result.eq(shdata >> self.shamt)
            ]

        m.d.comb += self.result.eq(Mux(r_direction, r_result, r_result[::-1]))
        return m
Example #24
0
    def mode_ext(self, m: Module) -> Statement:
        """Generates logic to get the 16-bit operand for extended mode instructions.

        Returns a Statement containing the 16-bit operand. After cycle 2, tmp16 
        contains the operand.
        """
        operand = Mux(self.cycle == 2, Cat(self.Din, self.tmp16[8:]),
                      self.tmp16)

        with m.If(self.cycle == 1):
            m.d.ph1 += self.tmp16[8:].eq(self.Din)
            m.d.ph1 += self.pc.eq(self.pc + 1)
            m.d.ph1 += self.Addr.eq(self.pc + 1)
            m.d.ph1 += self.RW.eq(1)
            m.d.ph1 += self.cycle.eq(2)
            if self.verification is not None:
                self.formalData.read(m, self.Addr, self.Din)

        with m.If(self.cycle == 2):
            m.d.ph1 += self.tmp16[:8].eq(self.Din)
            m.d.ph1 += self.pc.eq(self.pc + 1)
            m.d.ph1 += self.cycle.eq(3)
            if self.verification is not None:
                self.formalData.read(m, self.Addr, self.Din)

        return operand
Example #25
0
    def check(self, m: Module, instr: Value, data: FormalData):
        b = instr[6]
        input = Mux(b, data.pre_b, data.pre_a)

        m.d.comb += [
            Assert(data.post_a == data.pre_a),
            Assert(data.post_b == data.pre_b),
            Assert(data.post_x == data.pre_x),
            Assert(data.post_sp == data.pre_sp),
        ]
        m.d.comb += [
            Assert(data.post_pc == data.plus16(data.pre_pc, 3)),
            Assert(data.addresses_read == 2),
            Assert(data.read_addr[0] == data.plus16(data.pre_pc, 1)),
            Assert(data.read_addr[1] == data.plus16(data.pre_pc, 2)),
            Assert(data.addresses_written == 1),
            Assert(data.write_addr[0] == Cat(data.read_data[1],
                                             data.read_data[0])),
            Assert(data.write_data[0] == input),
        ]
        self.assertFlags(m,
                         data.post_ccs,
                         data.pre_ccs,
                         Z=(input == 0),
                         N=input[7],
                         V=0)
Example #26
0
    def check(self, m: Module, instr: Value, data: FormalData):
        mode = instr[4:6]

        m.d.comb += [
            Assert(data.post_ccs == data.pre_ccs),
            Assert(data.post_a == data.pre_a),
            Assert(data.post_b == data.pre_b),
            Assert(data.post_x == data.pre_x),
            Assert(data.post_sp == data.pre_sp),
            Assert(data.addresses_written == 0),
        ]

        with m.If(mode == ModeBits.EXTENDED.value):
            m.d.comb += [
                Assert(data.addresses_read == 2),
                Assert(data.read_addr[0] == data.plus16(data.pre_pc, 1)),
                Assert(data.read_addr[1] == data.plus16(data.pre_pc, 2)),
                Assert(
                    data.post_pc == Cat(data.read_data[1], data.read_data[0])),
            ]

        with m.If(mode == ModeBits.INDEXED.value):
            m.d.comb += [
                Assert(data.addresses_read == 1),
                Assert(data.read_addr[0] == data.plus16(data.pre_pc, 1)),
                Assert(
                    data.post_pc == (data.pre_x + data.read_data[0])[:16]),
            ]
Example #27
0
    def check(self, m: Module, instr: Value, data: FormalData):
        b = instr[6]
        pre_input = Mux(b, data.pre_b, data.pre_a)
        output = Mux(b, data.post_b, data.post_a)

        with m.If(b):
            m.d.comb += Assert(data.post_a == data.pre_a)
        with m.Else():
            m.d.comb += Assert(data.post_b == data.pre_b)

        m.d.comb += [
            Assert(data.post_x == data.pre_x),
            Assert(data.post_sp == data.pre_sp),
            Assert(data.addresses_written == 0),
        ]
        m.d.comb += [
            Assert(data.post_pc == data.plus16(data.pre_pc, 3)),
            Assert(data.addresses_read == 3),
            Assert(data.read_addr[0] == data.plus16(data.pre_pc, 1)),
            Assert(data.read_addr[1] == data.plus16(data.pre_pc, 2)),
            Assert(data.read_addr[2] == Cat(data.read_data[1],
                                            data.read_data[0])),
        ]

        input1 = pre_input
        input2 = data.read_data[2]
        z = output == 0
        n = output[7]
        v = 0

        m.d.comb += Assert(output == (input1 | input2))
        self.assertFlags(m, data.post_ccs, data.pre_ccs, Z=z, N=n, V=v)
Example #28
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
Example #29
0
 def elaborate(self, comb: List[Statement], input: Signal):
     comb += self.opcode.eq(input[0:7])
     comb += self.funct3.eq(input[12:15])
     comb += self.rs1.eq(input[15:20])
     comb += self.rs2.eq(input[20:25])
     comb += self.imm.eq(
         Cat(Const(0, 1), input[8:12], input[25:31], input[7],
             Repl(input[31], 20)))
Example #30
0
    def formal_ripple(cls) -> Tuple[Module, List[Signal]]:
        """Formal verification for a bunch of ALUs in ripple-carry mode."""
        m = Module()

        alus = [None] * 8
        m.submodules.alu0 = alus[0] = IC_74181()
        m.submodules.alu1 = alus[1] = IC_74181()
        m.submodules.alu2 = alus[2] = IC_74181()
        m.submodules.alu3 = alus[3] = IC_74181()
        m.submodules.alu4 = alus[4] = IC_74181()
        m.submodules.alu5 = alus[5] = IC_74181()
        m.submodules.alu6 = alus[6] = IC_74181()
        m.submodules.alu7 = alus[7] = IC_74181()

        a = Signal(32)
        b = Signal(32)
        f = Signal(32)
        cin = Signal()
        cout = Signal()
        s = Signal(4)
        mt = Signal()

        for x in range(8):
            m.d.comb += alus[x].a.eq(a[x * 4:x * 4 + 4])
            m.d.comb += alus[x].b.eq(b[x * 4:x * 4 + 4])
            m.d.comb += f[x * 4:x * 4 + 4].eq(alus[x].f)
            m.d.comb += alus[x].m.eq(mt)
            m.d.comb += alus[x].s.eq(s)
        for x in range(7):
            m.d.comb += alus[x + 1].n_carryin.eq(alus[x].n_carryout)
        m.d.comb += alus[0].n_carryin.eq(~cin)
        m.d.comb += cout.eq(~alus[7].n_carryout)

        add_mode = (s == 9) & (mt == 0)
        sub_mode = (s == 6) & (mt == 0)
        m.d.comb += Assume(add_mode | sub_mode)

        y = Signal(33)
        with m.If(add_mode):
            m.d.comb += y.eq(a + b + cin)
            m.d.comb += Assert(f == y[:32])
            m.d.comb += Assert(cout == y[32])
        with m.Elif(sub_mode):
            m.d.comb += y.eq(a - b - ~cin)
            m.d.comb += Assert(f == y[:32])
            m.d.comb += Assert(cout == ~y[32])

            # Check how equality, unsigned gt, and unsigned gte comparisons work.
            with m.If(cin == 0):
                all_eq = Cat(*[i.a_eq_b for i in alus]).all()
                m.d.comb += Assert(all_eq == (a == b))
                m.d.comb += Assert(cout == (a > b))
            with m.Else():
                m.d.comb += Assert(cout == (a >= b))

        return m, [a, b, f, cin, cout, s, mt, y]