Exemplo n.º 1
0
 def check(m: Module, data: Snapshot, alu: Signal):
     m.d.comb += [
         Assert(data.read_data[0].matches(MUL.opcode)),
     ]
     for i in range(1, 10):
         m.d.comb += [
             Assert(Past(alu.oper, i) == Operation.MUL),
         ]
     for i in range(3, 10):
         m.d.comb += [
             Assert(Past(alu.inputa, i) == data.pre.Y),
             Assert(Past(alu.inputb, i) == data.pre.A),
         ]
     m.d.comb += [
         Assert(data.post.A == Past(alu.result, 1)),
         Assert(data.post.X == data.pre.X),
         Assert(data.post.Y == Past(alu.result, 2)),
         Assert(data.post.SP == data.pre.SP),
         Assert(data.post.PC == add16(data.pre.PC, 1)),
     ]
     m.d.comb += [
         Assert(data.addresses_read == 1),
         Assert(data.addresses_written == 0),
         Assert(data.read_addr[0] == add16(data.pre.PC, 0)),
     ]
Exemplo n.º 2
0
 def check(m: Module, data: Snapshot, alu: Signal):
     m.d.comb += [
         Assert(data.read_data[0].matches(JMP.opcode)),
     ]
     m.d.comb += [
         Assert(Past(alu.oper, 3) == Operation.NOP),
         Assert(Past(alu.oper, 2) == Operation.NOP),
         Assert(Past(alu.oper, 1) == Operation.NOP),
     ]
     m.d.comb += [
         Assert(data.post.A == data.pre.A),
         Assert(data.post.X == data.pre.X),
         Assert(data.post.Y == data.pre.Y),
         Assert(data.post.SP == data.pre.SP),
         Assert(data.post.PC[:8] == data.read_data[1]),
         Assert(data.post.PC[8:] == data.read_data[2]),
         Assert(data.post.PSW == data.pre.PSW),
     ]
     m.d.comb += [
         Assert(data.addresses_read == 3),
         Assert(data.addresses_written == 0),
         Assert(data.read_addr[0] == add16(data.pre.PC, 0)),
         Assert(data.read_addr[1] == add16(data.pre.PC, 1)),
         Assert(data.read_addr[2] == add16(data.pre.PC, 2)),
     ]
Exemplo n.º 3
0
def __main():
    m = top = Module()
    clock = ClockInfo("i")
    m.domains.i = clock.domain

    top.submodules.regs = regs = RegisterFileModule(32)
    regs.aux_ports.append(clock.clk)
    regs.aux_ports.append(clock.rst)

    comb = m.d.comb

    with m.If(regs.rs1_in == 0):
        comb += Assert(regs.rs1_out == 0)
    with m.If(regs.rs2_in == 0):
        comb += Assert(regs.rs2_out == 0)

    with m.If(regs.rs2_in == regs.rs1_in):
        comb += Assert(regs.rs2_out == regs.rs2_out)

    with m.If((Past(regs.rd) == regs.rs1_in)
              & (~Past(clock.rst) & (~clock.rst))):
        with m.If(regs.rs1_in != 0):
            comb += Assert(regs.rs1_out == Past(regs.rd_value))

    nmigen_main(top, ports=regs.ports())
Exemplo n.º 4
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]
Exemplo n.º 5
0
 def past(self, signal):
     return [
         signal,
         Past(signal),
         Past(signal, 2),
         Past(signal, 3),
         Past(signal, 4),
     ]
Exemplo n.º 6
0
 def check(m: Module, data: Snapshot, alu: Signal):
     m.d.comb += [
         Assert(data.read_data[0].matches(MOV_A_read.opcode)),
     ]
     m.d.comb += [
         Assert(Past(alu.oper, 4) == Operation.NOP),
         Assert(Past(alu.oper, 3) == Operation.NOP),
         Assert(Past(alu.oper, 2) == Operation.NOP),
         Assert(Past(alu.oper, 1) == Operation.OOR),
         Assert(Past(alu.inputa) == data.read_data[3]),
         Assert(Past(alu.inputb) == 0),
         Assert(Past(alu.result) == data.read_data[3]),
     ]
     m.d.comb += [
         Assert(data.post.A == Past(alu.result)),
         Assert(data.post.X == data.pre.X),
         Assert(data.post.Y == data.pre.Y),
         Assert(data.post.SP == data.pre.SP),
         Assert(data.post.PC == add16(data.pre.PC, 3)),
     ]
     m.d.comb += [
         Assert(data.addresses_read == 4),
         Assert(data.addresses_written == 0),
         Assert(data.read_addr[0] == add16(data.pre.PC, 0)),
         Assert(data.read_addr[1] == add16(data.pre.PC, 1)),
         Assert(data.read_addr[2] == add16(data.pre.PC, 2)),
         Assert(data.read_addr[3] == Cat(data.read_data[1], data.read_data[2])),
     ]
def verification_statements(m):
    #Create Local Reference to the LDPC_Decoder
    LDPC_Decoder = m.submodules.LDPC_Decoder

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

    return
Exemplo n.º 8
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
Exemplo n.º 9
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]
Exemplo n.º 10
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.º 11
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]
Exemplo n.º 12
0
    def elaborate(self, platform):
        m = Module()

        # increments every clock cycle. when the high bit changes, the timers
        # are decremented -> 256 cycle decrement period for them.
        global_counter = Signal(9)
        do_decrement = Signal()
        m.d.sync += [
            global_counter.eq(global_counter + 1),
            do_decrement.eq(global_counter[-1] != Past(global_counter)[-1]),
        ]

        # NOT arrays, we don't index them dynamically
        timer_val = tuple(Signal(16) for _ in range(NUM_TIMERS))
        timer_ended = tuple(Signal(1) for _ in range(NUM_TIMERS))
        # decrement timers (before they potentially get written to)
        for ti in range(NUM_TIMERS):
            with m.If((timer_val[ti] > 0) & do_decrement):
                m.d.sync += timer_val[ti].eq(timer_val[ti] - 1)
                with m.If(timer_val[ti] == 1):
                    m.d.sync += timer_ended[ti].eq(1)

        # let the timer values be set
        with m.If(self.i_we):
            with m.Switch(self.i_addr):
                for ti in range(NUM_TIMERS):
                    with m.Case(ti):
                        m.d.sync += [
                            timer_val[ti].eq(self.i_wdata),
                            timer_ended[ti].eq(0),
                        ]
                with m.Case():
                    pass

        # and let the end status be read
        read_status = Signal()  # bus expects one cycle of read latency
        m.d.sync += self.o_rdata.eq(Cat(read_status, 0))
        with m.If(self.i_re):
            with m.Switch(self.i_addr):
                for ti in range(NUM_TIMERS):
                    with m.Case(ti):
                        m.d.comb += read_status.eq(timer_ended[ti])
                with m.Case():
                    pass

        return m
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
    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.º 15
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.º 16
0
 def validate(self):
     with self.is_running():
         with self.is_instruction(0xC6, 2):
             self.assert_equals(self.registers.b, Past(self.Din))
             self.assert_end_of_instruction()
Exemplo n.º 17
0
    def elaborate(self, platform):
        m = Module()

        # hook up the modules which do the work
        m.submodules.txm = txm = Transmitter(self.divisor)
        m.submodules.rxm = rxm = Receiver(self.divisor)
        m.d.comb += [
            rxm.i_rx.eq(self.i_rx),
            self.o_tx.eq(txm.o_tx),
        ]

        # define the signals that make up the registers
        r1_rx_error = SetReset(m, priority="set")
        r1_tx_overflow = SetReset(m, priority="set")
        r1_rx_timeout = SetReset(m, priority="set")
        r1_rx_overflow = SetReset(m, priority="set")

        r6_tx_full = SetReset(m, priority="set")

        # hook up transmit "buffer". it's just one byte.
        tx_data = Signal(8)
        m.d.comb += [
            txm.i_start_tx.eq(r6_tx_full.value),
            txm.i_data.eq(tx_data),
            r6_tx_full.reset.eq(txm.o_re),
        ]

        # hook up receive FIFO. it's big so the CPU can be busy and not miss
        # stuff
        m.submodules.rx_fifo = rx_fifo = self.rx_fifo
        m.d.comb += [
            r1_rx_overflow.set.eq(~rx_fifo.w_rdy & rxm.o_we),
            rx_fifo.w_data.eq(rxm.o_data),
            rx_fifo.w_en.eq(rxm.o_we),
        ]

        # hook up the CRC engine
        m.submodules.crc = crc = KermitCRC()

        # run the receive timeout timer
        rt_timeout_val = Signal(16)
        rt_timer_reset = SetReset(m, priority="set")
        rt_timer_curr = Signal(16)
        rt_subtimer = Signal(9)

        # keep reset if reception is ongoing
        with m.If(rxm.o_active):
            m.d.comb += rt_timer_reset.set.eq(1)

        # cancel reset request once it's been done
        m.d.sync += rt_timer_reset.reset.eq(rt_timer_reset.value)

        m.d.sync += rt_subtimer.eq(rt_subtimer - 1)
        with m.If(rt_timer_reset.value):
            m.d.sync += rt_timer_curr.eq(rt_timeout_val)
        with m.Elif(rt_timer_curr > 0):
            with m.If(
                    rt_subtimer[-1] != Past(rt_subtimer)[-1]):  # rolled over?
                m.d.sync += rt_timer_curr.eq(rt_timer_curr - 1)
                # timeout about to hit zero?
                m.d.comb += r1_rx_timeout.set.eq(rt_timer_curr == 1)

        # handle the boneless bus.
        read_data = Signal(16)  # it expects one cycle of read latency
        m.d.sync += self.o_rdata.eq(read_data)

        with m.If(self.i_re):
            with m.Switch(self.i_addr[:3]):  # we only have 8 registers
                with m.Case(0):  # status register
                    m.d.comb += [
                        # transmitter remains active as long as there is data to
                        # transmit
                        read_data[15].eq(txm.o_active),
                        read_data[0].eq(rxm.o_active),
                    ]
                with m.Case(1):  # error register
                    m.d.comb += [
                        read_data[15].eq(r1_rx_error.value),
                        read_data[2].eq(r1_tx_overflow.value),
                        read_data[1].eq(r1_rx_timeout.value),
                        read_data[0].eq(r1_rx_overflow.value),
                    ]
                with m.Case(2):  # CRC value register
                    m.d.comb += read_data.eq(crc.o_crc)
                with m.Case(4, 5):  # rx status and receive data
                    # the FIFO will be okay if we read from it while empty, so
                    # we just read from it regardless
                    m.d.comb += rx_fifo.r_en.eq(1)
                    # can be read from low or high byte
                    with m.If(self.i_addr[0]):  # high byte
                        m.d.comb += [
                            read_data[7:15].eq(rx_fifo.r_data),
                            read_data[15].eq(~rx_fifo.r_rdy),
                        ]
                    with m.Else():  # low byte (rotated for status bit access)
                        m.d.comb += [
                            read_data[15].eq(rx_fifo.r_data[0]),
                            read_data[:7].eq(rx_fifo.r_data[1:]),
                            read_data[14].eq(~rx_fifo.r_rdy),
                        ]
                    # if there actually was a byte, fold it into the CRC
                    with m.If(rx_fifo.r_rdy):
                        m.d.comb += [
                            crc.i_byte.eq(rx_fifo.r_data),
                            crc.i_start.eq(1),
                        ]
                with m.Case(6, 7):  # tx fifo status
                    m.d.comb += read_data[0].eq(r6_tx_full.value)
        with m.Elif(self.i_we):
            with m.Switch(self.i_addr[:3]):
                with m.Case(1):  # error register
                    m.d.comb += [
                        r1_rx_error.reset.eq(self.i_wdata[15]),
                        r1_tx_overflow.reset.eq(self.i_wdata[2]),
                        r1_rx_timeout.reset.eq(self.i_wdata[1]),
                        r1_rx_overflow.reset.eq(self.i_wdata[0]),
                    ]
                    with m.If(self.i_wdata[1]):
                        m.d.comb += rt_timer_reset.set.eq(1)
                with m.Case(2):  # CRC reset register
                    m.d.comb += crc.i_reset.eq(1)
                with m.Case(3):  # receive timeout register
                    m.d.sync += rt_timeout_val.eq(self.i_wdata)
                    m.d.comb += rt_timer_reset.set.eq(1)
                with m.Case(6, 7):  # transmit data register
                    # can be written to low or high byte
                    value = Signal(8)
                    m.d.comb += value.eq(
                        Mux(self.i_addr[0], self.i_wdata[8:],
                            self.i_wdata[:8]))
                    # do we have space available for it?
                    with m.If(~r6_tx_full.value):
                        # yes, store it and set that we've used the space
                        m.d.sync += tx_data.eq(value)
                        m.d.comb += r6_tx_full.set.eq(1)
                        # and fold it into the CRC
                        m.d.comb += [crc.i_byte.eq(value), crc.i_start.eq(1)]
                    with m.Else():
                        # overflowed! drop the write and raise error.
                        m.d.comb += r1_tx_overflow.set.eq(1)

        return m
Exemplo n.º 18
0
    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
                m.d.comb += [
                    sum9.eq(alu.input1 + alu.input2 + carry_in),
                    sum8.eq(alu.input1[:7] + alu.input2[:7] + carry_in),
Exemplo n.º 19
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.º 20
0
 def assert_inc16(self, signal, ago):
     if ago == 0:
         self.m.d.ph1 += Assert(signal == (Past(signal) + 1)[:16])
     else:
         self.m.d.ph1 += Assert(
             Past(signal, ago) == (Past(signal, ago + 1) + 1)[:16])
Exemplo n.º 21
0
 def is_instruction(self, instruction, max_cycle):
     return self.m.If((Past(self.core.cycle) == max_cycle)
                      & (Past(self.core.registers.instr) == instruction))
Exemplo n.º 22
0

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

    # o_digit_rd rises with o_conv_rd and falls on the next cycle
    with m.If(Rose(b2d.o_conv_rd, 2)):
        m.d.comb += Assert(Rose(b2d.o_digit_rd, 2))
Exemplo n.º 23
0
 def make_term():
     if expect:
         return Past(signal, n)
     else:
         return ~Past(signal, n)
Exemplo n.º 24
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
Exemplo n.º 25
0
    def elaborate(self, platform):
        m = Module()
        m.submodules.cpu_core = cpu_core = self.cpu_core
        m.submodules.bootrom_r = bootrom_r = self.bootrom.read_port(
            transparent=False)
        m.submodules.bootrom_w = bootrom_w = self.bootrom.write_port()

        m.submodules.reset_req = reset_req = self.reset_req
        m.submodules.uart = uart = self.uart
        m.submodules.timer = timer = self.timer
        m.submodules.snes = snes = self.snes

        # hook up main bus. the main RAM gets the first half and the boot ROM
        # gets the second (though nominally, it's from 0xFF00 to 0xFFFF)
        mainram_en = Signal()
        bootrom_en = Signal()
        # the code area of the boot ROM can't be written to to avoid destroying
        # it by accident. if it got destroyed, then the bootloader wouldn't work
        # after reset; a full reconfiguration would be required.
        bootrom_writable = Signal()
        m.d.comb += [
            mainram_en.eq(cpu_core.o_bus_addr[-1] == 0),
            bootrom_en.eq(cpu_core.o_bus_addr[-1] == 1),
            bootrom_writable.eq((cpu_core.o_bus_addr & 0xC0) == 0xC0)
        ]
        # wire the main bus to the memories
        m.d.comb += [
            # address bus
            bootrom_r.addr.eq(cpu_core.o_bus_addr),
            bootrom_w.addr.eq(cpu_core.o_bus_addr),
            self.memory_signals.o_addr.eq(cpu_core.o_bus_addr),
            # write data
            bootrom_w.data.eq(cpu_core.o_mem_data),
            self.memory_signals.o_wdata.eq(cpu_core.o_mem_data),
            # enables
            bootrom_r.en.eq(bootrom_en & cpu_core.o_mem_re),
            bootrom_w.en.eq(bootrom_en & cpu_core.o_mem_we & bootrom_writable),
            self.memory_signals.o_re.eq(mainram_en & cpu_core.o_mem_re),
            self.memory_signals.o_we.eq(mainram_en & cpu_core.o_mem_we),
        ]
        # mux read results back to the cpu bus. the cpu gets the read value if
        # it addressed the memory last cycle. it can only address one memory at
        # a time (if it did more then all the results would be ORed together).
        mainram_rdata = Signal(16)
        bootrom_rdata = Signal(16)
        m.d.comb += [
            mainram_rdata.eq(
                Mux(Past(mainram_en), self.memory_signals.i_rdata, 0)),
            bootrom_rdata.eq(Mux(Past(bootrom_en), bootrom_r.data, 0)),
            cpu_core.i_mem_data.eq(mainram_rdata | bootrom_rdata),
        ]
        # the main RAM runs with the system clock
        m.d.comb += [
            self.memory_signals.o_clock.eq(ClockSignal("sync")),
            self.memory_signals.o_reset.eq(ResetSignal("sync")),
        ]

        # split up the external bus into (at most) 16 regions of 16 registers.
        # we use the first 128 words and last 128 words of the bus since those
        # regions can be addressed with the 1-word form of the external bus
        # instructions. each peripheral gets 1 read and 1 write enable bit, 4
        # address bits, 16 write data bits, and gives back 16 read data bits
        NUM_PERIPHS = 4
        periph_en = tuple(Signal(1) for _ in range(NUM_PERIPHS))
        periph_re = tuple(Signal(1) for _ in range(NUM_PERIPHS))
        periph_we = tuple(Signal(1) for _ in range(NUM_PERIPHS))
        periph_addr = Signal(4)
        periph_wdata = Signal(16)
        periph_rdata = tuple(Signal(16) for _ in range(NUM_PERIPHS))

        m.d.comb += periph_addr.eq(cpu_core.o_bus_addr[:4])
        m.d.comb += periph_wdata.eq(cpu_core.o_ext_data)
        # hook up enable bits
        x_addr = cpu_core.o_bus_addr
        for pi in range(NUM_PERIPHS):
            m.d.comb += [
                periph_en[pi].eq((x_addr[-1] == (pi >> 3))
                                 & (x_addr[4:7] == (pi & 7))),
                periph_re[pi].eq(cpu_core.o_ext_re & periph_en[pi]),
                periph_we[pi].eq(cpu_core.o_ext_we & periph_en[pi]),
            ]

        # mux peripheral read data back to the CPU
        result_expr = Const(0, 16)
        for pi in range(NUM_PERIPHS):
            # this peripheral gets to put its result on the bus if it was
            # addressed last cycle
            result_expr = result_expr | \
                Mux(Past(periph_en[pi]), periph_rdata[pi], 0)
        m.d.comb += cpu_core.i_ext_data.eq(result_expr)

        # hook up the reset request peripheral
        m.d.comb += [
            reset_req.i_re.eq(periph_re[p_map.reset_req.periph_num]),
            reset_req.i_we.eq(periph_we[p_map.reset_req.periph_num]),
            reset_req.i_addr.eq(periph_addr),
            reset_req.i_wdata.eq(periph_wdata),
            periph_rdata[p_map.reset_req.periph_num].eq(reset_req.o_rdata),
            self.o_reset_req.eq(reset_req.o_reset_req),
        ]

        # hook up the UART
        m.d.comb += [
            uart.i_re.eq(periph_re[p_map.uart.periph_num]),
            uart.i_we.eq(periph_we[p_map.uart.periph_num]),
            uart.i_addr.eq(periph_addr),
            uart.i_wdata.eq(periph_wdata),
            periph_rdata[p_map.uart.periph_num].eq(uart.o_rdata),
            uart.i_rx.eq(self.uart_signals.i_rx),
            self.uart_signals.o_tx.eq(uart.o_tx),
        ]

        # hook up the timers
        m.d.comb += [
            timer.i_re.eq(periph_re[p_map.timer.periph_num]),
            timer.i_we.eq(periph_we[p_map.timer.periph_num]),
            timer.i_addr.eq(periph_addr),
            timer.i_wdata.eq(periph_wdata),
            periph_rdata[p_map.timer.periph_num].eq(timer.o_rdata),
        ]

        # hook up the SNES interface
        m.d.comb += [
            snes.i_re.eq(periph_re[p_map.snes.periph_num]),
            snes.i_we.eq(periph_we[p_map.snes.periph_num]),
            snes.i_addr.eq(periph_addr),
            snes.i_wdata.eq(periph_wdata),
            periph_rdata[p_map.snes.periph_num].eq(snes.o_rdata),
        ]

        return m
Exemplo n.º 26
0
	def validate(self):
		with self.is_running():
			with self.is_instruction(0x1B, 2):
				self.assert_equals(self.registers.a, Past(self.registers.a) + Past(self.registers.b))
				self.assert_end_of_instruction()
Exemplo n.º 27
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.º 28
0
    def capture(self, m: Core, core: Core, past: int):
        comb = m.d.comb
        if past > 0:
            prefix = f"past{past}"
        else:
            prefix = "now"
        self.r = RegisterFile(core.xlen, prefix=prefix)
        for i in range(self.r.main_gpr_count()):
            comb += self.r[i].eq(Past(core.register_file.r[i], past))
        comb += self.r.pc.eq(Past(core.pc, past))

        # TODO: move to additional structure
        self.itype = IType(prefix=f"{prefix}_i")
        self.itype.elaborate(comb, Past(core.current_instruction, past))

        self.jtype = JType(prefix=f"{prefix}_j")
        self.jtype.elaborate(comb, Past(core.current_instruction, past))

        self.utype = UType(prefix=f"{prefix}_u")
        self.utype.elaborate(comb, Past(core.current_instruction, past))

        self.btype = BType(prefix=f"{prefix}_b")
        self.btype.elaborate(comb, Past(core.current_instruction, past))

        # TODO: membus
        self.input_ready = Signal.like(core.mem2core.ready,
                                       name=f"{prefix}_input_ready")
        self.input_data = Array([
            Signal(core.xlen, name=f"{prefix}_input_{i}")
            for i in range(core.look_ahead)
        ])

        self.cycle = Signal.like(core.cycle, name=f"{prefix}_cycle")
        comb += self.cycle.eq(Past(core.cycle, past))

        # TODO: move to structure
        self.mem2core_addr = Signal.like(core.mem2core.addr,
                                         name=f"{prefix}_mem2core_addr")
        self.mem2core_en = Signal.like(core.mem2core.en,
                                       name=f"{prefix}_mem2core_en")
        self.mem2core_seq = Signal.like(core.mem2core.seq,
                                        name=f"{prefix}_mem2core_seq")
        comb += self.mem2core_addr.eq(Past(core.mem2core.addr, past))
        comb += self.mem2core_en.eq(Past(core.mem2core.en, past))
        comb += self.mem2core_seq.eq(Past(core.mem2core.seq, past))
        comb += self.input_ready.eq(Past(core.mem2core.ready, past))
        comb += self.input_data[0].eq(Past(core.mem2core.value, past))
Exemplo n.º 29
0
    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,
            0xFFFF: 0x34,
            0x1234: 0x7E,  # JMP 0xA010
            0x1235: 0xA0,
Exemplo n.º 30
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]