Exemple #1
0
def infer_dtype(val, dtype):
    if is_type(type(val)):
        return type(val)

    if not is_type(dtype) or typeof(dtype, Any):
        if isinstance(val, int):
            if val < 0:
                return type(Int(val))
            else:
                return type(Uint(val))

    if dtype.specified:
        return dtype

    return type(dtype.base(val))
Exemple #2
0
def fixp_type_trunc_resolver(cast_type: FixpnumberType, dtype):
    if not is_type(dtype) or dtype.base != cast_type.base:
        raise TypeError(
            f"cannot truncate type '{repr(dtype)}' to a type '{repr(cast_type)}'"
            f" of a different base type")

    return cast_type
Exemple #3
0
def pipeline(din, *, length, feedback=False, init=None) -> b'din':
    if init is None:
        init = []

    if is_type(init) or not isinstance(init, (list, tuple)):
        init = [init] * length

    if feedback:
        if init:
            stage_init = init[0]
            init.pop(0)
        else:
            stage_init = None

        din = decouple(din, init=stage_init)
        length -= 1

    inputs = [din]
    for i in range(length):
        if init:
            stage_init = init[0]
            init.pop(0)
        else:
            stage_init = None

        dout = dreg(inputs.pop(0), init=stage_init)
        inputs.append(dout)

    return inputs.pop(0)
Exemple #4
0
def _(node, ctx: Context):
    targets = visit_ast(node.target, ctx)
    annotation = visit_ast(node.annotation, ctx)

    if not (isinstance(annotation, ir.ResExpr)
            or isinstance(annotation.val, type) or is_type(annotation.val)):
        raise SyntaxError(
            f'Variable annotation has to be a type, not "{annotation}"')

    if node.value is None:
        output_port_shadow_check(targets.name, ctx)
        ctx.scope[targets.name] = ir.Variable(targets.name, annotation.val)
        return

    if node.value:
        init = visit_ast(node.value, ctx)

        init_cast = ir.CastExpr(init, annotation.val)
        stmts = assign_targets(ctx, targets, init_cast)
        if not isinstance(stmts, list):
            stmts = [stmts]

        # for s in stmts:
        #     s.target.obj.val = s.val
        #     if init.val is None or getattr(init.val, 'unknown', False):
        #         s.target.obj.any_init = True

        return stmts
Exemple #5
0
def infer_targets(ctx, target, source):
    dtype = source.dtype
    if isinstance(target, ir.Name):
        ctx.alias_map[target.name] = source
        if target.name not in ctx.scope:
            var = ir.Variable(target.name,
                              dtype,
                              reg=target.name in ctx.registers)
            ctx.scope[target.name] = var
            target.obj = var
        else:
            output_port_shadow_check(target.name, ctx)

    elif isinstance(target, ir.ConcatExpr):
        # We can only make this check if the value is recognized PyGears type.
        # If it is some random Python type, just hope for the best
        if is_type(dtype) and len(dtype) != len(target.operands):
            raise SyntaxError(
                f'Cannot unpack value of type "{dtype!r}" with {len(dtype)} component(s) into {len(target.operands)} variables: '
                f'"{target}".')

        for i, t in enumerate(target.operands):
            infer_targets(ctx, t, ir.SubscriptExpr(source, ir.ResExpr(i)))
    elif isinstance(target, ir.SubscriptExpr):
        # # TODO: can we do some check here?
        if isinstance(target.val, ir.Name):
            ctx.alias_map[target.val.name] = ctx.ref(target.val.name)
    else:
        breakpoint()
Exemple #6
0
def shr_or_code(x, y):
    if is_type(y):
        if typeof(y, Uint) and (not y.specified):
            y = Uint[x.dtype.width]

        return code(x, t=y)
    else:
        return shr(x, shamt=y)
Exemple #7
0
def integer_type_trunc_resolver(cast_type: IntegerType, dtype):
    if dtype is int:
        return cast_type

    if not is_type(dtype) or dtype.base != cast_type.base:
        raise TypeError(
            f"cannot truncate type '{repr(dtype)}' to a type '{repr(cast_type)}'"
            f" of a different base type")

    return cast_type
Exemple #8
0
    def dtype(self):
        # if is_type(type(self.val)):
        #     return type(self.val)

        if not is_type(type(self.val)) and isinstance(self.val, int):
            return type(Integer(self.val))

        if isinstance(self.val, Intf):
            return IntfType[self.val.dtype]

        return type(self.val)
Exemple #9
0
    def __new__(cls, operands: typing.Sequence[Expr]):
        if all(isinstance(v, ResExpr) for v in operands):
            if all(is_type(v.dtype) for v in operands):
                return ResExpr(Tuple[tuple(v.dtype for v in operands)](tuple(v.val
                                                                             for v in operands)))
            else:
                return ResExpr(tuple(v.val for v in operands))

        inst = super().__new__(cls)
        inst.operands = operands

        return inst
Exemple #10
0
    def dtype(self):
        # if is_type(type(self.val)):
        #     return type(self.val)

        if not is_type(type(self.val)) and isinstance(self.val, int):
            return type(Integer(self.val))

        # TODO: Remove this if unecessary
        if isinstance(self.val, Intf):
            return IntfType[self.val.dtype]

        return type(self.val)
Exemple #11
0
def vgen_signal(dtype, vtype, name, direction, hier=True):
    if isinstance(dtype, str):
        return f'{dtype} {name};'

    if is_type(dtype) and dtype.width == 0:
        return f'{vtype} [0:0] {name};'

    if not hier:
        if is_type(dtype):
            width = dtype.width
            sign = 'signed' if getattr(dtype, 'signed', False) else ''
        elif isinstance(dtype, (tuple, list)):
            width = sum(d.width for d in dtype)
            sign = ''

        return f'{vtype} {sign} [{width-1}:0] {name}; // {dtype}'

    vis = VGenTypeVisitor(name,
                          basic_type=vtype,
                          direction=direction,
                          hier=hier)

    return '\n'.join(vis.visit(type_=dtype, field=name))
Exemple #12
0
def field_names_eq(a, b):
    if not hasattr(a, 'fields'):
        return True

    if a.fields != b.fields:
        return False

    for aa, ab in zip(a.args, b.args):
        if not is_type(aa):
            continue

        if not field_names_eq(aa, ab):
            return False

    return True
Exemple #13
0
    def description(self):
        tooltip = '<b>{}</b><br/><br/>'.format(self.name)
        pp = pprint.PrettyPrinter(indent=4, width=30)
        fmt = pp.pformat

        def _pprint_list(self, object, stream, indent, allowance, context,
                         level):
            if len(object) > 5:
                object = object[:5] + ['...']

            pprint.PrettyPrinter._pprint_list(self, object, stream, indent,
                                              allowance, context, level)

        pp._dispatch[list.__repr__] = _pprint_list

        table = []
        for name, val in self.rtl.params.items():
            name_style = 'style="font-weight:bold" nowrap'
            val_style = ''

            if name == 'definition':
                val = val.func.__name__
                val_style = 'style="font-weight:bold"'
            elif inspect.isclass(val) and not is_type(val):
                val = val.__name__
            elif name not in registry('gear/params/extra').keys():
                # if isinstance(val, (list, tuple)) and len(val) > 5:
                #     val = fmt(val[:2]) + '\n...'

                val = highlight(fmt(val), 'py', add_style=False)
            else:
                continue

            table.append([(name_style, name), (val_style, val)])

        table_style = """
<style>
td {
padding-left: 10px;
padding-right: 10px;
}
</style>
        """

        tooltip += table_style
        tooltip += tabulate(table, 'style="padding-right: 10px;"')

        return tooltip
Exemple #14
0
    def visit_SubscriptExpr(self, node):
        val = self.visit(node.val)

        if isinstance(node.index, slice):
            return f'{val}[{int(node.index.stop) - 1}:{node.index.start}]'

        dtype = node.val.dtype
        if typeof(dtype, Array):
            index = self.visit(node.index)
            return f'{val}_arr[{index}]'
        elif typeof(dtype, Number):
            return f'{val}[{self.visit(node.index)}]'
        elif is_type(dtype):
            return f'{val}_{dtype.fields[node.index]}'
        else:
            raise Exception('Unable to subscript')
Exemple #15
0
def svgen_typedef(dtype, name, depth=4):
    # TODO: if a variable is called "wr", of the type that has a composite
    # field "data", than struct for that field will be called "wr_data_t". If
    # there is a variable "wr_data" in same module, it will also have the type
    # called "wr_data_t". This can be in conflict when the type definitions are
    # added for verilator debugging. Maybe think of a different scheme to name
    # subtypes
    if isinstance(dtype, str):
        return f'typedef {dtype} {name}_t;'

    assert is_type(dtype)

    if dtype.width == 0:
        return f'typedef logic [0:0] {name}_t;'

    vis = SVGenTypeVisitor(name, depth=depth)
    vis.visit(type_=dtype, field=name)
    return '\n'.join(vis.struct_array)
Exemple #16
0
def integral_saturate_resolver(t, data: Integral, limits=None):
    if not is_type(type(data)) and isinstance(data, int):
        conv_data = Integer(data)
    else:
        conv_data = data

    idin = code(data)

    if type(conv_data).signed == t.signed and type(conv_data).width <= t.width:
        if type(conv_data).signed:
            sign = code(data, int) >> (type(conv_data).width - 1)
            sign_exten = Uint[t.width -
                              type(conv_data).width].max if sign else 0
            return t.decode((sign_exten << type(conv_data).width)
                            | code(data, int))
        else:
            return code(conv_data, t)
    elif type(conv_data).signed and not t.signed:
        if idin[t.width:] == 0:
            return code(conv_data, t)
        elif conv_data < 0:
            return 0
        else:
            return t.max
    elif type(conv_data).signed and t.signed:
        # TODO: This 0 is not typecast, check why that happens
        if ((idin[t.width - 1:] == 0)
                or (idin[t.width - 1:]
                    == Uint[type(conv_data).width - t.width + 1].max)):
            return code(conv_data, t)
        elif idin[-1]:
            return t.min
        else:
            return t.max
    else:
        if type(conv_data).width <= t.width or idin[t.width:] == 0:
            return code(conv_data, t)
        else:
            return t.max
Exemple #17
0
    def params(self):
        if not self.impl_params:
            return {}

        params = {}
        for k, v in self.node.params.items():
            param_name = k.upper()
            param_valid_name = f'{param_name}_VALID'

            if (param_name in self.impl_params):
                if v is None:
                    if param_valid_name in self.impl_params:
                        params[param_valid_name] = 0
                    continue

                if is_type(v):
                    v = max(v.width, 1)

                err = None
                try:
                    v = code(v, int)
                except:
                    err = ValueError(
                        f'Cannot encode value "{v}" as integer, passed for HDL parameter "{param_name}"\n'
                        f' - when instantiating module "{self.node.name}"')

                if err:
                    raise err

                if (code(v, int) != int(self.impl_params[param_name]['val'])):
                    params[param_name] = code(v, int)

                if param_valid_name in self.impl_params:
                    params[param_valid_name] = 1

        return params
Exemple #18
0
def resolve_func(func, args, kwds, ctx):
    if is_type(func):
        if const_func_args(args, kwds):
            return resolve_compile_time(func, args, kwds)

        return resolve_cast_func(args[0], func)

    hashable_func = hashable(func)

    if isinstance(func, partial):
        args = func.args + tuple(args)
        func = func.func
    elif not inspect.isbuiltin(func) and hasattr(func, '__self__'):
        if func is super:
            if not isinstance(ctx, FuncContext):
                raise Exception(f'super() called outside a method function')

            f = ctx.funcref.func
            obj = ctx.ref('self')
            cls = get_class_that_defined_method(f).__base__

            return ir.ResExpr(Super(cls, obj))
        elif getattr(func, '__func__', None) in reg['hls/ir_builtins']:
            val = func.__self__
            for name, v in ctx.scope.items():
                if val is v.val:
                    val = ctx.ref(name)
                    break

            return reg['hls/ir_builtins'][func.__func__](val, *args, **kwds)
        elif const_func_args(args, kwds):
            return resolve_compile_time(func, args, kwds)
        elif is_type(func.__self__):
            if func.__name__ == 'decode':
                return ir.CastExpr(args[0], ir.ResExpr(func.__self__))
            else:
                breakpoint()
                raise Exception
        else:
            breakpoint()
            raise Exception

    if hashable_func and func not in reg['hls/ir_builtins']:
        if func in special_funcs:
            return resolve_func(getattr(args[0].dtype, special_funcs[func]), args, kwds, ctx)

    if isinstance(func, Partial):
        intf, stmts = call_gear(func, *form_gear_args(args, kwds, func), ctx)
        ctx.ir_parent_block.stmts.extend(stmts)
        return intf

    if hashable_func and func in compile_time_builtins and const_func_args(args, kwds):
        return resolve_compile_time(func, args, kwds)

    if hashable_func and func in reg['hls/ir_builtins']:
        try:
            return reg['hls/ir_builtins'][func](*args, **kwds)
        except TypeError as e:
            raise SyntaxError(str(e).replace('<lambda>()', repr(func)))

    if const_func_args(args, kwds):
        return resolve_compile_time(func, args, kwds)
    elif hasattr(func, 'dispatch'):
        return resolve_func(func.dispatch(args[0].dtype), args, kwds, ctx)
    else:
        return parse_func_call(func, args, kwds, ctx)
Exemple #19
0
def call_is_type(arg):
    if not isinstance(arg, ir.ResExpr):
        return ir.res_false

    return ir.ResExpr(is_type(arg.val))
Exemple #20
0
def trunc(data, t):
    if is_type(data):
        return type_trunc(t, data)
    else:
        return value_trunc(type_trunc(t, type(data)), data)
Exemple #21
0
def saturate(data, t, limits=None):
    if is_type(data):
        return type_saturate(t, data)
    else:
        return value_saturate(type_saturate(t, type(data)), data, limits)