Example #1
0
    def __init__(self, left, right):
        lpoint = left.point if isinstance(left, _FixedBase) else 0
        rpoint = right.point if isinstance(right, _FixedBase) else 0
        lsigned = vtypes.get_signed(left)
        rsigned = vtypes.get_signed(right)
        point = _max_mux(lpoint, rpoint)
        signed = lsigned and rsigned if not self.overwrite_signed else False
        lwidth = vtypes.get_width(left)
        rwidth = vtypes.get_width(right)

        if lpoint <= rpoint:
            ldata, rdata = adjust(left, right, lpoint, rpoint, signed)
            shift_size = point
        else:
            ldata = left
            rdata = right
            shift_size = point - (lpoint - rpoint)

        try:
            lmsb = ldata[lwidth - 1]
        except:
            lmsb = (ldata >> (lwidth - 1) & vtypes.Int(1, 1, base=2))

        try:
            rmsb = rdata[rwidth - 1]
        except:
            rmsb = (rdata >> (rwidth - 1) & vtypes.Int(1, 1, base=2))

        abs_ldata = (ldata if not lsigned else vtypes.Mux(
            vtypes.Ulnot(lmsb), ldata,
            vtypes.Unot(ldata) + 1))
        abs_rdata = (rdata if not rsigned else vtypes.Mux(
            vtypes.Ulnot(rmsb), rdata,
            vtypes.Unot(rdata) + 1))
        abs_data = vtypes.Divide(abs_ldata, abs_rdata)
        data = (abs_data if not signed else vtypes.Mux(
            vtypes.Eq(lmsb, rmsb), abs_data,
            vtypes.Unot(abs_data) + 1))

        if shift_size > 0:
            data = vtypes.Sll(data, shift_size)

        _FixedSkipUnaryOperator.__init__(self, data, point, signed)
Example #2
0
    def _call_Name_len(self, node):
        if len(node.args) > 1:
            raise TypeError('takes %d positional arguments but %d were given' %
                            (1, len(node.args)))
        value = self.visit(node.args[0])
        if not isinstance(value, numerical_types):
            return len(value)

        ln = getattr(value, '_len', None)
        if ln is not None:
            return ln

        return vtypes.get_width(value)
Example #3
0
def write(dst, value, blk=False, ldelay=None, rdelay=None, method='write'):
    width = vtypes.get_width(dst)
    signed = vtypes.get_signed(dst)

    if signed:
        max = _pow2(width - 1) - 1
        min = _pow2(width - 1) * (-1)
    else:
        max = _pow2(width) - 1
        min = 0

    sat_val = to_saturate(value, width=width, max=max, min=min, signed=signed)

    return getattr(dst, method)(sat_val, blk=blk, ldelay=ldelay, rdelay=rdelay)
Example #4
0
    def __init__(self,
                 m,
                 name,
                 clk,
                 addr,
                 values,
                 enable=None,
                 datawidth=None):

        self.m = m
        self.name = name
        self.clk = clk

        size = int(math.ceil(math.log(len(values), 2)))
        self.addr = self.m.Wire(name + '_addr', size)
        self.m.Assign(self.addr(addr))

        if datawidth is None:
            datawidth = 1
            for v in values:
                w = vtypes.get_width(v)
                if w is not None and w > datawidth:
                    datawidth = w

        with_enable = enable is not None
        if enable is not None:
            self.enable = self.m.Wire(name + '_enable')
            self.m.Assign(self.enable(enable))

        self.rdata = self.m.Wire(name + '_val', datawidth)
        sync = True if clk is not None else False
        rom_def = mkROMDefinition(name, values, size, datawidth, sync,
                                  with_enable)

        ports = []
        if clk is not None:
            ports.append(self.clk)

        ports.append(self.addr)

        if enable is not None:
            ports.append(self.enable)

        ports.append(self.rdata)

        self.m.Instance(rom_def, name, params=(), ports=ports)
Example #5
0
    def pack(self, *args):
        rslts = [self.visit(arg) for arg in args]
        all_stage_none = reduce(lambda t, x: t and x is None,
                                [rslt[0] for rslt in rslts], True)

        if all_stage_none:
            data = [rslt[1] for rslt in rslts]
            valid = reduce(self.pack_valid, [rslt[2] for rslt in rslts], None)
            ready = reduce(self.pack_ready, [rslt[3] for rslt in rslts], [])
            return (None, data, valid, ready)

        max_stage = reduce(
            lambda x, y: None if x is None and y is None else x
            if x is not None and y is None else y
            if y is not None and x is None else max(x, y),
            [rslt[0] for rslt in rslts], None)

        new_args = []
        for rslt, arg in zip(rslts, args):
            stage = rslt[0]
            if stage is None:
                new_args.append(arg)
                continue
            if stage == max_stage:
                new_args.append(arg)
                continue

            diff = max_stage - stage
            p = arg
            for i in range(diff):
                width = vtypes.get_width(rslt[1])
                p = self.df.stage(p, width=width, preg=arg)

            new_args.append(p)

        new_rslts = [self.visit(arg) for arg in new_args]
        data = [rslt[1] for rslt in new_rslts]
        valid = reduce(self.pack_valid, [rslt[2] for rslt in new_rslts], None)
        ready = reduce(self.pack_ready, [rslt[3] for rslt in new_rslts], [])

        return (max_stage, data, valid, ready)
Example #6
0
    def visit_Cat(self, node):
        left_values = []
        right_values = []

        for v in node.vars:
            val = self.visit(v)
            width = vtypes.get_width(v)
            if width is None:
                width = 1
            if val is None:
                right = vtypes.IntX(width)
            elif isinstance(val.right, int):
                right = vtypes.Int(val.right, width)
            elif isinstance(val.right, vtypes._Constant):
                right = copy.deepcopy(val.right)
                right.width = width
            else:
                right = v._get_module().TmpLocalparam(val.right, width)

            left_values.append(v)
            right_values.append(right)

        return vtypes.Subst(vtypes.Cat(*left_values), vtypes.Cat(*right_values))
Example #7
0
    def _add_delayed_subst(self, subst, delay):
        if not isinstance(subst, vtypes.Subst):
            return subst
        left = subst.left
        right = subst.right
        if isinstance(right, (bool, int, float, str, vtypes._Constant,
                              vtypes._ParameterVariable)):
            return subst
        width = vtypes.get_width(left)
        signed = vtypes.get_signed(left)
        prev = right

        name_prefix = ('_'.join([
            '', left.name, str(self.tmp_count)
        ]) if isinstance(left, vtypes._Variable) else '_'.join(
            ['', self.name, 'sbst', str(self.tmp_count)]))
        self.tmp_count += 1

        for i in range(delay):
            tmp_name = '_'.join([name_prefix, str(i + 1)])
            tmp = self.m.Reg(tmp_name, width, initval=0, signed=signed)
            self._add_statement([tmp(prev)], delay=i, no_delay_cond=True)
            prev = tmp
        return left(prev)
Example #8
0
    def __init__(self,
                 m,
                 name,
                 clk,
                 rst,
                 left,
                 right,
                 enable=None,
                 update=None,
                 lwidth=None,
                 rwidth=None,
                 lsigned=True,
                 rsigned=True,
                 depth=6):

        if lwidth is None:
            lwidth = vtypes.get_width(left)
        if lwidth is None:
            lwidth = 1

        if rwidth is None:
            rwidth = vtypes.get_width(right)
        if rwidth is None:
            rwidth = 1

        retwidth = lwidth + rwidth

        with_enable = True if enable is not None else False
        with_update = True if update is not None else False

        self.m = m
        self.name = name
        self.clk = clk
        self.rst = rst

        self.enable = enable
        self.update = update

        if with_enable:
            self.valid = self.m.Wire(name + '_valid')

        self.left = left
        self.right = right
        self.value = self.m.Wire(name + '_value', retwidth)

        mul_def = mkMultiplier(name, lsigned, rsigned, depth, with_update,
                               with_enable)

        params = [('lwidth', lwidth), ('rwidth', rwidth)]

        ports = []
        ports.append(self.clk)
        ports.append(self.rst)

        if with_update:
            ports.append(self.update)

        if with_enable:
            ports.append(self.enable)
            ports.append(self.valid)

        ports.append(self.left)
        ports.append(self.right)
        ports.append(self.value)

        self.m.Instance(mul_def, name, params=params, ports=ports)
Example #9
0
    def add_dump(self, m, seq, input_vars, output_vars, all_vars):
        pipeline_depth = self.pipeline_depth()
        log_pipeline_depth = max(
            int(math.ceil(math.log(max(pipeline_depth, 10), 10))), 1)

        seq(
            self.dump_step(1)
        )

        for i in range(pipeline_depth + 1):
            seq.If(seq.Prev(self.dump_enable, i))(
                self.dump_step.inc()
            )

        def get_name(obj):
            if hasattr(obj, 'name'):
                return obj.name
            if isinstance(obj, vtypes._Constant):
                return obj.__class__.__name__
            raise TypeError()

        longest_name_len = 0
        for input_var in sorted(input_vars, key=lambda x: x.object_id):
            if not (self.dump_mode == 'all' or
                    self.dump_mode == 'stream' or
                    self.dump_mode == 'input' or
                    self.dump_mode == 'inout' or
                    (self.dump_mode == 'selective' and
                        hasattr(input_var, 'dump') and input_var.dump)):
                continue

            name = get_name(input_var.sig_data)
            length = len(name) + 6
            longest_name_len = max(longest_name_len, length)

        for var in sorted(all_vars, key=lambda x: (-1, x.object_id)
                          if x.end_stage is None else
                          (x.end_stage, x.object_id)):
            if not (self.dump_mode == 'all' or
                    self.dump_mode == 'stream' or
                    (self.dump_mode == 'selective' and
                        hasattr(var, 'dump') and var.dump)):
                continue

            name = get_name(var.sig_data)
            length = len(name) + 6
            longest_name_len = max(longest_name_len, length)

        for output_var in sorted(output_vars, key=lambda x: x.object_id):
            if not (self.dump_mode == 'all' or
                    self.dump_mode == 'stream' or
                    self.dump_mode == 'output' or
                    self.dump_mode == 'inout' or
                    (self.dump_mode == 'selective' and
                        hasattr(output_var, 'dump') and output_var.dump)):
                continue

            name = get_name(output_var.output_sig_data)
            length = len(name) + 6
            longest_name_len = max(longest_name_len, length)

        longest_var_len = 0
        for var in sorted(all_vars, key=lambda x: (-1, x.object_id)
                          if x.start_stage is None else
                          (x.start_stage, x.object_id)):
            bitwidth = vtypes.get_width(var.sig_data)
            if bitwidth is None:
                bitwidth = 1
            if bitwidth <= 0:
                bitwidth = 1

            base = (var.dump_base if hasattr(var, 'dump_base') else
                    self.dump_base)
            total_length = int(math.ceil(bitwidth / math.log(base, 2)))
            #point_length = int(math.ceil(var.point / math.log(base, 2)))
            #point_length = max(point_length, 8)
            #longest_var_len = max(longest_var_len, total_length, point_length)
            longest_var_len = max(longest_var_len, total_length)

        for input_var in sorted(input_vars, key=lambda x: x.object_id):

            base = (input_var.dump_base if hasattr(input_var, 'dump_base') else
                    self.dump_base)
            base_char = ('b' if base == 2 else
                         'o' if base == 8 else
                         'd' if base == 10 and input_var.point <= 0 else
                         # 'f' if base == 10 and input_var.point > 0 else
                         'g' if base == 10 and input_var.point > 0 else
                         'x')
            prefix = ('0b' if base == 2 else
                      '0o' if base == 8 else
                      '  ' if base == 10 else
                      '0x')

            # if base_char == 'f':
            #    point_length = int(math.ceil(input_var.point / math.log(base, 2)))
            #    point_length = max(point_length, 8)
            #    fmt_list = [prefix, '%',
            #                '%d.%d' % (longest_var_len + 1, point_length), base_char]
            # if base_char == 'g':
            #    fmt_list = [prefix, '%', base_char]
            # else:
            #    fmt_list = [prefix, '%', '%d' % (longest_var_len + 1), base_char]
            fmt_list = [prefix, '%', '%d' % (longest_var_len + 1), base_char]

            if input_var not in all_vars:
                fmt_list.append(' (unused)')

            input_var.dump_fmt = ''.join(fmt_list)

        for output_var in sorted(output_vars, key=lambda x: x.object_id):

            base = (output_var.dump_base if hasattr(output_var, 'dump_base') else
                    self.dump_base)
            base_char = ('b' if base == 2 else
                         'o' if base == 8 else
                         'd' if base == 10 and output_var.point <= 0 else
                         # 'f' if base == 10 and output_var.point > 0 else
                         'g' if base == 10 and output_var.point > 0 else
                         'x')
            prefix = ('0b' if base == 2 else
                      '0o' if base == 8 else
                      '  ' if base == 10 else
                      '0x')

            # if base_char == 'f':
            #    point_length = int(math.ceil(output_var.point / math.log(base, 2)))
            #    point_length = max(point_length, 8)
            #    fmt_list = [prefix, '%',
            #                '%d.%d' % (longest_var_len + 1, point_length), base_char]
            # if base_char == 'g':
            #    fmt_list = [prefix, '%', base_char]
            # else:
            #    fmt_list = [prefix, '%', '%d' % (longest_var_len + 1), base_char]
            fmt_list = [prefix, '%', '%d' % (longest_var_len + 1), base_char]

            if output_var not in all_vars:
                fmt_list.append(' (unused)')

            output_var.dump_fmt = ''.join(fmt_list)

        for var in sorted(all_vars, key=lambda x: (-1, x.object_id)
                          if x.start_stage is None else
                          (x.start_stage, x.object_id)):

            base = (var.dump_base if hasattr(var, 'dump_base') else
                    self.dump_base)
            base_char = ('b' if base == 2 else
                         'o' if base == 8 else
                         'd' if base == 10 and var.point <= 0 else
                         # 'f' if base == 10 and var.point > 0 else
                         'g' if base == 10 and var.point > 0 else
                         'x')
            prefix = ('0b' if base == 2 else
                      '0o' if base == 8 else
                      '  ' if base == 10 else
                      '0x')

            # if base_char == 'f':
            #    point_length = int(math.ceil(var.point / math.log(base, 2)))
            #    point_length = max(point_length, 8)
            #    fmt_list = [prefix, '%',
            #                '%d.%d' % (longest_var_len + 1, point_length), base_char]
            # if base_char == 'g':
            #    fmt_list = [prefix, '%', base_char]
            # else:
            #    fmt_list = [prefix, '%', '%d' % (longest_var_len + 1), base_char]
            fmt_list = [prefix, '%', '%d' % (longest_var_len + 1), base_char]

            var.dump_fmt = ''.join(fmt_list)

        enables = []
        for input_var in sorted(input_vars, key=lambda x: x.object_id):
            if not (self.dump_mode == 'all' or
                    self.dump_mode == 'stream' or
                    self.dump_mode == 'input' or
                    self.dump_mode == 'inout' or
                    (self.dump_mode == 'selective' and
                        hasattr(input_var, 'dump') and input_var.dump)):
                continue

            vfmt = input_var.dump_fmt

            name = get_name(input_var.sig_data)
            name_alignment = ' ' * (longest_name_len - len(name) -
                                    len('(in) '))
            fmt = ''.join(['<', self.name, ' step:%d, ',
                           'stage:%', str(
                               log_pipeline_depth), 'd, age:%d> (in) ',
                           name_alignment, name, ' = ', vfmt])

            stage = input_var.end_stage if input_var.end_stage is not None else 0
            enable = seq.Prev(self.dump_enable, stage)
            enables.append(enable)
            age = seq.Prev(self.dump_step, stage) - 1

            if input_var.point > 0:
                sig_data = vtypes.Div(vtypes.SystemTask('itor', input_var.sig_data),
                                      1.0 * (2 ** input_var.point))
            elif input_var.point < 0:
                sig_data = vtypes.Times(input_var.sig_data, 2 ** -input_var.point)
            else:
                sig_data = input_var.sig_data

            seq.If(enable, vtypes.Not(self.dump_mask))(
                vtypes.Display(fmt, self.dump_step, stage, age, sig_data)
            )

        for var in sorted(all_vars, key=lambda x: (-1, x.object_id)
                          if x.end_stage is None else
                          (x.end_stage, x.object_id)):
            if not (self.dump_mode == 'all' or
                    self.dump_mode == 'stream' or
                    (self.dump_mode == 'selective' and
                        hasattr(var, 'dump') and var.dump)):
                continue

            vfmt = var.dump_fmt

            name = get_name(var.sig_data)
            name_alignment = ' ' * (longest_name_len - len(name))
            stage = var.end_stage if var.end_stage is not None else 0

            fmt = ''.join(['<', self.name, ' step:%d, ',
                           'stage:%', str(log_pipeline_depth), 'd, age:%d> ',
                           name_alignment, name, ' = ', vfmt])

            enable = seq.Prev(self.dump_enable, stage)
            enables.append(enable)
            age = seq.Prev(self.dump_step, stage) - 1

            if var.point > 0:
                sig_data = vtypes.Div(vtypes.SystemTask('itor', var.sig_data),
                                      1.0 * (2 ** var.point))
            elif var.point < 0:
                sig_data = vtypes.Times(var.sig_data, 2 ** -var.point)
            else:
                sig_data = var.sig_data

            seq.If(enable, vtypes.Not(self.dump_mask))(
                vtypes.Display(fmt, self.dump_step, stage, age, sig_data)
            )

        for output_var in sorted(output_vars, key=lambda x: x.object_id):
            if not (self.dump_mode == 'all' or
                    self.dump_mode == 'stream' or
                    self.dump_mode == 'output' or
                    self.dump_mode == 'inout' or
                    (self.dump_mode == 'selective' and
                        hasattr(output_var, 'dump') and output_var.dump)):
                continue

            vfmt = output_var.dump_fmt

            name = get_name(output_var.output_sig_data)
            name_alignment = ' ' * (longest_name_len - len(name) -
                                    len('(out) '))
            fmt = ''.join(['<', self.name, ' step:%d, ',
                           'stage:%', str(
                               log_pipeline_depth), 'd, age:%d> (out) ',
                           name_alignment, name, ' = ', vfmt])

            stage = output_var.end_stage if output_var.end_stage is not None else 0
            enable = seq.Prev(self.dump_enable, stage)
            enables.append(enable)
            age = seq.Prev(self.dump_step, stage) - 1

            if output_var.point > 0:
                sig_data = vtypes.Div(vtypes.SystemTask('itor', output_var.output_sig_data),
                                      1.0 * (2 ** output_var.point))
            elif output_var.point < 0:
                sig_data = vtypes.Times(output_var.output_sig_data, 2 ** -output_var.point)
            else:
                sig_data = output_var.output_sig_data

            seq.If(enable, vtypes.Not(self.dump_mask))(
                vtypes.Display(fmt, self.dump_step, stage, age, sig_data)
            )
Example #10
0
 def get_width(self):
     return vtypes.get_width(self.data)
Example #11
0
def reinterpret_cast_to_fixed(value, point, signed=True):
    m = value._get_module()
    width = vtypes.get_width(value)
    v = FixedTmpWire(m, width=width, point=point, signed=signed)
    v.assign_raw(value)
    return v