Ejemplo n.º 1
0
def get_port_def(top, name, axi_name, subintf, parent, axi_conf):
    for p in top.in_ports + top.out_ports:
        if p.basename == name:
            break
    else:
        breakpoint()
        raise Exception(
            f'Port "{name}" supplied for {subintf} port of the'
            f' {axi_name} interface, not found')

    if axi_conf['type'] == 'axi':
        if p.direction == 'in' and subintf not in ['araddr', 'awaddr', 'wdata']:
            raise Exception(
                f'Cannot drive gear port {name} from AXi port {axi_name}.{subintf}')

        if p.direction == 'out' and subintf not in ['rdata']:
            raise Exception(
                f'Cannot drive AXi port {axi_name}.{subintf} from gear port {name}')

    if subintf == 'awaddr':
        if typeof(p.dtype, Tuple) and axi_conf.get('wdata', '') == name:
            return port_conf(parent, subintf, p, 0)

    if subintf == 'araddr':
        if typeof(p.dtype, Tuple) and axi_conf.get('wdata', '') == name:
            return port_conf(parent, subintf, p, 0)

    if subintf == 'wdata':
        if typeof(p.dtype, Tuple) and axi_conf.get('awaddr', '') == name:
            if typeof(p.dtype[1], Union) and axi_conf.get('araddr', '') == name:
                return port_conf(parent, subintf, p, (1, 0))
            else:
                return port_conf(parent, subintf, p, 1)

    return port_conf(parent, subintf, p)
Ejemplo n.º 2
0
def register_traces_for_intf(dtype, scope, writer):
    vcd_vars = {}

    if typeof(dtype, TLM):
        vcd_vars['data'] = writer.register_var(scope, 'data', 'string')
    else:
        v = VCDTypeVisitor()
        v.visit(dtype, 'data')

        for name, t in v.fields.items():
            field_scope, _, basename = name.rpartition('.')
            if field_scope:
                field_scope = '.'.join((scope, field_scope))
            else:
                field_scope = scope

            if typeof(t, Float):
                vcd_vars[name] = writer.register_var(field_scope,
                                                     basename,
                                                     var_type='real',
                                                     size=32)
            else:
                vcd_vars[name] = writer.register_var(field_scope,
                                                     basename,
                                                     var_type='wire',
                                                     size=max(t.width, 1))

    for sig in ('valid', 'ready'):
        vcd_vars[sig] = writer.register_var(scope, sig, 'wire', size=1, init=0)

    return vcd_vars
Ejemplo n.º 3
0
    def visit_SubscriptExpr(self, node):
        val = self.visit(node.val)

        if val is None:
            return None

        if isinstance(node.index, ir.ResExpr):
            index = node.index.val

            index = node.val.dtype.index_norm(index)[0]

            if isinstance(index, slice):
                stop = int(index.stop) - 1
                start = int(index.start)

                if isinstance(node.val, (ir.Name, ir.AttrExpr)):
                    return f'{val}[{stop}:{start}]'
            else:
                if index == node.val.dtype.keys()[0]:
                    start = 0
                else:
                    start = node.val.dtype[:index].width

                stop = start + node.val.dtype[index].width - 1
                index = int(index)

                if isinstance(node.val, (ir.Name, ir.AttrExpr, ir.Component)):
                    if typeof(node.val.dtype, (Tuple, Union, Queue)):
                        return f'{val}{self.separator}{node.val.dtype.fields[index]}'
                    else:
                        return f'{val}[{index}]'

            if isinstance(node.val, ir.ResExpr):
                if typeof(node.val.dtype, Array):
                    return f'{val}[{index}]'
                elif typeof(node.val.dtype, Integral):
                    return f'{val}[{index}]'
                elif typeof(node.val.dtype, (Tuple, Union, Queue)):
                    return f'{val}{self.separator}{node.val.dtype.fields[index]}'
            else:
                fname = get_slice_func(self.aux_funcs, start, stop,
                                       node.val.dtype.width,
                                       getattr(node.dtype, 'signed', False))
                return f'{fname}({val})'

        if typeof(node.val.dtype, (Array, Queue, Integer, Tuple, Union)):
            ind = self.visit(node.index)
            if isinstance(node.val, ir.Name):
                return f'{val}[{ind}]'
            else:
                fname = get_index_func(self.aux_funcs, node.val.dtype.width,
                                       node.index.dtype.width,
                                       node.dtype.width,
                                       getattr(node.dtype, 'signed', False))

                return f'{fname}({val}, {ind})'

        breakpoint()
        raise Exception('Unsupported slicing')
Ejemplo n.º 4
0
def call_int(arg, **kwds):
    # ignore cast
    if typeof(arg.dtype, (Uint, Int)):
        return arg
    elif typeof(arg.dtype, Integral):
        if arg.dtype.signed:
            return ir.CastExpr(arg, cast_to=Int[arg.dtype.width])
        else:
            return ir.CastExpr(arg, cast_to=Uint[arg.dtype.width])
    else:
        return ir.ResExpr(NotImplemented)
Ejemplo n.º 5
0
def test_pysim_dir(sel, din_t, seq, sim_cls):
    if seq == 'rand':
        skip_ifndef('RANDOM_TEST')
        seq = [(random.randint(1, 100), random.randint(0, 2))
               for _ in range(random.randint(10, 50))]

    if typeof(din_t, Queue):
        queue_filt_test(din_t, seq, sel, sim_cls)
    elif typeof(din_t, Union):
        filt_test(din_t, seq, sel, sim_cls)
    else:
        filt_by_test(din_t, seq, sel, sim_cls)
Ejemplo n.º 6
0
def max_expr(op1, op2):
    op1_compare = op1
    op2_compare = op2

    # TODO: Sort this casting out
    signed = typeof(op1.dtype, Int) or typeof(op2.dtype, Int)
    if signed and typeof(op1.dtype, Uint):
        op1_compare = resolve_cast_func(op1, Int)
    if signed and typeof(op2.dtype, Uint):
        op2_compare = resolve_cast_func(op2, Int)

    cond = ir.BinOpExpr((op1_compare, op2_compare), ir.opc.Gt)
    return ir.ConditionalExpr(cond=cond, operands=(op1, op2))
Ejemplo n.º 7
0
def maybe_resolver(opexp, cast_to):
    cast_to = cast(opexp.dtype, cast_to)

    if typeof(opexp.dtype, Tuple):
        data = resolve_cast_func(ir.SubscriptExpr(opexp, ir.ResExpr(0)),
                                 cast_to.dtype)
        ctrl = resolve_cast_func(ir.SubscriptExpr(opexp, ir.ResExpr(1)),
                                 cast_to[1])
        return ir.CastExpr(ir.ConcatExpr([data, ctrl]), cast_to)
    elif typeof(opexp.dtype, Union):
        return ir.CastExpr(opexp, cast_to)
    else:
        breakpoint()
Ejemplo n.º 8
0
def booleq(op1, op2, operator):
    if operator not in [opc.Eq, opc.NotEq]:
        return

    if not (typeof(op1.dtype,
                   (Bool, Uint[1])) and typeof(op2.dtype, (Bool, Uint[1]))):
        return

    if op2 == res_true:
        return op1 if operator == opc.Eq else UnaryOpExpr(op1, opc.Not)

    if op2 == res_false:
        return op1 if operator == opc.NotEq else UnaryOpExpr(op1, opc.Not)

    return None
Ejemplo n.º 9
0
def integral_type_saturate_resolver(cast_type, dtype):
    if dtype is not int and not typeof(dtype, Integer):
        raise TypeError(
            f"cannot saturate '{repr(dtype)}' to a different base type '{repr(cast_type)}'"
        )

    return cast_type
Ejemplo n.º 10
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')
Ejemplo n.º 11
0
def call_tuple(arg):
    if isinstance(arg, ir.ConcatExpr):
        return ir.TupleExpr(arg.operands)
    elif isinstance(arg, ir.TupleExpr):
        return arg
    elif isinstance(arg, ir.ResExpr):
        # TODO: Array is a list, so we have a workaround here
        if typeof(arg.dtype, (Tuple, Array, Queue)):
            return arg
        else:
            return ir.ResExpr(tuple(arg.val))
    elif typeof(arg.dtype, (Array, Tuple)):
        return ir.ConcatExpr([ir.SubscriptExpr(arg, ir.ResExpr(i)) for i in range(len(arg.dtype))])
    else:
        breakpoint()
        raise Exception
Ejemplo n.º 12
0
    def __new__(cls, operand, cast_to):
        if isinstance(cast_to, ResExpr):
            cast_to = cast_to.val

        if cast_to == int:
            cast_to = Uint[operand.dtype.width]

        if operand.dtype == cast_to:
            return operand

        if isinstance(operand, ResExpr):
            return ResExpr(code(operand.val, cast_to))

        if isinstance(operand, ConcatExpr) and typeof(
                cast_to, (Array, Tuple, Queue, Union)):
            cast_ops = [
                CastExpr(op, cast_t) if op.dtype != cast_t else op
                for op, cast_t in zip(operand.operands, cast_to)
            ]
            operand = ConcatExpr(cast_ops)

        inst = super().__new__(cls)
        inst.operand = operand
        inst.cast_to = cast_to
        return inst
Ejemplo n.º 13
0
    def put_nb(self, val):
        put_event = self.events['put']

        if self.dtype is not type(val):
            err = None
            try:
                if not typeof(self.dtype, Any):
                    val = self.dtype(val)
            except (TypeError, ValueError) as e:
                err = e

            if err:
                # TODO: when value cannot be represented, the error report can be terse
                raise TypeMatchError(
                    f'{str(err)}\n, when converting output data "{repr(val)}"'
                    f' from the "{reg["gear/current_module"].name}"'
                    f' module to the type {repr(self.dtype)}')

        if put_event:
            put_event(self, val)

        for q, c in zip(self.out_queues, self.end_consumers):
            if c.consumer._done:
                raise GearDone

            put_event = c.consumer.events['put']
            if put_event:
                put_event(c.consumer, val)

            q.put_nowait(val)
Ejemplo n.º 14
0
async def zip_cat(*din) -> b'zip_type(din)':
    id_max_lvl, max_lvl = max(enumerate(din),
                              key=lambda p: p[1].dtype.lvl
                              if typeof(p[1].dtype, Queue) else 0)

    async with gather(*din) as dout:
        yield (din_data_cat_value(dout), dout[id_max_lvl].eot)
Ejemplo n.º 15
0
    def list_initials(self):
        for name, obj in self.ctx.scope.items():
            if not isinstance(obj, ir.Variable):
                continue

            if typeof(obj.dtype, ir.IntfType):
                # if isinstance(obj.val.producer, HDLProducer):
                if (self.selected(self.ctx.ref(name, ctx='store'))
                        and obj.dtype.direction == ir.IntfType.iout):
                    yield self.attr(name, 'valid'), '0'
                # elif len(obj.val.consumers) == 1 and isinstance(obj.val.consumers[0], HDLConsumer):
                elif self.selected(self.ctx.ref(name, ctx='ready')):
                    if not is_port_intf(name, self.ctx):
                        yield self.attr(name, 'ready'), f"{self.attr(name, 'valid')} ? 0 : 1'bx"

            elif obj.reg:
                target = self.ctx.ref(name)
                if self.selected(target):
                    if name == '_state':
                        yield '_state_en', '0'

                    yield (f'{self.svexpr(self.ctx.ref(name, ctx="store"), self.aux_funcs)}',
                           f'{self.svexpr(self.ctx.ref(name), self.aux_funcs)}')
            else:
                pass
Ejemplo n.º 16
0
def qrange_out_type(cfg):
    if typeof(cfg, Tuple):
        base = Int if any(c.signed for c in cfg) else Uint

        return cast(max(cfg[0], cfg[1]), base)

    return cfg
Ejemplo n.º 17
0
def fixp_resolver(opexp, cast_to):
    cast_to = cast(opexp.dtype, cast_to)

    val_dtype = opexp.dtype

    if typeof(val_dtype, Integer):
        other_cls = Fixp if val_dtype.signed else Ufixp
        val_dtype = other_cls[val_dtype.width, val_dtype.width]

    if cast_to is Fixpnumber:
        return ir.CastExpr(opexp, val_dtype)

    val_fract = val_dtype.fract
    fract = cast_to.fract

    if val_dtype.signed:
        opexp = ir.CastExpr(opexp, Int[val_dtype.width])
    else:
        opexp = ir.CastExpr(opexp, Uint[val_dtype.width])

    if fract > val_fract:
        shift = ir.BinOpExpr(
            [opexp, ir.ResExpr(Uint(fract - val_fract))], ir.opc.LShift)
    else:
        shift = ir.BinOpExpr(
            [opexp, ir.ResExpr(Uint(val_fract - fract))], ir.opc.RShift)

    return ir.CastExpr(shift, cast_to)
Ejemplo n.º 18
0
    def get_class(self):
        queue_struct_cons = []
        queue_size_cons = []
        data_cons = []

        for c in self.cons:
            if 'queue.length' in c:
                queue_size_cons.append(c.replace('queue.length', 'length'))
            elif 'queue.struct' in c:
                queue_struct_cons.append(c.replace('queue.struct', 'struct'))
            else:
                data_cons.append(c.replace(f'dout.data', 'data'))

        self.cons = data_cons
        context = {
            'con': self,
            'sv_dtype': self.cvars['dout'],
            'queue_struct_cons': queue_struct_cons,
            'queue_size_cons': queue_size_cons
        }

        if typeof(self.dtype.data, Integral):
            dt = self.dtype.data
            context[
                'sv_data_dtype'] = f'logic {"signed" if dt.signed else ""} [{dt.width-1}:0]'
        else:
            context['sv_data_dtype'] = f'dout_data_t'

        del self.cvars['dout']

        return self.tenv.cons.queue_tcon(**context)
Ejemplo n.º 19
0
async def zip_sync(*din, outsync=True) -> b'din':
    lvls = tuple(d.dtype.lvl if typeof(d.dtype, Queue) else 0 for d in din)
    overlap_lvl = min(lvls)

    eot_aligned = (1, 1)

    while (1):
        din_data = [(await d.pull()) for d in din]

        if overlap_lvl > 0:
            eot_overlap = [d.eot[:overlap_lvl] for d in din_data]

            eot_aligned = (eot_overlap[0] >= eot_overlap[1],
                           eot_overlap[1] >= eot_overlap[0])
        else:
            eot_aligned = (1, 1)
            eot_overlap = din_data[0].eot if lvls[0] else din_data[1].eot

        if all(eot_aligned):
            yield din_data
        else:
            await delta()

        for d, aligned in zip(din, eot_aligned):
            if (not aligned) or all(eot_aligned):
                d.ack()
Ejemplo n.º 20
0
def is_trace_included(port, include, vcd_tlm):
    if not match(f'{port.gear.name}.{port.basename}', include):
        return False

    if (port.dtype is None) or (typeof(port.dtype, TLM) and not vcd_tlm):
        return False

    return True
Ejemplo n.º 21
0
async def cart_sync(*din, outsync=True) -> b'din':
    async with din[0] as d0:
        if typeof(din[1].dtype, Queue):
            async for d1 in quiter_async(din[1]):
                yield d0, d1
        else:
            async with din[1] as d1:
                yield d0, d1
Ejemplo n.º 22
0
def call_signed(val):
    if val.dtype.signed:
        return val

    if typeof(val.dtype, Uint):
        return resolve_cast_func(val, Int)

    raise Exception("Unsupported signed cast")
Ejemplo n.º 23
0
def call_isinstance(arg, dtype):
    if isinstance(dtype, ir.ResExpr):
        dtype = dtype.val

    if isinstance(arg, ir.ResExpr):
        return isinstance(arg.val, dtype)

    return ir.ResExpr(typeof(arg.dtype, dtype))
Ejemplo n.º 24
0
def call_typeof(arg, dtype):
    if isinstance(dtype, ir.ResExpr):
        dtype = dtype.val

    if not isinstance(arg, ir.ResExpr):
        return ir.res_false

    return ir.ResExpr(typeof(arg.val, dtype))
Ejemplo n.º 25
0
def rand_seq(name, cnt=None):
    randomizer = reg['sim/config/randomizer']
    dtype = randomizer.get_dtype_by_name(name)

    if typeof(dtype, Queue):
        yield from get_rand(name, cnt, perpetum(queue_rand_seq, dtype, name))
    else:
        yield from get_rand(name, cnt)
Ejemplo n.º 26
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)
Ejemplo n.º 27
0
def uint_resolver(opexp, cast_to):
    cast_to = cast(opexp.dtype, cast_to)

    if typeof(opexp.dtype, Ufixp):
        if opexp.dtype.fract >= 0:
            opexp = ir.BinOpExpr((opexp, ir.ResExpr(opexp.dtype.fract)), ir.opc.RShift)
        else:
            opexp = ir.BinOpExpr((opexp, ir.ResExpr(-opexp.dtype.fract)), ir.opc.LShift)

    return ir.CastExpr(opexp, cast_to)
Ejemplo n.º 28
0
async def replicate_while(cond: Bool, data: Any) -> Queue['data']:
    async with data as d:
        last = False
        while not last:
            async with cond as en:
                last = not en
                if typeof(data.dtype, Queue):
                    yield (d[0], d[1] @ last)
                else:
                    yield (d, last)
Ejemplo n.º 29
0
async def cart_sync(*din, outsync=True) -> b'din':
    din_t = [d.dtype for d in din]

    queue_id, single_id = (0, 1) if typeof(din_t[0], Queue) else (1, 0)

    async with din[single_id] as single_data:
        async for queue_data in quiter_async(din[queue_id]):
            dout = [0, 0]
            dout[single_id] = single_data
            dout[queue_id] = queue_data
            yield tuple(dout)
Ejemplo n.º 30
0
def expand_tuple(din: Tuple) -> b'expand_type(din)':
    ctrl_lens = []
    ctrl_list = []
    for i, t in enumerate(din.dtype):
        if (typeof(t, Union)):
            ctrl_list.append(din[i][1])
            ctrl_lens.append(t[1].width)

    if not ctrl_list:
        return din

    ctrl = ccat(*ctrl_list)
    ctrl = ctrl >> Uint
    ctrl_width = sum(ctrl_lens)

    mux_din = []
    data_indices = []
    comb_no = 2**ctrl_width
    for i in range(comb_no):
        ctrl_bits = format(i, f'0={ctrl_width}b')
        k = 0
        for clen in ctrl_lens:
            data_indices.append(int(ctrl_bits[k:k + clen], 2))
            k += clen

        data = []
        for j, t in enumerate(din.dtype):
            if (typeof(t, Union)):
                if (data_indices[0] < len(t.types)):
                    if (t.types[data_indices[0]].width != 0):
                        data.append(din[j][0] >> Uint[t.types[data_indices.pop(
                            0)].width])
                    else:
                        data_indices.pop(0)
                else:
                    data_indices.pop(0)
            else:
                data.append(din[j])
        mux_din.append(ccat(*data))

    return ((ctrl, ccat(*mux_din)) | mux) >> expand_type(din.dtype)