Exemple #1
0
    def elaborate(self, platform: Platform) -> Module:
        m = Module()

        m.submodules.alu = self.alu = ALU()

        """Fetch the opcode, common for all instr"""
        m.d.sync += self.opcode.eq(Mux(self.cycle == 1, self.dout, self.opcode))

        with m.Switch(Mux(self.cycle == 1, self.dout, self.opcode)):
            for i in implemented.implemented:
                with m.Case(i.opcode):
                    i.synth(self, m)
            with m.Default():
                m.d.comb += core.alu.oper.eq(Operation.NOP)
                m.d.sync += [
                    core.reg.PC.eq(add16(core.reg.PC, 1)),
                    core.enable.eq(1),
                    core.addr.eq(add16(core.reg.PC, 1)),
                    core.RWB.eq(1),
                    core.cycle.eq(1),
                ]

        if self.verification is not None:
            self.verify(m)

            with m.If(Initial()):
                m.d.sync += [
                    self.reg.A.eq(AnyConst(8)),
                    self.reg.X.eq(AnyConst(8)),
                    self.reg.Y.eq(AnyConst(8)),
                    self.reg.SP.eq(AnyConst(16)),
                    self.reg.PC.eq(AnyConst(16)),
                ]
                m.d.sync += [
                    self.reg.PSW.N.eq(AnyConst(1)),
                    self.reg.PSW.V.eq(AnyConst(1)),
                    self.reg.PSW.P.eq(AnyConst(1)),
                    self.reg.PSW.B.eq(AnyConst(1)),
                    self.reg.PSW.H.eq(AnyConst(1)),
                    self.reg.PSW.I.eq(AnyConst(1)),
                    self.reg.PSW.Z.eq(AnyConst(1)),
                    self.reg.PSW.C.eq(AnyConst(1)),
                ]

        return m
Exemple #2
0
def build_formal_pipe(bld: Builder):
    m = Module()

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

    enc_char_comb = Signal(10)
    enc_char_pipe = Signal(10)

    m.submodules.enc_comb = enc_comb = TMDSEncoder(pipeline=False)
    m.submodules.enc_pipe = enc_pipe = TMDSEncoder(pipeline=True)

    m.d.comb += [
        enc_pipe.i_data.eq(in_data),
        enc_pipe.i_en_data.eq(en_data),
        enc_pipe.i_hsync.eq(hsync),
        enc_pipe.i_vsync.eq(vsync),
        enc_char_pipe.eq(enc_pipe.o_char),
    ]

    m.d.sync += [
        enc_comb.i_data.eq(in_data),
        enc_comb.i_en_data.eq(en_data),
        enc_comb.i_hsync.eq(hsync),
        enc_comb.i_vsync.eq(vsync),
    ]
    m.d.comb += [
        enc_char_comb.eq(enc_comb.o_char),
    ]

    with m.If(~Initial()):
        m.d.comb += [
            Assert(enc_char_pipe == enc_char_comb),
            Assert(enc_pipe.dc_bias == enc_comb.dc_bias),
        ]

    with bld.temp_open("formal.il") as f:
        il_text = rtlil.convert(m, ports=[enc_char_comb, enc_char_pipe])
        f.write(il_text)
Exemple #3
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]
Exemple #4
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]
Exemple #5
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
Exemple #6
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()]
        )
Exemple #7
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]