예제 #1
0
    def check(self, m: Module):
        mode = self.instr[4:6]
        self.assert_flags(m)

        with m.If(mode == ModeBits.EXTENDED.value):
            self.assert_cycles(m, 3)
            addr_hi = self.assert_cycle_signals(m,
                                                1,
                                                address=self.data.pre_pc + 1,
                                                vma=1,
                                                rw=1,
                                                ba=0)
            addr_lo = self.assert_cycle_signals(m,
                                                2,
                                                address=self.data.pre_pc + 2,
                                                vma=1,
                                                rw=1,
                                                ba=0)
            self.assert_registers(m, PC=LCat(addr_hi, addr_lo))

        with m.If(mode == ModeBits.INDEXED.value):
            self.assert_cycles(m, 4)
            offset = self.assert_cycle_signals(m,
                                               1,
                                               address=self.data.pre_pc + 1,
                                               vma=1,
                                               rw=1,
                                               ba=0)
            self.assert_cycle_signals(m, 2, vma=0, ba=0)
            self.assert_cycle_signals(m, 3, vma=0, ba=0)
            self.assert_registers(m, PC=self.data.pre_x + offset)
예제 #2
0
파일: event.py 프로젝트: wxh0000mm/luna
    def elaborate(self, platform):
        m = Module()

        with m.If(self.pending.w_stb):
            m.d.sync += self.pending.r_data.eq(self.pending.r_data
                                               & ~self.pending.w_data)

        with m.If(self.enable.w_stb):
            m.d.sync += self.enable.r_data.eq(self.enable.w_data)

        for i, event in enumerate(self._events):
            m.d.sync += self.status.r_data[i].eq(event.stb)

            if event.mode in ("rise", "fall"):
                event_stb_r = Signal.like(event.stb, name_suffix="_r")
                m.d.sync += event_stb_r.eq(event.stb)

            event_trigger = Signal(name="{}_trigger".format(event.name))
            if event.mode == "level":
                m.d.comb += event_trigger.eq(event.stb)
            elif event.mode == "rise":
                m.d.comb += event_trigger.eq(~event_stb_r & event.stb)
            elif event.mode == "fall":
                m.d.comb += event_trigger.eq(event_stb_r & ~event.stb)
            else:
                assert False  # :nocov:

            with m.If(event_trigger):
                m.d.sync += self.pending.r_data[i].eq(1)

        m.d.comb += self.irq.eq(
            (self.pending.r_data & self.enable.r_data).any())

        return m
예제 #3
0
    def elaborate(self, platform):
        m = Module()
        m.submodules.serdes = serdes = self.serdes

        # The symbol table reads the corresponding symbols for each
        # symbol in PACKET and outputs them on tx_data
        m.submodules.symboltable = symboltable = SymbolTable(
            table=pack_mem(TABLE, width=20),
            packet=Memory(width=16,
                          depth=len(PACKET),
                          init=[int(i) for i in np.array(PACKET) * 5000 / 20]),
            samples_per_symbol=int(5e9 / 1e6),
            tx_domain="tx")
        m.d.comb += [
            symboltable.packet_length.eq(len(PACKET)),
            serdes.tx_data.eq(symboltable.tx_data)
        ]

        # Quick state machine to transmit and then wait a bit before
        # transmitting again
        counter = Signal(32)
        with m.FSM():
            with m.State("START"):
                m.d.sync += symboltable.tx_reset.eq(1)
                m.next = "WAIT_DONE"
            with m.State("WAIT_DONE"):
                m.d.sync += symboltable.tx_reset.eq(0)
                with m.If(symboltable.tx_done):
                    m.d.sync += counter.eq(0)
                    m.next = "PAUSE"
            with m.State("PAUSE"):
                m.d.sync += counter.eq(counter + 1)
                with m.If(counter >= int(1e4)):
                    m.next = "START"
        return m
예제 #4
0
    def handle_jalr(self, m: Module):
        """Adds the JALR logic to the given module.

        rd <- PC + 4, PC <- (rs1 + imm) & 0xFFFFFFFE

        rs1     -> X
        imm     -> Y
        ALU ADD -> Z
        Z       -> memaddr
        ---------------------
        PC + 4  -> Z
        Z       -> rd
        memaddr -> PC  # This will zero the least significant bit
        """
        with m.If(self._instr_phase == 0):
            m.d.comb += [
                self.reg_to_x.eq(1),
                self._x_reg_select.eq(InstrReg.RS1),
                self.y_mux_select.eq(SeqMuxSelect.IMM),
                self.alu_op_to_z.eq(AluOp.ADD),
                self.memaddr_mux_select.eq(SeqMuxSelect.Z),
                self._next_instr_phase.eq(1),
            ]
        with m.Else():
            with m.If(self.memaddr_2_lsb[1] != 0):
                self.set_exception(m,
                                   ConstSelect.EXC_INSTR_ADDR_MISALIGN,
                                   mtval=SeqMuxSelect.MEMADDR_LSB_MASKED)
            with m.Else():
                m.d.comb += [
                    self.z_mux_select.eq(SeqMuxSelect.PC_PLUS_4),
                    self._z_reg_select.eq(InstrReg.RD),
                ]
                self.next_instr(m, NextPC.MEMADDR_NO_LSB)
예제 #5
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),
            ]
예제 #6
0
    def formal(cls) -> Tuple[Module, List[Signal]]:
        """Formal verification for the NextDay module."""
        m = Module()
        m.submodules.nd = nd = cls()

        # We don't have to create a signal here. Using is_zero is like just copying the logic.
        is_zero = ((nd.next_year == 0) & (nd.next_month == 0) &
                   (nd.next_day == 0))
        m.d.comb += Assert(nd.invalid == is_zero)

        all_nonzero = ((nd.next_year != 0) & (nd.next_month != 0) &
                       (nd.next_day != 0))
        m.d.comb += Assert(all_nonzero | is_zero)

        with m.If(~nd.invalid):
            with m.If(nd.day == 31):
                m.d.comb += Assert(nd.next_day == 1)
            with m.If((nd.month == 12) & (nd.day == 31)):
                m.d.comb += Assert(nd.next_month == 1)

        with m.If(((nd.year % 2) == 1) & (nd.month == 2) & (nd.day == 29)):
            m.d.comb += Assert(nd.invalid)

        m.d.comb += Cover((nd.next_month == 2) & (nd.next_day == 29))

        return m, [nd.year, nd.month, nd.day]
예제 #7
0
    def mode_indexed(self, m: Module) -> Statement:
        """Generates logic to get the 16-bit address for indexed mode instructions.

        Returns a Statement containing a 16-bit address.
        After cycle 2, tmp16 contains the address. The address is not valid until after
        cycle 2.
        """
        operand = self.tmp16

        with m.If(self.cycle == 1):
            # Output during cycle 2:
            m.d.ph1 += self.tmp16[8:].eq(0)
            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.VMA.eq(0)
            if self.verification is not None:
                self.formalData.read(m, self.Addr, self.Din)

        with m.If(self.cycle == 2):
            # Output during cycle 3:
            m.d.ph1 += self.tmp16.eq(self.tmp16 + self.x)
            m.d.ph1 += self.VMA.eq(0)

        return operand
예제 #8
0
    def check(self, m: Module):
        input1, input2, actual_output, size, use_a = self.common_check(m)

        carry_in = Signal()
        sum9 = Signal(9)
        sum8 = Signal(8)
        with_carry = self.instr[1] == 1

        n = sum9[7]
        c = ~sum9[8]
        z = sum9[:8] == 0
        v = sum8[7] ^ sum9[8]

        with m.If(with_carry):
            m.d.comb += carry_in.eq(self.data.pre_ccs[Flags.C])
        with m.Else():
            m.d.comb += carry_in.eq(0)

        m.d.comb += [
            sum9.eq(input1 + ~input2 + ~carry_in),
            sum8.eq(input1[:7] + ~input2[:7] + ~carry_in),
        ]

        with m.If(use_a):
            self.assert_registers(m, A=sum9, PC=self.data.pre_pc + size)
        with m.Else():
            self.assert_registers(m, B=sum9, PC=self.data.pre_pc + size)
        self.assert_flags(m, Z=z, N=n, V=v, C=c)
예제 #9
0
파일: transmitter.py 프로젝트: zyp/luna
    def elaborate(self, platform):
        m = Module()

        shifter = Signal(self._width)
        pos = Signal(self._width, reset=0b1)

        with m.If(self.i_enable):
            empty = Signal()
            m.d.usb += [
                pos.eq(pos >> 1),
                shifter.eq(shifter >> 1),
                self.o_get.eq(empty),
            ]

            with m.If(empty):
                m.d.usb += [
                    shifter.eq(self.i_data),
                    pos.eq(1 << (self._width - 1)),
                ]

        with m.If(self.i_clear):
            m.d.usb += [shifter.eq(0), pos.eq(1)]

        m.d.comb += [
            empty.eq(pos[0]),
            self.o_empty.eq(empty),
            self.o_data.eq(shifter[0]),
        ]

        return m
예제 #10
0
    def formal(cls) -> Tuple[Module, List[Signal]]:
        m = Module()
        ph = ClockDomain("ph")
        clk = ClockSignal("ph")

        m.domains += ph
        m.d.sync += clk.eq(~clk)

        s = IC_7416374(clk="ph")

        m.submodules += s

        with m.If(s.n_oe):
            m.d.comb += Assert(s.q == 0)

        with m.If(~s.n_oe & Rose(clk)):
            m.d.comb += Assert(s.q == Past(s.d))

        with m.If(~s.n_oe & Fell(clk) & ~Past(s.n_oe)):
            m.d.comb += Assert(s.q == Past(s.q))

        sync_clk = ClockSignal("sync")
        sync_rst = ResetSignal("sync")

        # Make sure the clock is clocking
        m.d.comb += Assume(sync_clk == ~Past(sync_clk))

        # Don't want to test what happens when we reset.
        m.d.comb += Assume(~sync_rst)
        m.d.comb += Assume(~ResetSignal("ph"))

        return m, [sync_clk, sync_rst, s.n_oe, s.q, s.d]
예제 #11
0
    def elaborate(self, platform):
        m = Module()

        with m.If(self.i_hlclk):
            m.d.sync += [
                self.r_hline.eq(self.r_hline + 1),
                self.r_hline_count.eq(self.r_hline_count + 1),
            ]

            with m.FSM() as fsm:
                with m.State("SYNC"):
                    with m.If(self.r_hline_count == self.syncv_vs):
                        m.d.sync += self.r_hline_count.eq(1)
                        m.next = "BACK-PORCH"

                with m.State("BACK-PORCH"):
                    with m.If(self.r_hline_count == (self.syncv_vbp +
                                                     self.syncv_vbpe)):
                        m.d.sync += self.r_hline_count.eq(1)
                        m.next = "DISPLAY"

                with m.State("DISPLAY"):
                    with m.If(self.r_hline_count == self.syncv_vdp):
                        m.d.sync += self.r_hline.eq(1)
                        m.d.sync += self.r_hline_count.eq(1)
                        m.next = "FRONT-PORCH"

                with m.State("FRONT-PORCH"):
                    with m.If(self.r_hline_count == (self.syncv_vfp +
                                                     self.syncv_vfpe)):
                        m.d.sync += self.r_hline_count.eq(1)
                        m.d.sync += self.o_odd.eq(~self.o_odd)
                        m.next = "SYNC"

        return m
예제 #12
0
    def elaborate(self, _: Platform) -> Module:
        """Implements the logic for the conditional right-shifter."""
        m = Module()
        N = self._N

        with m.If(self.en):
            # The high N bits get either 0 or the most significant
            # bit in data_in, depending on arithmetic.
            msb = self.data_in[-1]
            w = len(self.data_out)

            # m.d.comb += self.data_out.bit_select(w-N, N).eq(
            #     Mux(self.arithmetic, Repl(msb, N), 0))

            with m.If(self.arithmetic):
                m.d.comb += self.data_out[w - N:].eq(Repl(msb, N))
            with m.Else():
                m.d.comb += self.data_out[w - N:].eq(0)

            # The rest are moved over.
            # m.d.comb += self.data_out.bit_select(0, w-N).eq(
            #     self.data_in.bit_select(N, w-N))

            m.d.comb += self.data_out[:w - N].eq(self.data_in[N:])

        with m.Else():
            m.d.comb += self.data_out.eq(self.data_in)

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

        # This state machine recognizes sequences of 6 bits and drops the 7th
        # bit.  The fsm implements a counter in a series of several states.
        # This is intentional to help absolutely minimize the levels of logic
        # used.
        drop_bit = Signal(1)

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

            for i in range(6):
                with m.State(f"D{i}"):
                    with m.If(self.i_valid):
                        with m.If(self.i_data):
                            # Receiving '1' increments the bitstuff counter.
                            m.next = (f"D{i + 1}")
                        with m.Else():
                            # Receiving '0' resets the bitstuff counter.
                            m.next = "D0"

            with m.State("D6"):
                with m.If(self.i_valid):
                    m.d.comb += drop_bit.eq(1)
                    # Reset the bitstuff counter, drop the data.
                    m.next = "D0"

        m.d.usb_io += [
            self.o_data.eq(self.i_data),
            self.o_stall.eq(drop_bit | ~self.i_valid),
            self.o_error.eq(drop_bit & self.i_data & self.i_valid),
        ]

        return m
예제 #14
0
파일: core.py 프로젝트: GuzTech/n6800
    def elaborate(self, platform: Platform) -> Module:
        m = Module()
        m.submodules.alu = alu = ALU8()

        # defaults
        m.d.comb += self.end_instr_flag.eq(0)
        m.d.comb += self.src8_1_select.eq(Reg8.NONE)
        m.d.comb += self.src8_2_select.eq(Reg8.NONE)
        m.d.comb += self.alu8_func.eq(ALU8Func.NONE)
        m.d.ph1 += self.VMA.eq(1)

        self.src_bus_setup(m, self.reg8_map, self.src8_1, self.src8_1_select)
        self.src_bus_setup(m, self.reg8_map, self.src8_2, self.src8_2_select)

        m.d.comb += alu.input1.eq(self.src8_1)
        m.d.comb += alu.input2.eq(self.src8_2)
        m.d.comb += self.alu8.eq(alu.output)
        m.d.comb += alu.func.eq(self.alu8_func)
        m.d.comb += self.ccs.eq(alu.ccs)

        self.reset_handler(m)
        with m.If(self.reset_state == 3):
            with m.If(self.cycle == 0):
                self.fetch(m)
            with m.Else():
                self.execute(m)
        self.maybe_do_formal_verification(m)
        self.end_instr_flag_handler(m)

        return m
예제 #15
0
파일: core.py 프로젝트: GuzTech/n6800
    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
예제 #16
0
    def handle_branch(self, m: Module):
        """Adds the BRANCH logic to the given module.

        cond <- rs1 - rs2 < 0, rs1 - rs2 == 0
        if f(cond):
            PC <- PC + imm
        else:
            PC <- PC + 4

        rs1     -> X
        rs2     -> Y
        ALU SUB -> Z, cond
        --------------------- cond == 1
        PC      -> X
        imm/4   -> Y (imm for cond == 1, 4 otherwise)
        ALU ADD -> Z
        Z       -> PC
        Z       -> memaddr
        --------------------- cond == 0
        PC + 4  -> PC
        PC + 4  -> memaddr
        """
        with m.If(self._instr_phase == 0):
            m.d.comb += [
                self.reg_to_x.eq(1),
                self._x_reg_select.eq(InstrReg.RS1),
                self.reg_to_y.eq(1),
                self._y_reg_select.eq(InstrReg.RS2),
                self.alu_op_to_z.eq(AluOp.SUB),
                self._next_instr_phase.eq(1),
            ]
        with m.Elif(self._instr_phase == 1):
            with m.If(~self._funct3.matches(BranchCond.EQ, BranchCond.NE,
                                            BranchCond.LT, BranchCond.GE,
                                            BranchCond.LTU, BranchCond.GEU)):
                self.handle_illegal_instr(m)

            with m.Else():
                with m.If(self.branch_cond):
                    m.d.comb += self.y_mux_select.eq(SeqMuxSelect.IMM)
                with m.Else():
                    m.d.comb += self._const.eq(ConstSelect.SHAMT_4)
                    m.d.comb += self.y_mux_select.eq(SeqMuxSelect.CONST)

                m.d.comb += [
                    self.x_mux_select.eq(SeqMuxSelect.PC),
                    self.alu_op_to_z.eq(AluOp.ADD),
                ]

                with m.If(self.data_z_in_2_lsb0):
                    self.next_instr(m, NextPC.Z)

                with m.Else():
                    m.d.comb += self._next_instr_phase.eq(2)
                    m.d.comb += self.tmp_mux_select.eq(SeqMuxSelect.Z)

        with m.Else():
            self.set_exception(m,
                               ConstSelect.EXC_INSTR_ADDR_MISALIGN,
                               mtval=SeqMuxSelect.TMP)
예제 #17
0
    def elaborate(self, platform):
        m = Module()
        rx_port = self.user_rx_mem.read_port()
        tx_port = self.user_tx_mem.write_port()

        m.submodules += [self.mem_r_port, self.mem_w_port, rx_port, tx_port]

        led1 = platform.request("user_led", 0)
        led2 = platform.request("user_led", 1)

        m.d.comb += [
            tx_port.addr.eq(0),
            tx_port.en.eq(0),
            tx_port.data.eq(0),
            rx_port.addr.eq(0),
        ]

        m.d.sync += [
            led1.eq(rx_port.data & 1),
            led2.eq((rx_port.data & 2) >> 1),
        ]

        with m.FSM():
            with m.State("IDLE"):
                m.d.sync += self.transmit_packet.eq(0)
                with m.If(self.packet_received):
                    m.next = "RX"
            with m.State("RX"):
                with m.If(self.transmit_ready):
                    m.d.sync += self.transmit_packet.eq(1)
                    m.next = "IDLE"

        return m
예제 #18
0
파일: formal_jmp.py 프로젝트: Lerking/n6800
    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]),
            ]
예제 #19
0
    def elaborate(self, platform):
        m = Module()
        mac = [Signal(8) for _ in range(6)]

        m.d.sync += self.mac_match.eq(
            reduce(operator.and_,
                   [(mac[idx] == self.mac_addr[idx]) | (mac[idx] == 0xFF)
                    for idx in range(6)]))

        with m.FSM():
            with m.State("RESET"):
                m.d.sync += [mac[idx].eq(0) for idx in range(6)]
                with m.If(~self.reset):
                    m.next = "BYTE0"

            for idx in range(6):
                next_state = f"BYTE{idx+1}" if idx < 5 else "DONE"

                with m.State(f"BYTE{idx}"):
                    m.d.sync += mac[idx].eq(self.data)
                    with m.If(self.reset):
                        m.next = "RESET"
                    with m.Elif(self.data_valid):
                        m.next = next_state

            with m.State("DONE"):
                with m.If(self.reset):
                    m.next = "RESET"

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

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

        #
        # Class request handlers.
        #

        with m.If(setup.type == USBRequestType.CLASS):
            with m.Switch(setup.request):

                # SET_LINE_CODING: The host attempts to tell us how it wants serial data
                # encoding. Since we output a stream, we'll ignore the actual line coding.
                with m.Case(self.SET_LINE_CODING):

                    # Always ACK the data out...
                    with m.If(interface.rx_ready_for_response):
                        m.d.comb += interface.handshakes_out.ack.eq(1)

                    # ... and accept whatever the request was.
                    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
예제 #21
0
파일: crc.py 프로젝트: ret/daqnet
    def elaborate(self, platform):

        m = Module()
        crc = Signal(32)

        self.crctable = Memory(32, 256, make_crc32_table())
        table_port = self.crctable.read_port()
        m.submodules += table_port

        m.d.comb += [
            self.crc_out.eq(crc ^ 0xFFFFFFFF),
            self.crc_match.eq(crc == 0xDEBB20E3),
            table_port.addr.eq(crc ^ self.data),
        ]

        with m.FSM():
            with m.State("RESET"):
                m.d.sync += crc.eq(0xFFFFFFFF)
                m.next = "IDLE"

            with m.State("IDLE"):
                with m.If(self.reset):
                    m.next = "RESET"
                with m.Elif(self.data_valid):
                    m.next = "BUSY"

            with m.State("BUSY"):
                with m.If(self.reset):
                    m.next = "RESET"
                m.d.sync += crc.eq(table_port.data ^ (crc >> 8))
                m.next = "IDLE"

        return m
예제 #22
0
    def handle_CSRRWI(self, m: Module):
        m.d.comb += self._funct12_to_csr_num.eq(1)

        with m.If(self._instr_phase == 0):
            with m.If(self.rd0):
                m.d.comb += [
                    self._x_reg_select.eq(InstrReg.ZERO),
                    self.reg_to_x.eq(1),
                ]
            with m.Else():
                m.d.comb += [self.csr_to_x.eq(1)]
            m.d.comb += [
                self.y_mux_select.eq(SeqMuxSelect.IMM),
                self.alu_op_to_z.eq(AluOp.Y),
                self.z_to_csr.eq(1),
                self.tmp_mux_select.eq(SeqMuxSelect.X),
                self._next_instr_phase.eq(1),
            ]

        with m.Else():
            m.d.comb += [
                self.z_mux_select.eq(SeqMuxSelect.TMP),
                self._z_reg_select.eq(InstrReg.RD),
            ]
            self.next_instr(m)
예제 #23
0
    def elaborate(self, platform):
        m = Module()
        interface = self.interface

        # Create convenience aliases for our interface components.
        setup = interface.setup
        handshake = interface.handshake

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

            # IDLE -- not handling any active request
            with m.State('IDLE'):

                # If we've received a new setup packet, handle it.
                # TODO: limit this to standard requests
                with m.If(setup.received):

                    # Select which standard packet we're going to handler.
                    m.next = 'UNHANDLED'

            # UNHANDLED -- we've received a request we're not prepared to handle
            with m.State('UNHANDLED'):

                # When we next have an opportunity to stall, do so,
                # and then return to idle.
                with m.If(interface.data_requested
                          | interface.status_requested):
                    m.d.comb += handshake.stall.eq(1)
                    m.next = 'IDLE'

        return m
예제 #24
0
 def read(self, m: Module, addr: Value, data: Value):
     if self.verification is None:
         return
     with m.If(self.snapshot_taken):
         with m.If(self.addresses_read != 7):
             m.d.ph1 += self.addresses_read.eq(self.addresses_read + 1)
             m.d.ph1 += self.read_addr[self.addresses_read].eq(addr)
             m.d.ph1 += self.read_data[self.addresses_read].eq(data)
예제 #25
0
    def elaborate(self, platform: Platform) -> Module:
        m = Module()

        # Signal defaults
        m.d.comb += self.ft.oe.o.eq(0)
        m.d.comb += self.ft.write.o.eq(0)
        m.d.comb += self.ft.read.o.eq(0)

        with m.FSM():
            with m.State("READY"):
                # If there is data to read, we read it first before entering the write state
                with m.If(self.ft.rxf.i):
                    m.d.comb += self.ft.oe.o.eq(1)

                    m.d.comb += self.ft.data.oe.eq(0)
                    m.d.comb += self.ft.be.oe.eq(0)

                    m.next = "READ"
                with m.Elif(self.ft.txe.i & self.input_valid):
                    m.d.comb += self.ft.data.oe.eq(1)
                    m.d.comb += self.ft.be.oe.eq(1)

                    m.next = "WRITE"

            with m.State("READ"):
                m.d.comb += self.ft.oe.o.eq(1)

                # Set pins in correct direction (input)
                m.d.comb += self.ft.data.oe.eq(0)
                m.d.comb += self.ft.be.oe.eq(0)

                # Connect FIFO
                m.d.comb += self.output_payload.eq(self.ft.data.i)
                m.d.comb += self.output_valid.eq(self.ft.rxf.i)
                m.d.comb += self.ft.read.o.eq(self.output_ready)

                with m.If(~self.ft.rxf.i):
                    m.next = "READY"

            with m.State("WRITE"):
                # Set pins in correct direction (output)
                m.d.comb += self.ft.data.oe.eq(1)
                m.d.comb += self.ft.be.oe.eq(1)

                # All bytes are valid
                m.d.comb += self.ft.oe.o.eq(0)
                m.d.comb += self.ft.be.o.eq(0b11)

                # Connect FIFO
                m.d.comb += self.ft.data.o.eq(self.input_payload)
                m.d.comb += self.input_ready.eq(self.ft.txe.i)
                m.d.comb += self.ft.write.o.eq(self.input_valid)

                # TODO: Should we go to ready if there is data to read, or wait until write is done?
                with m.If(~self.ft.txe.i | ~self.input_valid):
                    m.next = "READY"

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

        # pins
        ft_clkout_i = platform.request("ft_clkout_i")
        ft_wr_n_o = platform.request("ft_wr_n_o")
        ft_txe_n_i = platform.request("ft_txe_n_i")
        ft_suspend_n_i = platform.request("ft_suspend_n_i")
        ft_oe_n_o = platform.request("ft_oe_n_o")
        ft_rd_n_o = platform.request("ft_rd_n_o")
        ft_siwua_n_o = platform.request("ft_siwua_n_o")
        ft_data_io = platform.request("ft_data_io")
        ext1 = platform.request("ext1")
        pa_en_n_o = platform.request("pa_en_n_o")

        # clock domains
        m.domains += ClockDomain("clk60")
        m.d.comb += ClockSignal("clk60").eq(ft_clkout_i.i)

        # signals
        ctr = Signal(8, reset=0)
        ctr_last = Signal(8, reset=0)
        ft_txe_last = Signal(1, reset=0)

        # submodules
        m.submodules.fifo = fifo = AsyncFIFO(width=8,
                                             depth=1024,
                                             r_domain="clk60",
                                             w_domain="sync")

        # logic
        m.d.comb += [
            ft_oe_n_o.o.eq(1),
            ft_rd_n_o.o.eq(1),
            ft_siwua_n_o.o.eq(1),
            ft_data_io.oe.eq(1),
            pa_en_n_o.o.eq(1),
        ]

        m.d.comb += [
            ft_data_io.o.eq(fifo.r_data),
            fifo.w_data.eq(ctr),
        ]

        with m.If(fifo.w_rdy):
            m.d.comb += fifo.w_en.eq(1)
            m.d.sync += ctr.eq(ctr + 1)
        with m.Else():
            m.d.comb += fifo.w_en.eq(0)

        with m.If(~ft_txe_n_i & ft_suspend_n_i & fifo.r_rdy):
            m.d.comb += ft_wr_n_o.o.eq(0)
            m.d.clk60 += fifo.r_en.eq(1)
        with m.Else():
            m.d.comb += ft_wr_n_o.o.eq(1)
            m.d.clk60 += fifo.r_en.eq(0)

        return m
예제 #27
0
 def write(self, m: Module, addr: Value, data: Value):
     if self.verification is None:
         return
     with m.If(self.snapshot_taken):
         with m.If(self.addresses_written != 7):
             m.d.ph1 += self.addresses_written.eq(self.addresses_written +
                                                  1)
             m.d.ph1 += self.write_addr[self.addresses_written].eq(addr)
             m.d.ph1 += self.write_data[self.addresses_written].eq(data)
예제 #28
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]
예제 #29
0
    def formal(cls) -> Tuple[Module, List[Signal]]:
        """Formal verification for the active low 74182 chip."""
        m = Module()
        m.submodules.clu = clu = IC_74182_active_low()

        # Verify the truth tables in the datasheet

        with m.If(clu.np.matches("0000")):
            m.d.comb += Assert(clu.group_np == 0)
        with m.Else():
            m.d.comb += Assert(clu.group_np == 1)

        with m.If(clu.ng.matches("0---") & clu.np.matches("----")):
            m.d.comb += Assert(clu.group_ng == 0)
        with m.Elif(clu.ng.matches("-0--") & clu.np.matches("0---")):
            m.d.comb += Assert(clu.group_ng == 0)
        with m.Elif(clu.ng.matches("--0-") & clu.np.matches("00--")):
            m.d.comb += Assert(clu.group_ng == 0)
        with m.Elif(clu.ng.matches("---0") & clu.np.matches("000-")):
            m.d.comb += Assert(clu.group_ng == 0)
        with m.Else():
            m.d.comb += Assert(clu.group_ng == 1)

        with m.If(clu.ng[0] == 0):
            m.d.comb += Assert(clu.carryout_x == 1)
        with m.Elif((clu.np[0] == 0) & (clu.carryin == 1)):
            m.d.comb += Assert(clu.carryout_x == 1)
        with m.Else():
            m.d.comb += Assert(clu.carryout_x == 0)

        with m.If(clu.ng.matches("--0-") & clu.np.matches("----")):
            m.d.comb += Assert(clu.carryout_y == 1)
        with m.Elif(clu.ng.matches("---0") & clu.np.matches("--0-")):
            m.d.comb += Assert(clu.carryout_y == 1)
        with m.Elif(
                clu.ng.matches("----") & clu.np.matches("--00")
                & (clu.carryin == 1)):
            m.d.comb += Assert(clu.carryout_y == 1)
        with m.Else():
            m.d.comb += Assert(clu.carryout_y == 0)

        with m.If(clu.ng.matches("-0--") & clu.np.matches("----")):
            m.d.comb += Assert(clu.carryout_z == 1)
        with m.Elif(clu.ng.matches("--0-") & clu.np.matches("-0--")):
            m.d.comb += Assert(clu.carryout_z == 1)
        with m.Elif(clu.ng.matches("---0") & clu.np.matches("-00-")):
            m.d.comb += Assert(clu.carryout_z == 1)
        with m.Elif(
                clu.ng.matches("----") & clu.np.matches("-000")
                & (clu.carryin == 1)):
            m.d.comb += Assert(clu.carryout_z == 1)
        with m.Else():
            m.d.comb += Assert(clu.carryout_z == 0)

        return m, clu.ports()
예제 #30
0
파일: rmii.py 프로젝트: ret/daqnet
    def elaborate(self, platform):
        m = Module()

        # Register input data on the data_valid signal
        data_reg = Signal(8)

        with m.FSM() as fsm:
            m.d.comb += [
                self.ready.eq(fsm.ongoing("IDLE") | fsm.ongoing("NIBBLE4")),
                self.txen.eq(~fsm.ongoing("IDLE")),
            ]

            with m.State("IDLE"):
                m.d.comb += [
                    self.txd0.eq(0),
                    self.txd1.eq(0),
                ]
                m.d.sync += data_reg.eq(self.data)
                with m.If(self.data_valid):
                    m.next = "NIBBLE1"

            with m.State("NIBBLE1"):
                m.d.comb += [
                    self.txd0.eq(data_reg[0]),
                    self.txd1.eq(data_reg[1]),
                ]
                m.next = "NIBBLE2"

            with m.State("NIBBLE2"):
                m.d.comb += [
                    self.txd0.eq(data_reg[2]),
                    self.txd1.eq(data_reg[3]),
                ]
                m.next = "NIBBLE3"

            with m.State("NIBBLE3"):
                m.d.comb += [
                    self.txd0.eq(data_reg[4]),
                    self.txd1.eq(data_reg[5]),
                ]
                m.next = "NIBBLE4"

            with m.State("NIBBLE4"):
                m.d.comb += [
                    self.txd0.eq(data_reg[6]),
                    self.txd1.eq(data_reg[7]),
                ]
                m.d.sync += data_reg.eq(self.data)
                with m.If(self.data_valid):
                    m.next = "NIBBLE1"
                with m.Else():
                    m.next = "IDLE"

        return m