Ejemplo n.º 1
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]
Ejemplo n.º 2
0
def cover_pending_counter(bld: Builder):
    m = Module()

    m.submodules.pc = pc = PendingCounter(3, 5)

    was_full = Signal()
    was_emptied = Signal()

    m.d.comb += pc.i_remove.eq(AnySeq(1))
    m.d.comb += Assume(~(pc.i_remove & ~pc.o_any))
    m.d.comb += Assume(~(~pc.i_remove & pc.o_full))

    with m.If(pc.o_full):
        m.d.sync += was_full.eq(1)
    with m.If(~pc.o_any & was_full):
        m.d.sync += was_emptied.eq(1)
    m.d.comb += Cover(was_emptied)

    with bld.temp_open("formal.il") as f:
        il_text = rtlil.convert(m, ports=[pc.pending, pc.timer])
        f.write(il_text)

    sby.verify(
        bld,
        "formal.sby",
        "formal.il",
        sby.Task("sby", "cover", depth=40, engines=["smtbmc", "yices"]),
    )
Ejemplo n.º 3
0
 def elaborate(self, platform):
     m = Module()
     MAX_AMOUNT = Const(22)
     with m.If(self.i_reset):
         m.d.sync += self.counter.eq(0)
     with m.Elif(self.i_start_signal & (self.counter == 0)):
         m.d.sync += self.counter.eq(MAX_AMOUNT - 1)
     with m.Elif(self.counter != 0):
         m.d.sync += self.counter.eq(self.counter - 1)
     m.d.sync += self.o_busy.eq((~self.i_reset) & \
      ((self.i_start_signal & (self.counter == 0)) | \
      (self.counter > 1)))
     if self.fv_mode:
         f_past_valid = Signal(1, reset=0)
         m.d.sync += f_past_valid.eq(1)
         m.d.comb += Assert(self.counter < MAX_AMOUNT)
         with m.If(f_past_valid & Past(self.i_start_signal)
                   & Past(self.o_busy)):
             m.d.comb += Assume(self.i_start_signal)
         with m.Elif(f_past_valid & Past(self.i_start_signal)
                     & ~Past(self.o_busy)):
             m.d.comb += Assume(~self.i_start_signal)
         m.d.comb += Assert(self.o_busy == (self.counter != 0))
         with m.If(f_past_valid & Past(self.counter) != 0):
             m.d.comb += Assert(self.counter < Past(self.counter))
     return m
Ejemplo n.º 4
0
    def elaborate(self, platform):
        m = Module()

        m.submodules.dut = dut = _DelayLine(self.delay)
        m.d.comb += Assume(~ResetSignal("sync"))
        m.d.comb += Assert(
            dut.o == Sample(expr=dut.i, clocks=self.delay, domain="sync"))

        return m
Ejemplo n.º 5
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]
Ejemplo n.º 6
0
def bmc_pending_counter(bld: Builder):
    m = Module()

    m.submodules.pc = pc = PendingCounter(3, 5)

    m.d.comb += pc.i_remove.eq(AnySeq(1))
    m.d.comb += Assume(~(pc.i_remove & ~pc.o_any))
    m.d.comb += Assume(~(~pc.i_remove & pc.o_full))

    with bld.temp_open("formal.il") as f:
        il_text = rtlil.convert(m, ports=[pc.pending, pc.timer])
        f.write(il_text)

    sby.verify(
        bld,
        "formal.sby",
        "formal.il",
        sby.Task("sby", "bmc", depth=40, engines=["smtbmc", "yices"]),
    )
Ejemplo n.º 7
0
    def verify_jtype(self, m):

        sig = self.build_signal(m, "U", [(0, 6, "1001011"), (7, 11, "10000"),
                                         (12, 19, "00100010"), (20, 20, "1"),
                                         (21, 30, "1011000111"),
                                         (31, 31, "1")])

        j = JType("jtype")
        j.elaborate(m.d.comb, sig)
        m.d.comb += Assert(j.opcode == Const(0b1001011, 7))
        m.d.comb += Assert(j.rd == Const(0b10000, 5))
        m.d.comb += Assert(
            j.imm == Const(0b1111_1111_1111_0010_0010_1101_1000_1110, 32))

        m.d.comb += Assert(j.match(opcode=0b1001011))
        m.d.comb += Assert(j.match(opcode=0b1001010) == 0)
        m.d.comb += Assert(j.match(rd=0b10000))
        m.d.comb += Assert(j.match(rd=0b00001) == 0)
        m.d.comb += Assert(
            j.match(imm=0b1111_1111_1111_0010_0010_1101_1000_1110)
        )  #extra bits - sign ext

        m.d.comb += Assert(j.match(imm=0b110100010110110001110) == 0)
        m.d.comb += Assert(
            j.match(opcode=0b1001011,
                    rd=0b10000,
                    imm=0b1111_1111_1111_0010_0010_1101_1000_1110))

        j_builder_check = Signal(32)
        j_builder_opcode = Signal(7)
        j_builder_rd = Signal(5)
        j_builder_imm = Signal(21)
        m.d.comb += Assume(j_builder_imm[0] == 0)

        built_jtype = JType.build_i32(opcode=j_builder_opcode,
                                      rd=j_builder_rd,
                                      imm=j_builder_imm)
        m.d.comb += j_builder_check.eq(built_jtype)
        j = JType("jtype.build")
        j.elaborate(m.d.comb, built_jtype)
        m.d.comb += Assert(j_builder_opcode == j.opcode)
        m.d.comb += Assert(j_builder_rd == j.rd)
        m.d.comb += Assert(j_builder_imm == j.imm[0:21])

        j = JType("jtype.se")
        j.elaborate(m.d.comb, Const(0x8000_0000, 32))
        m.d.comb += Assert(j.imm[20] == 1)
        m.d.comb += Assert(j.imm[31] == 1)

        j = JType("jtype.ze")
        j.elaborate(m.d.comb, Const(0x7FFF_FFFF, 32))
        m.d.comb += Assert(j.imm[20] == 0)
        m.d.comb += Assert(j.imm[31] == 0)

        return [j_builder_check, j_builder_opcode, j_builder_rd, j_builder_imm]
Ejemplo n.º 8
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
        ]
Ejemplo n.º 9
0
    def formal(cls) -> Tuple[Module, List[Signal]]:
        """Formal verification for my module."""
        m = Module()
        m.submodules.my_class = my_class = cls()

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

        # Make sure that the output is always the same as the input
        m.d.comb += Assert(my_class.my_input == my_class.my_output)

        # Cover the case where the output is 1.
        m.d.comb += Cover(my_class.my_output == 1)

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

        # Include this only if you don't want to test resets
        m.d.comb += Assume(~sync_rst)

        # Ensure sync's clock and reset signals are manipulable.
        return m, [sync_clk, sync_rst, my_class.my_input]
Ejemplo n.º 10
0
    def formal(cls) -> Tuple[Module, List[Signal]]:
        """Formal verification for the Counter module."""
        m = Module()
        m.submodules.c = c = cls()

        m.d.comb += Assert((c.count >= 1) & (c.count <= 999_999_999_999))

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

        with m.If(Rose(sync_clk) & ~Initial()):
            with m.If(c.count == 1):
                m.d.comb += Assert(Past(c.count) == 999_999_999_999)
            with m.Else():
                m.d.comb += Assert(c.count == (Past(c.count) + 1))

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

        return m, [sync_clk, sync_rst]
Ejemplo n.º 11
0
    def verify_utype(self, m):
        sig = self.build_signal(m, "U", [(0, 6, "1001011"), (7, 11, "10000"),
                                         (12, 31, "00100010000110111111")])
        u = UType("utype")
        u.elaborate(m.d.comb, sig)
        m.d.comb += Assert(u.opcode == Const(0b1001011, 7))
        m.d.comb += Assert(u.rd == Const(0b10000, 5))
        m.d.comb += Assert(
            u.imm == Const(0b00100010000110111111000000000000, 32))

        m.d.comb += Assert(u.match(opcode=0b1001011))
        m.d.comb += Assert(u.match(rd=0b10000))
        m.d.comb += Assert(u.match(imm=0b00100010000110111111000000000000))

        m.d.comb += Assert(u.match(opcode=0b1011011) == 0)
        m.d.comb += Assert(u.match(rd=0b11000) == 0)
        m.d.comb += Assert(
            u.match(imm=0b10100010000110111111000000000000) == 0)

        m.d.comb += Assert(
            u.match(opcode=0b1001011,
                    rd=0b10000,
                    imm=0b00100010000110111111000000000000))

        u = UType("utype.sign")
        u.elaborate(m.d.comb, Const(0x8000_0000, 32))
        m.d.comb += Assert(u.imm[31] == 1)

        u = UType("utype.trailzero")
        u.elaborate(m.d.comb, Const(0xFFFF_FFFF, 32))
        m.d.comb += Assert(u.imm.bit_select(0, 12) == 0)

        u_builder_check = Signal(32)
        u_builder_opcode = Signal(7)
        u_builder_rd = Signal(5)
        u_builder_imm = Signal(20)
        m.d.comb += Assume(u_builder_imm[0:12] == 0)

        built_utype = UType.build_i32(opcode=u_builder_opcode,
                                      rd=u_builder_rd,
                                      imm=u_builder_imm)
        m.d.comb += u_builder_check.eq(built_utype)
        u = UType("utype.build")
        u.elaborate(m.d.comb, built_utype)
        m.d.comb += Assert(u_builder_opcode == u.opcode)
        m.d.comb += Assert(u_builder_rd == u.rd)
        m.d.comb += Assert(Cat(Repl(0, 12), u_builder_imm[12:32]) == u.imm)

        return [u_builder_check, u_builder_opcode, u_builder_rd, u_builder_imm]
Ejemplo n.º 12
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_reg32_with_mux(clk="ph", N=2, faster=True)

        m.submodules += s

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

        with m.If(Rose(clk)):
            with m.Switch(~Past(s.n_sel)):
                with m.Case(0b11):
                    m.d.comb += Assert(0)
                with m.Case(0b01):
                    m.d.comb += Assert(s.q == Past(s.d[0]))
                with m.Case(0b10):
                    m.d.comb += Assert(s.q == Past(s.d[1]))
                with m.Default():
                    m.d.comb += Assert(s.q == Past(s.q))

        # 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"))

        m.d.comb += Assume(s.n_sel != 0)

        return m, [sync_clk, sync_rst, s.d[0], s.d[1], s.n_sel, s.q]
Ejemplo n.º 13
0
    def formal(cls) -> Tuple[Module, List[Signal]]:
        """Formal verification for the active high 74182 chip.

        Used with an active high 74181.
        """
        m = Module()
        m.submodules.clu = clu = IC_74182_active_high()
        m.submodules.alu = alu = IC_74181()

        add_mode = (alu.s == 9) & (alu.m == 0)
        m.d.comb += Assume(add_mode)

        m.d.comb += [
            clu.x[0].eq(alu.x),
            clu.y[0].eq(alu.y),
            clu.x[1:].eq(0),
            clu.y[1:].eq(0),
            clu.n_carryin.eq(alu.n_carryin),
        ]

        m.d.comb += Assert(clu.n_carryout_x == alu.n_carryout)

        return m, clu.ports() + alu.ports()
Ejemplo n.º 14
0
    m.submodules.alu = alu = ALU8()
    m.domains.ph1 = ph1 = ClockDomain("ph1")

    rst = Signal()
    ph1clk = ClockSignal("ph1")
    ph1.rst = rst

    test_daa = Signal()
    m.submodules.alu2 = alu2 = ALU8()

    carry_in = Signal()
    sum9 = Signal(9)
    sum8 = Signal(8)
    sum5 = Signal(5)

    m.d.ph1 += Assume(rst == 0)
    m.d.comb += Assert(alu._ccs[6:] == 0b11)

    with m.If((~test_daa) | ~Past(test_daa)):
        with m.Switch(alu.func):
            with m.Case(ALU8Func.ADD, ALU8Func.ADC):
                # sumN = input1[:N] + input2[:N] (so sumN[N-1] is the carry bit)
                with m.If(alu.func == ALU8Func.ADD):
                    m.d.comb += carry_in.eq(0)
                with m.Else():
                    m.d.comb += carry_in.eq(alu.ccs[Flags.C])
                h = sum5[4]
                n = sum9[7]
                c = sum9[8]
                z = sum9[:8] == 0
                v = sum8[7] ^ c
Ejemplo n.º 15
0
    def check(self, m: Module):
        self.assert_cycles(m, 2)
        input1 = self.data.pre_a
        pre_h = self.data.pre_ccs[Flags.H]
        pre_c = self.data.pre_ccs[Flags.C]
        lo = input1[:4]
        hi = input1[4:]

        with m.If(pre_h):
            m.d.comb += Assume(lo <= 3)
            with m.If(pre_c):
                m.d.comb += Assume(hi <= 3)

        # Conditions taken directly from Motorola 6800 Programming Reference Manual,
        # the DAA instruction operation table.

        # Conditions are: C before DAA, a condition on hi, H before DAA, a condition on lo.
        conds = Array(
            [
                Array([0, hi <= 9, 0, lo <= 9]),
                Array([0, hi <= 8, 0, lo >= 10]),
                Array([0, hi <= 9, 1, lo <= 3]),
                Array([0, hi >= 10, 0, lo <= 9]),
                Array([0, hi >= 9, 0, lo >= 10]),
                Array([0, hi >= 10, 1, lo <= 3]),
                Array([1, hi <= 2, 0, lo <= 9]),
                Array([1, hi <= 2, 0, lo >= 10]),
                Array([1, hi <= 3, 1, lo <= 3]),
            ]
        )

        # Results are: DAA adjustment, state of C after DAA
        results = Array(
            [
                Array([0, 0]),
                Array([6, 0]),
                Array([6, 0]),
                Array([0x60, 1]),
                Array([0x66, 1]),
                Array([0x66, 1]),
                Array([0x60, 1]),
                Array([0x66, 1]),
                Array([0x66, 1]),
            ]
        )

        input_is_valid = Signal()
        expected_output = Signal(8)
        expected_c = Signal()

        for i in range(len(conds)):
            with m.If(
                (pre_c == conds[i][0])
                & conds[i][1]
                & (pre_h == conds[i][2])
                & conds[i][3]
            ):
                m.d.comb += input_is_valid.eq(1)
                m.d.comb += expected_output.eq(input1 + results[i][0])
                m.d.comb += expected_c.eq(results[i][1])

        z = expected_output == 0
        n = expected_output[7]

        with m.If(input_is_valid):
            self.assert_registers(m, A=expected_output, PC=self.data.pre_pc + 1)
            self.assert_flags(m, Z=z, N=n, C=expected_c)
Ejemplo n.º 16
0
    def formal(cls) -> Tuple[Module, List[Signal]]:
        """Formal verification for the async memory.

        Note that you MUST have multiclock on in the sby file, because there is
        more than one clock in the system -- the default formal clock and the
        local clock inside the memory.
        """
        m = Module()
        m.submodules.mem = mem = AsyncMemory(width=32, addr_lines=5)

        # Assume "good practices":
        # * n_oe and n_wr are never simultaneously 0, and any changes
        #   are separated by at least a cycle to allow buffers to turn off.
        # * memory address remains stable throughout a write cycle, and
        #   is also stable just before a write cycle.

        m.d.comb += Assume(mem.n_oe | mem.n_wr)

        # Paren placement is very important! While Python logical operators
        # and, or have lower precedence than ==, the bitwise operators
        # &, |, ^ have *higher* precedence. It can be confusing when it looks
        # like you're writing a boolean expression, but you're actually writing
        # a bitwise expression.
        with m.If(Fell(mem.n_oe)):
            m.d.comb += Assume((mem.n_wr == 1) & (Past(mem.n_wr) == 1))
        with m.If(Fell(mem.n_wr)):
            m.d.comb += Assume((mem.n_oe == 1) & (Past(mem.n_oe) == 1))
        with m.If(Rose(mem.n_wr) | (mem.n_wr == 0)):
            m.d.comb += Assume(Stable(mem.addr))

        m.d.comb += Cover((mem.data_out == 0xAAAAAAAA)
                          & (Past(mem.data_out) == 0xBBBBBBBB))

        # Make sure that when the output is disabled, the output is zero, and
        # when enabled, it's whatever we're pointing at in memory.
        with m.If(mem.n_oe == 1):
            m.d.comb += Assert(mem.data_out == 0)
        with m.Else():
            m.d.comb += Assert(mem.data_out == mem._mem[mem.addr])

        # If we just wrote data, make sure that cell that we pointed at
        # for writing now contains the data we wrote.
        with m.If(Rose(mem.n_wr)):
            m.d.comb += Assert(mem._mem[Past(mem.addr)] == Past(mem.data_in))

        # Pick an address, any address.
        check_addr = AnyConst(5)

        # We assert that unless that address is written, its data will not
        # change. To know when we've written the data, we have to create
        # a clock domain to let us save the data when written.

        saved_data_clk = ClockDomain("saved_data_clk")
        m.domains.saved_data_clk = saved_data_clk
        saved_data_clk.clk = mem.n_wr

        saved_data = Signal(32)
        with m.If(mem.addr == check_addr):
            m.d.saved_data_clk += saved_data.eq(mem.data_in)

        with m.If(Initial()):
            m.d.comb += Assume(saved_data == mem._mem[check_addr])
            m.d.comb += Assume(mem.n_wr == 1)
        with m.Else():
            m.d.comb += Assert(saved_data == mem._mem[check_addr])

        return m, [mem.addr, mem.data_in, mem.n_wr, mem.n_oe]
Ejemplo n.º 17
0
 def elaborate(self, platform):
     m = Module()
     m.d.comb += Assume(~dut.request_req)
     m.d.comb += Assert(~dut.request_gnt)
     return m
Ejemplo n.º 18
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
Ejemplo n.º 19
0

if __name__ == "__main__":
    parser = main_parser()
    parser.add_argument("--oper")
    args = parser.parse_args()

    oper: Optional[Operation] = None
    if args.oper is not None:
        oper = Operation[args.oper]

    m = Module()
    m.submodules.alu = alu = ALU_big(oper)

    if oper is not None:
        m.d.comb += Assume(~ResetSignal())
        m.d.comb += Assume(alu.oper == oper)
        main_runner(parser, args, m, ports=alu.ports())

    else:
        sim = Simulator(m)

        def process():
            yield
            yield alu.inputa.eq(0x12)
            yield alu.inputb.eq(0x34)
            yield alu.oper.eq(Operation.ADC)
            yield
            yield
            yield alu.inputa.eq(0x7F)
            yield alu.inputb.eq(0x7F)
Ejemplo n.º 20
0
	def elaborate(self, platform: str):
		#--------
		m = Module()

		#add_clk_domain(m, self.bus().clk)
		#add_clk_from_domain(m, self.bus.clk())
		#--------

		#--------
		# Local variables
		bus = self.bus()

		loc = Blank()

		loc.arr = Array([Signal(bus.shape_t()) for _ in range(bus.SIZE())])

		loc.PTR_WIDTH = width_from_arg(bus.SIZE())

		loc.rd = Signal(loc.PTR_WIDTH)
		loc.wr = Signal(loc.PTR_WIDTH)

		loc.RD_PLUS_1 = loc.rd + 0x1
		loc.WR_PLUS_1 = loc.wr + 0x1

		loc.incr_rd = Signal(loc.PTR_WIDTH)
		loc.incr_wr = Signal(loc.PTR_WIDTH)

		loc.next_empty = Signal()
		loc.next_full = Signal()

		loc.next_rd = Signal(loc.PTR_WIDTH)
		loc.next_wr = Signal(loc.PTR_WIDTH)

		loc.rst = ResetSignal("sync")

		#loc.curr_en_cat = Signal(2)

		if self.FORMAL():
			loc.formal = Blank()

			loc.formal.last_rd_val = Signal(bus.shape_t())
			loc.formal.test_wr = Signal(loc.PTR_WIDTH)
			#loc.formal.empty = Signal()
			#loc.formal.full = Signal()
			loc.formal.wd_cnt = Signal(bus.shape_t(), reset=0xa0)
		#--------

		#--------
		if self.FORMAL():
			m.d.sync \
			+= [
				loc.formal.last_rd_val.eq(loc.arr[loc.rd]),
				loc.formal.wd_cnt.eq(loc.formal.wd_cnt - 0x10)
			]
			m.d.comb \
			+= [
				loc.formal.test_wr.eq((loc.wr + 0x1) % bus.SIZE()),
			]
		#--------

		#--------
		# Combinational logic

		m.d.comb \
		+= [
			loc.incr_rd.eq(Mux(loc.RD_PLUS_1 < bus.SIZE(),
				(loc.rd + 0x1), 0x0)),
			loc.incr_wr.eq(Mux(loc.WR_PLUS_1 < bus.SIZE(),
				(loc.wr + 0x1), 0x0)),

			loc.next_empty.eq(loc.next_wr == loc.next_rd),
			#loc.next_full.eq((loc.next_wr + 0x1) == loc.next_rd),

			#loc.curr_en_cat.eq(Cat(bus.rd_en, bus.wr_en)),
		]

		with m.If(bus.rd_en & (~bus.empty)):
			m.d.comb += loc.next_rd.eq(loc.incr_rd)
		with m.Else():
			m.d.comb += loc.next_rd.eq(loc.rd)

		with m.If(bus.wr_en & (~bus.full)):
			m.d.comb \
			+= [
				loc.next_wr.eq(loc.incr_wr),
				loc.next_full.eq((loc.incr_wr + 0x1) == loc.next_rd),
			]
		with m.Else():
			m.d.comb \
			+= [
				loc.next_wr.eq(loc.wr),
				loc.next_full.eq(loc.incr_wr == loc.next_rd), 
			]
		#--------

		#--------
		# Clocked behavioral code
		with m.If(loc.rst):
			#for elem in loc.arr:
			#	m.d.sync += elem.eq(bus.shape_t()())

			m.d.sync \
			+= [
				loc.rd.eq(0x0),
				loc.wr.eq(0x0),

				#bus.rd_data.eq(bus.shape_t()()),

				bus.empty.eq(0b1),
				bus.full.eq(0b0),
			]
		with m.Else(): # If(~loc.rst):
			#--------
			m.d.sync \
			+= [
				bus.empty.eq(loc.next_empty),
				bus.full.eq(loc.next_full),
				loc.rd.eq(loc.next_rd),
				loc.wr.eq(loc.next_wr),
			]

			with m.If(bus.rd_en & (~bus.empty)):
				m.d.sync += bus.rd_data.eq(loc.arr[loc.rd])
			with m.If(bus.wr_en & (~bus.full)):
				m.d.sync += loc.arr[loc.wr].eq(bus.wr_data)
			#--------

			#--------
			if self.FORMAL():
				with m.If(Fell(loc.rst)):
					m.d.sync \
					+= [
						Assert(loc.rd == 0x0),
						Assert(loc.wr == 0x0),

						Assert(bus.empty == 0b1),
						Assert(bus.full == 0b0),
					]
				with m.Else(): # If(~Fell(loc.rst)):
					m.d.sync \
					+= [
						Assert(bus.empty == Past(loc.next_empty)),
						Assert(bus.full == Past(loc.next_full)),
						Assert(loc.rd == Past(loc.next_rd)),
						Assert(loc.wr == Past(loc.next_wr)),
					]
					with m.If(Past(bus.rd_en)):
						with m.If(Past(bus.empty)):
							m.d.sync \
							+= [
								#Assert(Stable(bus.empty)),
								Assert(Stable(loc.rd)),
							]
						with m.Else(): # If(~Past(bus.empty)):
							#with m.If(~Past(bus.wr_en)):
							m.d.sync \
							+= [
								Assert(bus.rd_data
									== loc.arr[Past(loc.rd)])
							]
					with m.If(Past(bus.wr_en)):
						with m.If(Past(bus.full)):
							m.d.sync \
							+= [
								Assert(Stable(loc.wr)),
							]
						#with m.Else(): # If(~Past(bus.full)):
						#	m.d.sync \
						#	+= [
						#		Assert(Past(bus.wr_data))
						#	]
					with m.Switch(Cat(bus.empty, bus.full)):
						with m.Case(0b00):
							m.d.sync \
							+= [
								Assume(loc.wr != loc.rd),
								Assume(loc.formal.test_wr != loc.rd),
							]
						with m.Case(0b01):
							m.d.sync \
							+= [
								Assert(loc.wr == loc.rd)
							]
						with m.Case(0b10):
							m.d.sync \
							+= [
								Assert(loc.formal.test_wr == loc.rd),
							]
					m.d.sync \
					+= [
						Assert(~(bus.empty & bus.full)),
						#Assume(~Stable(bus.wr_data)),
						#Assume(bus.wr_data == loc.formal.wd_cnt),
					]
			#--------
		#--------

		#--------
		return m
Ejemplo n.º 21
0
    instr: Optional[Instruction] = None
    if args.instr is not None:
        instr = getattr(modules["instruction.implemented"], args.instr.split(".")[0])
        instr = getattr(instr, args.instr.split(".")[1])
        if instr not in implemented.implemented:
            raise AttributeError()

    m = Module()
    m.submodules.core = core = Core(instr)

    if instr is not None:
        time = Signal(6, reset_less=True)
        m.d.sync += time.eq(time + 1)

        with m.If(Initial()):
            m.d.sync += Assume(ResetSignal())
        with m.Else():
            m.d.sync += Assume(~ResetSignal())

        # A time slot delayed because PC and addr need to sync
        with m.If(time == 2):
            m.d.sync += Assume(~core.snapshot.taken)
        with m.If(time == 3):
            m.d.sync += Cover(core.snapshot.taken)
            m.d.sync += Assume(core.snapshot.taken)
        m.d.sync += Cover(Fell(core.snapshot.taken))

        main_runner(
            parser, args, m, ports=core.ports() + [ClockSignal(), ResetSignal()]
        )
Ejemplo n.º 22
0
    rst = Signal()
    ph1clk = ClockSignal("ph1")
    ph1.rst = rst

    if verification is not None:
        # Cycle counter
        cycle2 = Signal(6, reset_less=True)
        m.d.ph1 += cycle2.eq(cycle2 + 1)

        # Force a reset
        # m.d.comb += Assume(rst == (cycle2 < 8))

        with m.If(cycle2 == 20):
            m.d.ph1 += Cover(core.formalData.snapshot_taken
                             & core.end_instr_flag)
            m.d.ph1 += Assume(core.formalData.snapshot_taken
                              & core.end_instr_flag)

        # Verify reset does what it's supposed to
        with m.If(Past(rst, 4) & ~Past(rst, 3) & ~Past(rst, 2) & ~Past(rst)):
            m.d.ph1 += Assert(Past(core.Addr, 2) == 0xFFFE)
            m.d.ph1 += Assert(Past(core.Addr) == 0xFFFF)
            m.d.ph1 += Assert(core.Addr[8:] == Past(core.Din, 2))
            m.d.ph1 += Assert(core.Addr[:8] == Past(core.Din))
            m.d.ph1 += Assert(core.Addr == core.pc)

        main_runner(parser, args, m, ports=core.ports() + [ph1clk, rst])

    else:
        # Fake memory
        mem = {
            0xFFFE: 0x12,
Ejemplo n.º 23
0
    def formal(cls) -> Tuple[Module, List[Signal]]:
        """Formal verification for the register card."""
        m = Module()

        ph1 = ClockDomain("ph1")
        ph2 = ClockDomain("ph2")
        regs = RegCard()

        m.domains += [ph1, ph2]
        m.submodules += regs

        # Generate the ph1 and ph2 clocks.
        cycle_count = Signal(8, reset=0, reset_less=True)
        phase_count = Signal(3, reset=0, reset_less=True)

        m.d.sync += phase_count.eq(phase_count + 1)
        with m.Switch(phase_count):
            with m.Case(0, 1, 2):
                m.d.comb += ph1.clk.eq(1)
            with m.Default():
                m.d.comb += ph1.clk.eq(0)
        with m.Switch(phase_count):
            with m.Case(1, 4):
                m.d.comb += ph2.clk.eq(0)
            with m.Default():
                m.d.comb += ph2.clk.eq(1)
        with m.If(phase_count == 5):
            m.d.sync += phase_count.eq(0)
            m.d.sync += cycle_count.eq(cycle_count + 1)

        # This is how we expect to use the card.
        with m.If(phase_count > 0):
            m.d.comb += [
                Assume(Stable(regs.reg_x)),
                Assume(Stable(regs.reg_y)),
                Assume(Stable(regs.reg_z)),
                Assume(Stable(regs.reg_page)),
                Assume(Stable(regs.reg_to_x)),
                Assume(Stable(regs.reg_to_y)),
                Assume(Stable(regs.data_z)),
            ]

        # Figure out how to get to the point where X and Y are nonzero and different.
        m.d.comb += Cover((regs.data_x != 0) & (regs.data_y != 0)
                          & (regs.data_x != regs.data_y))

        # X and Y buses should not change during a cycle, except for the first phase
        with m.Switch(phase_count):
            with m.Case(2, 3, 4, 5):
                with m.If(regs.data_x != 0):
                    m.d.comb += Assert(Stable(regs.data_x))
                with m.If(regs.data_y != 0):
                    m.d.comb += Assert(Stable(regs.data_y))

        # X and Y buses should be zero if there is no data transfer.
        with m.If(regs.reg_to_x == 0):
            m.d.comb += Assert(regs.data_x == 0)
        with m.If(regs.reg_to_y == 0):
            m.d.comb += Assert(regs.data_y == 0)

        with m.If(phase_count > 0):
            # X and Y buses should be zero if we read from register 0.
            with m.If(regs.reg_to_x & (regs.reg_x == 0)):
                m.d.comb += Assert(regs.data_x == 0)
            with m.If(regs.reg_to_y & (regs.reg_y == 0)):
                m.d.comb += Assert(regs.data_y == 0)

        write_pulse = Signal()
        m.d.comb += write_pulse.eq(phase_count != 4)

        # On write, the data should have been written to both banks.
        past_mem_addr = Signal(6)
        m.d.comb += past_mem_addr[:5].eq(Past(regs.reg_z))
        m.d.comb += past_mem_addr[5].eq(Past(regs.reg_page))
        past_z = Past(regs.data_z)
        with m.If(Rose(write_pulse)):
            m.d.comb += Assert(regs._x_bank._mem[past_mem_addr] == past_z)
            m.d.comb += Assert(regs._y_bank._mem[past_mem_addr] == past_z)

        # Pick an register, any register, except 0. We assert that unless
        # it is written, its data will not change.

        check_addr = AnyConst(5)
        check_page = AnyConst(1)
        saved_data = Signal(32)
        stored_x_data = Signal(32)
        stored_y_data = Signal(32)

        write_pulse_domain = ClockDomain("write_pulse_domain", local=True)
        m.domains.write_pulse_domain = write_pulse_domain
        write_pulse_domain.clk = write_pulse

        mem_addr = Signal(6)

        m.d.comb += Assume(check_addr != 0)
        m.d.comb += [
            mem_addr[:5].eq(check_addr),
            mem_addr[5].eq(check_page),
            stored_x_data.eq(regs._x_bank._mem[mem_addr]),
            stored_y_data.eq(regs._y_bank._mem[mem_addr]),
        ]

        with m.If((regs.reg_z == check_addr) & (regs.reg_page == check_page)):
            m.d.write_pulse_domain += saved_data.eq(regs.data_z)

        with m.If(Initial()):
            m.d.comb += Assume(saved_data == stored_x_data)
            m.d.comb += Assume(stored_x_data == stored_y_data)
        with m.Else():
            m.d.comb += Assert(saved_data == stored_x_data)
            m.d.comb += Assert(saved_data == stored_y_data)

        return m, [regs.data_z, regs.reg_to_x, regs.reg_to_y,
                   regs.reg_x, regs.reg_y, regs.reg_z, regs.reg_page, ph1.clk, ph2.clk, saved_data,
                   stored_x_data, stored_y_data]