Exemple #1
0
    def elaborate(self, platform):
        m = Module()
        delay_tap = Signal(self._SREG_LEN)
        m.d.comb += delay_tap.eq(1 << self.log_downsample_ratio)
        # Dynamic delay shift register
        out_val = Signal(signed(self._dw))
        delay_reg = Array(
            Signal(signed(self._dw), reset=0) for _ in range(self._SREG_LEN))
        src = self.i
        for x in range(self._SREG_LEN):
            m.d.sync += delay_reg[x].eq(src)
            src = delay_reg[x]
        m.d.comb += out_val.eq(delay_reg[delay_tap - 1])
        counter = Signal(signed(self._dw))
        with m.If(counter == delay_tap - 1):
            m.d.sync += counter.eq(0)
            m.d.comb += self.data_valid.eq(1)
        with m.Else():
            m.d.sync += counter.eq(counter + 1)

        moving_average_full = Signal(signed(self._dw + self.MAX_DELAY_BITS))
        m.d.sync += moving_average_full.eq(moving_average_full + self.i -
                                           out_val)
        m.d.comb += [
            self.o.eq(moving_average_full >> self.log_downsample_ratio)
        ]
        return m
Exemple #2
0
    def init(self, p, zi: iterable = None) -> None:
        """
        Initialize filter with parameter dict `p` by initialising all registers
        and quantizers.
        This needs to be done every time quantizers or coefficients are updated.

        Parameters
        ----------
        p : dict
            dictionary with coefficients and quantizer settings (see docstring of
            `__init__()` for details)

        zi : array-like
            Initialize `L = len(b)` filter registers. Strictly speaking, `zi[0]` is
            not a register but the current input value.
            When `len(zi) != len(b)`, truncate or fill up with zeros.
            When `zi == None`, all registers are filled with zeros.

        Returns
        -------
        None.
        """
        self.p = p  # fb.fil[0]['fxqc']  # parameter dictionary with coefficients etc.
        # ------------- Define I/Os --------------------------------------
        self.i = Signal(signed(self.p['QI']['W']))  # input signal
        self.o = Signal(signed(self.p['QO']['W']))  # output signal
Exemple #3
0
 def __init__(self, platform=None, divider=50, top=False):
     '''
         platform  -- pass test platform
         divider -- original clock of 100 MHz via PLL reduced to 50 MHz
                    if this is divided by 50 motor state updated
                    with 1 Mhz
         top       -- trigger synthesis of module
     '''
     self.top = top
     self.divider = divider
     self.platform = platform
     self.order = DEGREE
     # change code for other orders
     assert self.order == 3
     self.motors = platform.motors
     self.max_steps = int(MOVE_TICKS / 2)  # Nyquist
     # inputs
     self.coeff = Array()
     for _ in range(self.motors):
         self.coeff.extend(
             [Signal(signed(64)),
              Signal(signed(64)),
              Signal(signed(64))])
     self.start = Signal()
     self.ticklimit = Signal(MOVE_TICKS.bit_length())
     # output
     self.busy = Signal()
     self.totalsteps = Array(
         Signal(signed(self.max_steps.bit_length() + 1))
         for _ in range(self.motors))
     self.dir = Array(Signal() for _ in range(self.motors))
     self.step = Array(Signal() for _ in range(self.motors))
Exemple #4
0
    def run_general(self):
        last = self.time[1]
        m = self.module
        core: Core = self.uut
        comb = m.d.comb

        lhs = Signal(signed(core.xlen))
        rhs = Signal(signed(core.xlen))
        blt_res = Signal(name="blt_res")

        comb += lhs.eq(last.r[last.btype.rs1])
        comb += rhs.eq(last.r[last.btype.rs2])
        comb += blt_res.eq(lhs < rhs)

        with m.If(blt_res):
            self.assert_jump_was_taken()
        with m.Else():
            self.assert_no_jump_taken()

        lhs_bz = Signal()  # bz = below-zero
        rhs_bz = Signal()
        comb += lhs_bz.eq(lhs[core.xlen - 1])
        comb += rhs_bz.eq(rhs[core.xlen - 1])

        with m.If(lhs_bz & (~rhs_bz)):
            self.assert_jump_was_taken()
        with m.Elif((~lhs_bz) & (rhs_bz)):
            self.assert_no_jump_taken()
Exemple #5
0
    def elaborate(self, platform: Platform) -> Module:
        m = Module()

        a = Signal(signed(33))
        b = Signal(signed(33))
        result_ll = Signal(32)
        result_lh = Signal(33)
        result_hl = Signal(33)
        result_hh = Signal(33)
        result_3 = Signal(64)
        result_4 = Signal(64)
        active = Signal(5)
        is_signed = Signal()
        a_is_signed = Signal()
        b_is_signed = Signal()
        low = Signal()

        m.d.sync += [
            is_signed.eq(a_is_signed ^ b_is_signed),
            active.eq(Cat(self.valid & (active == 0), active)),
            low.eq(self.op == Funct3.MUL)
        ]
        # ----------------------------------------------------------------------
        # fist state
        m.d.comb += [
            a_is_signed.eq((
                (self.op == Funct3.MULH) | (self.op == Funct3.MULHSU))
                           & self.dat1[-1]),
            b_is_signed.eq((self.op == Funct3.MULH) & self.dat2[-1])
        ]
        m.d.sync += [
            a.eq(Mux(a_is_signed, -Cat(self.dat1, 1), self.dat1)),
            b.eq(Mux(b_is_signed, -Cat(self.dat2, 1), self.dat2)),
        ]
        # ----------------------------------------------------------------------
        # second state
        m.d.sync += [
            result_ll.eq(a[0:16] * b[0:16]),
            result_lh.eq(a[0:16] * b[16:33]),
            result_hl.eq(a[16:33] * b[0:16]),
            result_hh.eq(a[16:33] * b[16:33])
        ]
        # ----------------------------------------------------------------------
        # third state
        m.d.sync += [
            result_3.eq(
                Cat(result_ll, result_hh) +
                Cat(Repl(0, 16), (result_lh + result_hl)))
        ]
        # ----------------------------------------------------------------------
        # fourth state
        m.d.sync += [
            result_4.eq(Mux(is_signed, -result_3, result_3)),
            self.result.eq(Mux(low, result_4[:32], result_4[32:64]))
        ]
        m.d.comb += self.ready.eq(active[-1])

        return m
Exemple #6
0
 def __init__(self):
     self.in0 = Signal(32)
     self.in1 = Signal(32)
     self.funct7 = Signal(7)
     self.output = Signal(32)
     self.start = Signal()
     self.done = Signal()
     self.in0s = Signal(signed(32))
     self.in1s = Signal(signed(32))
Exemple #7
0
    def decode_imm(self, m: Module):
        """Decodes the immediate value out of the instruction."""
        with m.Switch(self._imm_format):
            # Format I instructions. Surprisingly, SLTIU (Set if Less Than
            # Immediate Unsigned) actually does sign-extend the immediate
            # value, and then compare as if the sign-extended immediate value
            # were unsigned!
            with m.Case(OpcodeFormat.I):
                tmp = Signal(signed(12))
                m.d.comb += tmp.eq(self.state._instr[20:])
                m.d.comb += self._imm.eq(tmp)

            # Format S instructions:
            with m.Case(OpcodeFormat.S):
                tmp = Signal(signed(12))
                m.d.comb += tmp[0:5].eq(self.state._instr[7:12])
                m.d.comb += tmp[5:].eq(self.state._instr[25:])
                m.d.comb += self._imm.eq(tmp)

            # Format R instructions:
            with m.Case(OpcodeFormat.R):
                m.d.comb += self._imm.eq(0)

            # Format U instructions:
            with m.Case(OpcodeFormat.U):
                m.d.comb += self._imm.eq(0)
                m.d.comb += self._imm[12:].eq(self.state._instr[12:])

            # Format B instructions:
            with m.Case(OpcodeFormat.B):
                tmp = Signal(signed(13))
                m.d.comb += [
                    tmp[12].eq(self.state._instr[31]),
                    tmp[11].eq(self.state._instr[7]),
                    tmp[5:11].eq(self.state._instr[25:31]),
                    tmp[1:5].eq(self.state._instr[8:12]),
                    tmp[0].eq(0),
                    self._imm.eq(tmp),
                ]

            # Format J instructions:
            with m.Case(OpcodeFormat.J):
                tmp = Signal(signed(21))
                m.d.comb += [
                    tmp[20].eq(self.state._instr[31]),
                    tmp[12:20].eq(self.state._instr[12:20]),
                    tmp[11].eq(self.state._instr[20]),
                    tmp[1:11].eq(self.state._instr[21:31]),
                    tmp[0].eq(0),
                    self._imm.eq(tmp),
                ]

            with m.Case(OpcodeFormat.SYS):
                m.d.comb += [
                    self._imm[0:5].eq(self.state._instr[15:]),
                    self._imm[5:].eq(0),
                ]
Exemple #8
0
    def comparison_impl(self, rv1, rv2):
        core : Core = self.core
        m = core.current_module
        comb = m.d.comb

        rv1_signed = Signal(signed(core.xlen))
        rv2_signed = Signal(signed(core.xlen))
        comb += rv1_signed.eq(rv1)
        comb += rv2_signed.eq(rv2)    
        return rv1_signed < rv2_signed
Exemple #9
0
 def __init__(self, MAX_DELAY_BITS=5, dw=16):
     self._dw = dw
     self.MAX_DELAY_BITS = MAX_DELAY_BITS
     self._SREG_LEN = 2**MAX_DELAY_BITS
     self.i, self.o = (Signal(signed(self._dw),
                              name='i'), Signal(signed(self._dw), name='o'))
     self.data_valid = Signal(name='data_valid')
     # log_downsample_ratio must be a power of 2.
     self.log_downsample_ratio = Signal(MAX_DELAY_BITS,
                                        name='log_downsample_ratio')
Exemple #10
0
    def elab(self, m):
        # Product is 17 bits: 8 bits * 9 bits = 17 bits
        products = [Signal(signed(17), name=f"product_{n}") for n in range(4)]
        for i_val, f_val, product in zip(all_words(self.i_data, 8),
                                         all_words(self.f_data, 8), products):
            f_tmp = Signal(signed(9))
            m.d.sync += f_tmp.eq(f_val.as_signed())
            i_tmp = Signal(signed(9))
            m.d.sync += i_tmp.eq(i_val.as_signed() + self.offset)
            m.d.comb += product.eq(i_tmp * f_tmp)

        m.d.sync += self.result.eq(tree_sum(products))
Exemple #11
0
    def __init__(self):
        super().__init__()
        self.input_offset = Signal(signed(32))
        self.reset_acc = Signal()

        self.output_offset = Signal(signed(32))

        self.out_depth_set = Signal()
        self.out_depth = Signal(32)
        self.out_mult_set = Signal()
        self.out_mult = Signal(signed(32))
        self.out_bias_shift_set = Signal()
        self.out_bias_shift = Signal(32)
Exemple #12
0
 def __init__(self, clk_freq):
     self.clk_freq = clk_freq
     self.i2s = Record([
         ('mclk', 1),
         ('lrck', 1),
         ('sck', 1),
         ('sd', 1),
     ])
     self.samples = Array((Signal(signed(16)), Signal(signed(16))))
     self.stb = Signal()
     self.ack = Signal()
     self.ports = [self.i2s.mclk, self.i2s.lrck, self.i2s.sck, self.i2s.sd]
     self.ports += [self.samples[0], self.samples[1], self.stb, self.ack]
    def elab(self, m):
        with_bias = Signal(signed(32))
        m.d.comb += with_bias.eq(self.accumulator + self.bias)

        # acc = cpp_math_mul_by_quantized_mul_software(
        #       acc, param_store_read(&output_multiplier),
        #       param_store_read(&output_shift));
        left_shift = Signal(5)
        right_sr = [Signal(5, name=f'right_sr_{n}') for n in range(4)]
        with m.If(self.shift > 0):
            m.d.comb += left_shift.eq(self.shift)
        with m.Else():
            m.d.comb += right_sr[0].eq(-self.shift)
        left_shifted = Signal(32)
        m.d.comb += left_shifted.eq(with_bias << left_shift),

        # Pass right shift value down through several cycles to where
        # it is needed
        for a, b in zip(right_sr, right_sr[1:]):
            m.d.sync += b.eq(a)

        # All logic is combinational up to the inputs to the SRDHM
        m.submodules['srdhm'] = srdhm = SRDHM()
        m.d.comb += [
            srdhm.a.eq(left_shifted),
            srdhm.b.eq(self.multiplier),
        ]

        # Output from SRDHM appears several cycles later
        right_shifted = Signal(signed(32))
        m.d.sync += right_shifted.eq(
            rounding_divide_by_pot(srdhm.result, right_sr[-1]))

        # This logic is combinational to output
        # acc += reg_output_offset
        # if (acc < reg_activation_min) {
        #     acc = reg_activation_min
        # } else if (acc > reg_activation_max) {
        #     acc = reg_activation_max
        # }
        # return acc
        with_offset = Signal(signed(32))
        m.d.comb += [
            with_offset.eq(right_shifted + self.offset),
            self.result.eq(
                clamped(with_offset, self.activation_min,
                        self.activation_max)),
        ]
Exemple #14
0
    def check(self, m: Module):
        ret_addr = (self.data.pre_pc + 2)[:16]
        offset = Signal(signed(8))

        self.assert_cycles(m, 8)
        data = self.assert_cycle_signals(m,
                                         1,
                                         address=self.data.pre_pc + 1,
                                         vma=1,
                                         rw=1,
                                         ba=0)
        self.assert_cycle_signals(m, 2, vma=0, ba=0)
        ret_addr_lo = self.assert_cycle_signals(m,
                                                3,
                                                address=self.data.pre_sp,
                                                vma=1,
                                                rw=0,
                                                ba=0)
        ret_addr_hi = self.assert_cycle_signals(m,
                                                4,
                                                address=self.data.pre_sp - 1,
                                                vma=1,
                                                rw=0,
                                                ba=0)
        self.assert_cycle_signals(m, 5, vma=0, ba=0)
        self.assert_cycle_signals(m, 6, vma=0, ba=0)
        self.assert_cycle_signals(m, 7, vma=0, ba=0)
        m.d.comb += offset.eq(data)

        m.d.comb += Assert(LCat(ret_addr_hi, ret_addr_lo) == ret_addr)
        self.assert_registers(m, PC=ret_addr + offset, SP=self.data.pre_sp - 2)
        self.assert_flags(m)
 def __init__(self):
     self.accumulator = Signal(signed(32))
     self.bias = Signal(signed(32))
     self.multiplier = Signal(signed(32))
     self.shift = Signal(signed(32))
     self.offset = Signal(signed(32))
     self.activation_min = Signal(signed(32))
     self.activation_max = Signal(signed(32))
     self.result = Signal(signed(32))
Exemple #16
0
 def elab(self, m):
     accumulator = Signal(signed(32))
     m.d.comb += self.result.eq(accumulator)
     with m.If(self.add_en):
         m.d.sync += accumulator.eq(accumulator + self.in_value)
         m.d.comb += self.result.eq(accumulator + self.in_value)
     # clear always resets accumulator next cycle, even if add_en is high
     with m.If(self.clear):
         m.d.sync += accumulator.eq(0)
Exemple #17
0
def as_signed(m: Module, signal: Signal):
    """ Create a new copy of signal, but marked as signed """
    if signal.signed:
        # signed already
        print(f"Warning: trying to cast already signed sigan {signal.name}")
        return signal

    new_signal = Signal(signed(signal.width), name=signal.name + "_signed")
    m.d.comb += new_signal.eq(signal)
    return new_signal
Exemple #18
0
 def elab(self, m):
     in_vals = [Signal(signed(8), name=f"in_val_{i}") for i in range(4)]
     filter_vals = [
         Signal(signed(8), name=f"filter_val_{i}") for i in range(4)
     ]
     mults = [Signal(signed(19), name=f"mult_{i}") for i in range(4)]
     for i in range(4):
         m.d.comb += [
             in_vals[i].eq(self.in0.word_select(i, 8).as_signed()),
             filter_vals[i].eq(self.in1.word_select(i, 8).as_signed()),
             mults[i].eq((in_vals[i] + self.input_offset) * filter_vals[i]),
         ]
     m.d.sync += self.done.eq(0)
     with m.If(self.start):
         m.d.sync += self.accumulator.eq(self.accumulator + sum(mults))
         # m.d.sync += self.accumulator.eq(self.accumulator + 72)
         m.d.sync += self.done.eq(1)
     with m.Elif(self.reset_acc):
         m.d.sync += self.accumulator.eq(0)
Exemple #19
0
    def check(self, m: Module, instr: Value, data: FormalData):
        b = instr[6]
        pre_input = Mux(b, data.pre_b, data.pre_a)

        m.d.comb += [
            Assert(data.post_a == data.pre_a),
            Assert(data.post_b == data.pre_b),
            Assert(data.post_x == data.pre_x),
            Assert(data.post_sp == data.pre_sp),
            Assert(data.addresses_written == 0),
        ]
        m.d.comb += [
            Assert(data.post_pc == data.plus16(data.pre_pc, 3)),
            Assert(data.addresses_read == 3),
            Assert(data.read_addr[0] == data.plus16(data.pre_pc, 1)),
            Assert(data.read_addr[1] == data.plus16(data.pre_pc, 2)),
            Assert(
                data.read_addr[2] == Cat(data.read_data[1], data.read_data[0])),
        ]

        input1 = pre_input
        input2 = data.read_data[2]
        sinput1 = Signal(signed(8))
        sinput2 = Signal(signed(8))
        m.d.comb += sinput1.eq(input1)
        m.d.comb += sinput2.eq(input2)

        z = (input1 == input2)
        n = (input1 - input2)[7]

        # The following is wrong. This would calculate LT (less than), not N.
        # In other words, N is not a comparison, it's just the high bit
        # of the (unsigned) result.
        # n = ((sinput1 - sinput2) < 0)

        # GE is true if and only if N^V==0 (i.e. N == V).
        ge = sinput1 >= sinput2
        v = Mux(ge, n, ~n)
        c = (input1 < input2)

        self.assertFlags(m, data.post_ccs, data.pre_ccs,
                         Z=z, N=n, V=v, C=c)
Exemple #20
0
    def elaborate(self, platform) -> Module:
        """
        `platform` normally specifies FPGA platform, not needed here.
        """
        m = Module()  # instantiate a module
        ###
        muls = [0] * len(self.p['b'])

        DW = int(np.ceil(np.log2(len(self.p['b']))))  # word growth
        # word format for sum of partial products b_i * x_i
        QP = {
            'WI': self.p['QI']['WI'] + self.p['QCB']['WI'] + DW,
            'WF': self.p['QI']['WF'] + self.p['QCB']['WF']
        }
        QP.update({'W': QP['WI'] + QP['WF'] + 1})

        src = self.i  # first register is connected to input signal

        i = 0
        for b in self.p['b']:
            sreg = Signal(signed(
                self.p['QI']['W']))  # create chain of registers
            m.d.sync += sreg.eq(src)  # with input word length
            src = sreg
            # TODO: keep old data sreg to allow frame based processing (requiring reset)
            muls[i] = int(b) * sreg
            i += 1

        # logger.debug(f"b = {pprint_log(self.p['b'])}\nW(b) = {self.p['QCB']['W']}")

        sum_full = Signal(signed(
            QP['W']))  # sum of all multiplication products with
        m.d.sync += sum_full.eq(reduce(add, muls))  # full product wordlength

        # rescale from full product wordlength to accumulator format
        sum_accu = Signal(signed(self.p['QA']['W']))
        m.d.comb += sum_accu.eq(requant(m, sum_full, QP, self.p['QA']))

        # rescale from accumulator format to output width
        m.d.comb += self.o.eq(requant(m, sum_accu, self.p['QA'], self.p['QO']))

        return m  # return result as list of integers
Exemple #21
0
    def __init__(self, config):
        self.divisor = config.osc_divisor
        self._calc_params(config)

        self.sync_in = Signal()
        # self.note_in = Signal(range(MIDI_NOTES))
        self.mod_in = Signal(signed(16))
        self.pw_in = Signal(7, reset=~0)

        self.note_in = voice_note_spec.outlet()
        self.pulse_out = mono_sample_spec(config.osc_depth).inlet()
        self.saw_out = mono_sample_spec(config.osc_depth).inlet()
Exemple #22
0
    def check(self, m: Module):
        input1, input2, actual_output, size, use_a = self.common_check(m)
        sinput1 = Signal(signed(8))
        sinput2 = Signal(signed(8))
        m.d.comb += sinput1.eq(input1)
        m.d.comb += sinput2.eq(input2)

        z = input1 == input2
        n = (input1 - input2)[7]

        # The following is wrong. This would calculate LT (less than), not N.
        # In other words, N is not a comparison, it's just the high bit
        # of the (unsigned) result.
        # n = ((sinput1 - sinput2) < 0)

        # GE is true if and only if N^V==0 (i.e. N == V).
        ge = sinput1 >= sinput2
        v = Mux(ge, n, ~n)
        c = input1 < input2

        self.assert_registers(m, PC=self.data.pre_pc + size)
        self.assert_flags(m, Z=z, N=n, V=v, C=c)
Exemple #23
0
    def BR(self, m: Module):
        operand = self.mode_immediate8(m)

        relative = Signal(signed(8))
        m.d.comb += relative.eq(operand)

        # At this point, pc is the instruction start + 2, so we just
        # add the signed relative offset to get the target.
        with m.If(self.cycle == 2):
            m.d.ph1 += self.tmp16.eq(self.pc + relative)

        with m.If(self.cycle == 3):
            take_branch = self.branch_check(m)
            self.end_instr(m, Mux(take_branch, self.tmp16, self.pc))
Exemple #24
0
    def check(self, m: Module, instr: Value, data: FormalData):
        input1, input2, actual_output = self.common_check(m, instr, data)
        sinput1 = Signal(signed(8))
        sinput2 = Signal(signed(8))
        m.d.comb += sinput1.eq(input1)
        m.d.comb += sinput2.eq(input2)
        output = input1

        z = (input1 == input2)
        n = (input1 - input2)[7]

        # The following is wrong. This would calculate LT (less than), not N.
        # In other words, N is not a comparison, it's just the high bit
        # of the (unsigned) result.
        # n = ((sinput1 - sinput2) < 0)

        # GE is true if and only if N^V==0 (i.e. N == V).
        ge = sinput1 >= sinput2
        v = Mux(ge, n, ~n)
        c = (input1 < input2)

        m.d.comb += Assert(actual_output == output)
        self.assertFlags(m, data.post_ccs, data.pre_ccs, Z=z, N=n, V=v, C=c)
 def __init__(self):
     super().__init__()
     self.bias = Signal(signed(32))
     self.bias_next = Signal()
     self.multiplier = Signal(signed(32))
     self.multiplier_next = Signal()
     self.shift = Signal(signed(32))
     self.shift_next = Signal()
     self.offset = Signal(signed(32))
     self.activation_min = Signal(signed(32))
     self.activation_max = Signal(signed(32))
Exemple #26
0
    def check(self, m: Module, instr: Value, data: FormalData):
        m.d.comb += [
            Assert(data.post_ccs == data.pre_ccs),
            Assert(data.post_a == data.pre_a),
            Assert(data.post_b == data.pre_b),
            Assert(data.post_x == data.pre_x),
            Assert(data.post_sp == data.pre_sp),
            Assert(data.addresses_written == 0),
        ]

        m.d.comb += [
            Assert(data.addresses_read == 1),
            Assert(data.read_addr[0] == data.plus16(data.pre_pc, 1)),
        ]

        n = data.pre_ccs[Flags.N]
        z = data.pre_ccs[Flags.Z]
        v = data.pre_ccs[Flags.V]
        c = data.pre_ccs[Flags.C]
        offset = Signal(signed(8))
        br = instr[:4]

        take_branch = Array([
            Const(1),
            Const(0),
            (c | z) == 0,
            (c | z) == 1,
            c == 0,
            c == 1,
            z == 0,
            z == 1,
            v == 0,
            v == 1,
            n == 0,
            n == 1,
            (n ^ v) == 0,
            (n ^ v) == 1,
            (z | (n ^ v)) == 0,
            (z | (n ^ v)) == 1,
        ])
        m.d.comb += offset.eq(data.read_data[0])
        m.d.comb += Assert(
            data.post_pc == Mux(take_branch[br], (data.pre_pc + 2 +
                                                  offset)[:16], (data.pre_pc +
                                                                 2)[:16]))
Exemple #27
0
    def __init__(self, platform, top=False):
        """
        platform  -- pass test platform
        top       -- trigger synthesis of module
        """
        self.platform = platform
        self.top = top

        self.spi = SPIBus()
        self.position = Array(Signal(signed(64))
                              for _ in range(platform.motors))
        self.pinstate = Signal(8)
        self.read_commit = Signal()
        self.read_en = Signal()
        self.read_discard = Signal()
        self.dispatcherror = Signal()
        self.execute = Signal()
        self.read_data = Signal(MEMWIDTH)
        self.empty = Signal()
Exemple #28
0
    def check(self, m: Module):
        self.assert_cycles(m, 4)
        data = self.assert_cycle_signals(m,
                                         1,
                                         address=self.data.pre_pc + 1,
                                         vma=1,
                                         rw=1,
                                         ba=0)
        self.assert_cycle_signals(m, 2, vma=0, ba=0)
        self.assert_cycle_signals(m, 3, vma=0, ba=0)

        n = self.data.pre_ccs[Flags.N]
        z = self.data.pre_ccs[Flags.Z]
        v = self.data.pre_ccs[Flags.V]
        c = self.data.pre_ccs[Flags.C]
        offset = Signal(signed(8))
        br = self.instr[:4]

        take_branch = Array([
            Const(1),
            Const(0),
            (c | z) == 0,
            (c | z) == 1,
            c == 0,
            c == 1,
            z == 0,
            z == 1,
            v == 0,
            v == 1,
            n == 0,
            n == 1,
            (n ^ v) == 0,
            (n ^ v) == 1,
            (z | (n ^ v)) == 0,
            (z | (n ^ v)) == 1,
        ])
        m.d.comb += offset.eq(data)
        target = Mux(take_branch[br], self.data.pre_pc + 2 + offset,
                     self.data.pre_pc + 2)
        self.assert_registers(m, PC=target)
        self.assert_flags(m)
Exemple #29
0
def __verify_right(m):
    m.submodules.shr = shr = Shifter(32, Shifter.RIGHT, "shr")
    comb = m.d.comb

    input_with_msb = Signal(signed(33))
    expected = Signal(32)
    comb += input_with_msb[0:32].eq(shr.input)
    comb += input_with_msb[32].eq(shr.msb)
    comb += expected.eq(input_with_msb >> shr.shamt)
    comb += Assert(shr.output == expected)
    with m.If(shr.shamt == 0):
        comb += Assert(shr.output == shr.input)
    with m.If((shr.input == 0) & (shr.output != 0)):
        comb += Assert(shr.msb)
    with m.If(shr.shamt == 31):
        comb += Assert(shr.output[0] == shr.input[31])
    comb += Assert(shr.output[0] == shr.input.bit_select(shr.shamt, 1))

    with m.If(shr.msb == shr.input[31]):
        comb += Assert(shr.output == as_signed(m, shr.input) >> shr.shamt)

    return shr.ports()
Exemple #30
0
    def elab(self, m):
        m.d.sync += self.done.eq(0)

        ab = Signal(signed(64))
        nudge = 1 << 30  # for some reason negative nudge is not used
        with m.FSM():
            with m.State("stage0"):
                with m.If(self.start):
                    with m.If((self.a == INT32_MIN) & (self.b == INT32_MIN)):
                        m.d.sync += [
                            self.result.eq(INT32_MAX),
                            self.done.eq(1)
                        ]
                    with m.Else():
                        m.d.sync += ab.eq(self.a * self.b)
                        m.next = "stage1"
            with m.State("stage1"):
                m.d.sync += [
                    self.result.eq((ab + nudge)[31:]),
                    self.done.eq(1)
                ]
                m.next = "stage0"