Exemplo n.º 1
0
    def formal(cls) -> Tuple[Module, List[Signal]]:
        """Formal verification for the ToPennies module."""
        m = Module()
        m.submodules.to_pennies = to_pennies = cls()

        m.d.comb += Cover((to_pennies.pennies == 37) &
                          (to_pennies.nickels == 3) &
                          (to_pennies.dimes == 10) &
                          (to_pennies.quarters == 5) &
                          (to_pennies.dollars == 2))

        m.d.comb += Cover(to_pennies.pennies_out == 548)

        m.d.comb += Cover((to_pennies.pennies_out == 64) &
                          (to_pennies.nickels == 2 * to_pennies.dimes) &
                          (to_pennies.dimes > 0))

        m.d.comb += Assert((to_pennies.pennies_out % 5)
                           == (to_pennies.pennies % 5))

        with m.If(to_pennies.pennies == 0):
            m.d.comb += Assert((to_pennies.pennies % 5) == 0)

        return m, [to_pennies.pennies, to_pennies.nickels, to_pennies.dimes,
                   to_pennies.quarters, to_pennies.dollars]
Exemplo n.º 2
0
    def formal(cls) -> Tuple[Module, List[Signal]]:
        """Formal verification for the shifter."""
        m = Module()
        m.submodules.shifter = shifter = ShiftCard()

        shamt = Signal(5)
        m.d.comb += shamt.eq(shifter.data_y[:5])

        with m.If(shamt > 0):
            m.d.comb += Cover(shifter.data_z == 0xFFFFAAA0)

        with m.Switch(shifter.alu_op):
            with m.Case(AluOp.SLL):
                m.d.comb += Assert(
                    shifter.data_z == (shifter.data_x << shamt)[:32])

            with m.Case(AluOp.SRL):
                m.d.comb += Assert(shifter.data_z == (shifter.data_x >> shamt))

            with m.Case(AluOp.SRA):
                m.d.comb += Assert(
                    shifter.data_z == (shifter.data_x.as_signed() >> shamt))

            with m.Default():
                m.d.comb += Assert(shifter.data_z == 0)

        return m, [
            shifter.alu_op, shifter.data_x, shifter.data_y, shifter.data_z
        ]
Exemplo n.º 3
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]
Exemplo n.º 4
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"]),
    )
Exemplo n.º 5
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 <= 9))
        m.d.comb += Cover(c.count == 3)

        return m, []
Exemplo n.º 6
0
    def formal(cls) -> Tuple[Module, List[Signal]]:
        """Formal verification for my module."""
        m = Module()
        m.submodules.my_class = my_class = cls()

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

        return m, [my_class.my_input]
Exemplo n.º 7
0
    def formal(cls) -> Tuple[Module, List[Signal]]:
        """Formal verification for the Cell4x4 module."""
        m = Module()
        m.submodules.c = c = cls()

        m.d.comb += Cover((c.output[0] == c.input[5])
                          & (c.output[1] == c.input[6])
                          & (c.output[2] == c.input[9])
                          & (c.output[3] == c.input[10]) & (c.output != 0))

        with m.If((c.output == 0b1111) & (c.input[5:7] == 0b11)
                  & (c.input[9:11] == 0b11)):
            m.d.comb += Assert(c.input == 0b0000011001100000)
        return m, [c.input]
    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]
Exemplo n.º 9
0
    def formal(cls) -> Tuple[Module, List[Signal]]:
        """Formal verification for the transparent latch.

        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 transparent latch.
        """
        m = Module()
        m.submodules.latch = latch = TransparentLatch(32)

        m.d.sync += Cover((latch.data_out == 0xAAAAAAAA) & (latch.le == 0)
                          & (Past(latch.data_out, 2) == 0xBBBBBBBB)
                          & (Past(latch.le, 2) == 0))

        with m.If(latch.n_oe == 1):
            m.d.comb += Assert(latch.data_out == 0)

        with m.If((latch.n_oe == 0) & (latch.le == 1)):
            m.d.comb += Assert(latch.data_out == latch.data_in)

        with m.If((latch.n_oe == 0) & Fell(latch.le)):
            m.d.sync += Assert(latch.data_out == Past(latch.data_in))

        return m, [latch.data_in, latch.le, latch.n_oe]
Exemplo n.º 10
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]
Exemplo n.º 11
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
Exemplo n.º 12
0
    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()]
        )

    else:
        # Fake memory
        mem = {
            0x0000: 0x5F,
            0x1000: 0x12,
            0x2000: 0x34,
            0x1234: 0x5F,
            0x1334: 0x00,
def verification_statements(m):
    #Create Local Reference to the LDPC_Encoder
    LDPC_Encoder = m.submodules.LDPC_Encoder

    #Ensure all codewords can be obtained
    m.d.sync += Cover((LDPC_Encoder.data_output == 0b000000))
    m.d.sync += Cover((LDPC_Encoder.data_output == 0b011001))
    m.d.sync += Cover((LDPC_Encoder.data_output == 0b110010))
    m.d.sync += Cover((LDPC_Encoder.data_output == 0b101011))
    m.d.sync += Cover((LDPC_Encoder.data_output == 0b111100))
    m.d.sync += Cover((LDPC_Encoder.data_output == 0b100101))
    m.d.sync += Cover((LDPC_Encoder.data_output == 0b001110))
    m.d.sync += Cover((LDPC_Encoder.data_output == 0b010111))

    #Ensure invalid codewords cannot be obtained
    m.d.sync += Cover((LDPC_Encoder.data_output != 0b111111))

    #Ensure the correct codeword output is obtained for each input word.
    m.d.sync += Cover((LDPC_Encoder.data_input == 0b000)
                      & (LDPC_Encoder.data_output == 0b000000))
    m.d.sync += Cover((LDPC_Encoder.data_input == 0b011)
                      & (LDPC_Encoder.data_output == 0b011001))
    m.d.sync += Cover((LDPC_Encoder.data_input == 0b110)
                      & (LDPC_Encoder.data_output == 0b110010))
    m.d.sync += Cover((LDPC_Encoder.data_input == 0b101)
                      & (LDPC_Encoder.data_output == 0b101011))
    m.d.sync += Cover((LDPC_Encoder.data_input == 0b111)
                      & (LDPC_Encoder.data_output == 0b111100))
    m.d.sync += Cover((LDPC_Encoder.data_input == 0b100)
                      & (LDPC_Encoder.data_output == 0b100101))
    m.d.sync += Cover((LDPC_Encoder.data_input == 0b001)
                      & (LDPC_Encoder.data_output == 0b001110))
    m.d.sync += Cover((LDPC_Encoder.data_input == 0b010)
                      & (LDPC_Encoder.data_output == 0b010111))
    m.d.sync += Cover((LDPC_Encoder.data_input == 0b011)
                      & (LDPC_Encoder.data_output != 0b010111))

    #Ensure that done and output signals are reset when start is toggled.
    with m.If((LDPC_Encoder.start == 0) & Past(LDPC_Encoder.start)):
        m.d.sync += Assert((LDPC_Encoder.done == 0))
        m.d.sync += Assert((LDPC_Encoder.data_output == 0))

    return
Exemplo n.º 14
0
from nmigen.asserts import Assert, Cover, Fell, Past, Rose, Stable
from nmigen.cli import main_parser, main_runner

from bin2dec import *


if __name__ == '__main__':
    parser = main_parser()
    args = parser.parse_args()

    b2d = Bin2Dec(8)

    m = Module()
    m.submodules.b2d = b2d

    m.d.comb += Cover(b2d.o_digit_rd == 1)
    m.d.comb += Cover(b2d.o_conv_rd == 1)

    # o_digit_rd is a 1-cycle strobe
    with m.If((Past(b2d.o_digit_rd, 2) == 0) & (Past(b2d.o_digit_rd, 1) == 1)):
        m.d.comb += Assert(b2d.o_digit_rd == 0)

    # i_bin_stb resets all outputs
    with m.If(Past(b2d.i_bin_stb) == 1):
        m.d.comb += Assert(b2d.o_digit == 0)
        m.d.comb += Assert(b2d.o_digit_rd == 0)
        m.d.comb += Assert(b2d.o_conv_rd == 0)

    # o_digit is stable if o_digit_rd is low
    with m.If((Past(ResetSignal()) == 0) & (Past(b2d.i_bin_stb) == 0) & (b2d.o_digit_rd == 0)):
        m.d.comb += Assert(Stable(b2d.o_digit))
Exemplo n.º 15
0
        out_carry = alu._ccs[Flags.C]

        in1_dec = 10 * in1_hi + in1_lo
        in2_dec = 10 * in2_hi + in2_lo
        out_dec = 100 * out_carry + 10 * out_hi + out_lo

        m.d.ph1 += [
            Assume(Past(alu.func) == ALU8Func.ADC),
            Assume(alu.func == ALU8Func.DAA),
            Assume(alu.input1 == Past(alu.output)),
            Assume(in1_lo < 10),
            Assume(in1_hi < 10),
            Assume(in2_lo < 10),
            Assume(in2_hi < 10),
        ]

        m.d.ph1 += [
            Assert((in1_dec + in2_dec + in_carry) == out_dec),
            Assert(alu._ccs[Flags.N] == alu.output[7]),
            Assert(alu._ccs[Flags.Z] == (alu.output == 0)),
        ]

        m.d.ph1 += Cover(out_dec == 142)

    main_runner(
        parser,
        args,
        m,
        ports=alu.input_ports() + alu2.input_ports() + [ph1clk, rst, test_daa],
    )
Exemplo n.º 16
0
def build_formal(bld: Builder):
    m = Module()

    in_data = AnySeq(8)
    en_data = AnySeq(1)
    hsync = AnySeq(1)
    vsync = AnySeq(1)

    enc_char = Signal(10)

    real_chr_bias = Signal(signed(5))
    real_dc_bias = Signal(signed(5))

    m.submodules.enc = enc = TMDSEncoder()
    m.submodules.dec = dec = TMDSDecoder()

    m.d.comb += [
        enc.i_data.eq(in_data),
        enc.i_en_data.eq(en_data),
        enc.i_hsync.eq(hsync),
        enc.i_vsync.eq(vsync),
        dec.i_char.eq(enc.o_char),
        enc_char.eq(enc.o_char),
    ]

    m.d.comb += [
        real_chr_bias.eq(popcount(enc.o_char) - 5),
        Assert(real_dc_bias >= -5),
        Assert(real_dc_bias <= +5),
        Assert(real_dc_bias[:4] == enc.dc_bias),
    ]
    m.d.sync += [
        real_dc_bias.eq(real_dc_bias + real_chr_bias),
    ]

    with m.If(~enc.i_en_data):
        m.d.sync += real_dc_bias.eq(real_dc_bias)

    m.d.comb += Cover(
        (Past(dec.o_en_data, 4) & (Past(enc.o_char, 4)[8:10] == 0b00))
        & (Past(dec.o_en_data, 3) & (Past(enc.o_char, 3)[8:10] == 0b01))
        & (Past(dec.o_en_data, 2) & (Past(enc.o_char, 2)[8:10] == 0b10))
        & (Past(dec.o_en_data, 1) & (Past(enc.o_char, 1)[8:10] == 0b11))
        & (dec.o_vsync))

    m.d.comb += Assert(dec.o_en_data == enc.i_en_data)
    with m.If(dec.o_en_data):
        m.d.comb += Assert(dec.o_data == enc.i_data)

        # Check that XNOR choice matches reference algorithm
        in_pop = Signal(4)
        use_xnor = Signal()
        m.d.comb += [
            in_pop.eq(popcount(in_data)),
            use_xnor.eq((in_pop > 4) | ((in_pop == 4) & (in_data[0] == 0))),
            Assert(enc.o_char[8] == ~use_xnor),
        ]

    with m.Else():
        m.d.comb += [
            Assert(dec.o_hsync == enc.i_hsync),
            Assert(dec.o_vsync == enc.i_vsync),
        ]

    with bld.temp_open("formal.il") as f:
        il_text = rtlil.convert(m,
                                ports=[enc_char, real_chr_bias, real_dc_bias])
        f.write(il_text)
Exemplo n.º 17
0
    m.domains.ph1 = ph1 = ClockDomain("ph1")

    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
Exemplo n.º 18
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]