Beispiel #1
0
async def decouple_din(din, *, depth, init) -> None:
    try:
        async with din as d:
            await module().queue.put(d)
            while (module().queue.full()):
                await delta()
    except GearDone:
        if module().queue.empty():
            await module().queue.put(None)

        raise GearDone
Beispiel #2
0
def dtype_rnd_seq(t, outdir=None, cons=None):
    if cons is not None:
        if not outdir:
            outdir = os.path.join(artifacts_dir(), module().basename)

        scvlib = scv_compile(outdir, module().basename, cons)
        scvlib.randomize_seed()
    else:
        scvlib = None

    yield SCVTypeSeqVisitor(scvlib).visit(t)
Beispiel #3
0
async def decouple_dout(*, t, depth) -> b't':
    queue = module().decouple_din.queue
    while queue.empty():
        if reg['sim/map'][module().decouple_din].done:
            raise GearDone

        await clk()

    yield queue.get_nowait()

    queue.task_done()
    await clk()
Beispiel #4
0
async def demux(
    din: Union,
    *,
    use_dflt=True,
    mapping=b'dflt_map(din)',
    _full_mapping=b'full_mapping(din, mapping, use_dflt)',
) -> b'demux_type(din, _full_mapping)':
    async with din as (data, ctrl):
        dout = [None] * len(module().tout)

        ctrl = _full_mapping[int(ctrl)]

        dout[ctrl] = module().tout[int(ctrl)].decode(int(data))

        yield tuple(dout)
Beispiel #5
0
def drvrnd(*, t, cnt=None, cons=None, params=None):
    return drv(t=t,
               seq=randomize(t,
                             module().basename,
                             cnt=cnt,
                             cons=cons,
                             params=params))
Beispiel #6
0
async def sample(din, *, latency=1, hold=1, init=None) -> b"din":
    data = din.dtype() if init is None else din.dtype(init)
    valid = init is not None
    dout = module().dout

    while True:
        if latency == 0:
            try:
                data = din.get_nb()
                valid = True
            except IntfEmpty:
                pass

        if valid and dout.ready_nb():
            dout.put_nb(data)

            if not hold:
                valid = False

        if latency == 1:
            try:
                data = din.get_nb()
                valid = True
            except IntfEmpty:
                pass

        await clk()
Beispiel #7
0
async def pipe(din, *, length) -> b'din':
    data = [None] * length
    dout = module().dout

    while True:
        if dout.ready_nb() and data[-1] is not None:
            dout.put_nb(data[-1])

        await delta()

        if dout.ready_nb():
            data[-1] = None

        if all(d is None for d in data) and din.done:
            raise GearDone

        for i in range(length - 1, 0, -1):
            if data[i] is None:
                data[i] = data[i - 1]
                data[i - 1] = None

        if not din.empty() and data[0] is None:
            data[0] = din.get_nb()

        await clk()
Beispiel #8
0
async def quenvelope(din: Queue['din_t', 'din_lvl'], *,
                     lvl) -> Queue[Unit, 'lvl']:
    """Extracts the queue structure of desired level called the envelope

    If there are more eot levels then forwarded to the output, those eot excess
levels are called subenvelope (which is not passed to the output). When
there is a subenvelope, the number of data the output transactions (envelope)
will contain is lowered by contracting each input transactions within
subenvelope to the length of 1. This is done in order that the envelope can be
correctly used within cartesian concatenations.

    """

    dout = module().dout
    sub_lvl = din.dtype.lvl - lvl
    out_data = None

    async for data in quiter_async(din):
        if out_data is None:
            out_data = (Unit(), data.eot[-lvl:])
            dout.put_nb(out_data)

        if sub_lvl > 0:
            subelem = data.sub(sub_lvl)
            if subelem.last:
                out_data = None
        else:
            out_data = None

        await dout.ready()
Beispiel #9
0
async def fifo(din, *, depth=2, threshold=0, regout=False) -> b'din':
    '''For this implementation depth must be a power of 2'''

    data = []
    out_data = False
    dout = module().dout

    while (1):
        if len(data) <= threshold and din.done:
            raise GearDone

        # TODO: Make fifo work correctly in corner case when it is full, but
        # consumer is ready
        if len(data) < depth:
            if not din.empty():
                data.insert(0, din.get_nb())

        if len(data) > threshold and not out_data and dout.ready_nb():
            dout.put_nb(data[-1])
            out_data = True

        await delta()

        if out_data and dout.ready_nb():
            data.pop()
            out_data = False

        await clk()
Beispiel #10
0
async def tdp_port1(req, *, depth) -> b'req["data"].data':
    ram = module().port0.ram

    async with req as (addr, (data, ctrl)):
        if ctrl:
            ram[addr] = data
        else:
            yield ram[addr]
Beispiel #11
0
def qround(din,
           *,
           fract=0,
           cut_bits=b'get_cut_bits(din, fract)',
           signed=b'din.signed') -> b'get_out_type(din, fract)':

    res = code(din, Int if signed else Uint) + (Bool(1) << (cut_bits - 1))
    return code(res >> cut_bits, module().tout)
Beispiel #12
0
 async def local_rst(din):
     sig = module().signals['flush']
     sig.write(0)
     async with din as d:
         if d:
             sig.write(1)
         else:
             sig.write(0)
Beispiel #13
0
async def sdp_rd_port(addr, *, t, depth) -> b't':
    ram = module().sdp_wr_port.ram

    while True:
        a = await addr.get()
        dout = ram[int(a)]
        await clk()
        yield dout
Beispiel #14
0
async def qrange_start_stop_inclusive(
    cfg: Tuple[{
        'start': Integer,
        'stop': Integer
    }],
    *,
    inclusive,
) -> Queue['qrange_out_type(cfg)']:
    cnt: module().tout.data = None
    last: Bool

    async with cfg as c:
        last = False
        cnt = module().tout.data(c[0])
        while not last:
            last = cnt == c[1]
            yield cnt, last
            cnt += 1
Beispiel #15
0
async def qrange_start_stop(
    cfg: Tuple[{
        'start': Integer,
        'stop': Integer
    }],
    *,
    inclusive=False,
) -> Queue['qrange_out_type(cfg)']:

    cnt: module().tout.data = None
    cur_cnt: cfg.dtype[0]
    last: Bool

    async with cfg as c:
        cnt = module().tout.data(c[0])
        last = False
        while not last:
            cur_cnt = cnt
            cnt += 1

            last = cnt == c[1]
            yield cur_cnt, cnt == c[1]
Beispiel #16
0
async def state_dout(*rd, t) -> b't':
    dout = [None] * len(rd)
    for i, rd_req in enumerate(rd):
        if not rd_req.empty():
            dout[i] = t(module().state_din.val)

    if len(rd) > 1:
        yield tuple(dout)
    else:
        yield dout[0]

    for i, rd_req in enumerate(rd):
        if dout[i] is not None:
            rd_req.get_nb()
Beispiel #17
0
async def decouple_dout(*, t, depth) -> b't':

    din = module().decouple_din
    if din.queue.empty() and (din not in reg['sim/map']
                              or reg['sim/map'][din].done):
        raise GearDone

    queue = din.queue
    data = await queue.get()

    yield data

    queue.task_done()
    await clk()
Beispiel #18
0
async def decouple_dout(*, t, depth, latency) -> b't':

    din = module().decouple_din
    sim_map = reg['sim/map']
    sim_din = sim_map[din]

    while True:
        if din.queue.empty() and (din not in sim_map or sim_din.done):
            raise GearDone

        queue = din.queue
        data = await queue.get()

        yield data

        queue.task_done()
        await clk()
Beispiel #19
0
async def sieve(din, *, key) -> b'din[key]':
    """Outputs a slice of the ``din`` input interface. Can be instantiated with
    the slicing statement: ``din[key]``.

    Args:
        key: A single key or a sequence of keys with which to slice the input
          interface.

    Returns:
        A sliced interface

    Which keys are exactly supported depends on the type of the ``din`` input
    interface, so checkout the __getitem__ method of the specific type. If for
    an example we have an interface of the type :class:`Uint[8] <Uint>` ::

        din = Intf(Uint[8])

    we could slice it using Python index operator to obtain a high nibble:

    >>> din[4:]
    Intf(Uint[4])

    which outputs an interface of the type :class:`Uint[4] <Uint>`. The same
    would be achieved if the ``sieve`` gear were instantiated explicitly:

    >>> sieve(din, key=slice(4, None, None))
    Intf(Uint[4])
    """

    async with din as d:
        dout = []
        for i in key:
            dout.append(d[i])

        if len(key) == 1:
            dout = dout[0]

        yield module().tout(dout)
Beispiel #20
0
async def decouple_din(din, *, depth, init) -> None:
    async with din as d:
        await module().queue.put(d)
        while (module().queue.full()):
            await delta()
Beispiel #21
0
def expand_tuple_single_end_union(din: Tuple) -> b'expand_type(din)':
    return din >> module().tout
Beispiel #22
0
async def scope(*xs,
                clk_freq=None,
                title=None,
                scale=None,
                method=None,
                live=None,
                dump=None,
                transaction=False):

    if clk_freq is None:
        clk_freq = reg['sim/clk_freq']

    if method is None:
        method = ['plot'] * len(xs)

    if len(method) != len(xs):
        raise Exception(
            f'Number of plotting methods ({method}) needs to match the number of inputs ({len(xs)})'
        )

    if title is None:
        title = module().name

    parallel_steps = max(
        len(x.dtype) if typeof(x.dtype, Array) else 1 for x in xs)

    backends = []

    kwds = {
        'method': method,
        'clk_freq': clk_freq * parallel_steps,
        'title': title,
        'scale': scale,
        'transaction': transaction
    }

    if live or (live is None and dump is None):
        backends.append(plot_live(**kwds))

    if dump:
        backends.append(plot_dump(dump, **kwds))

    for b in backends:
        b.send(None)

    try:
        while True:
            for ch, x in enumerate(xs):
                if x.done:
                    raise GearDone

                if x.empty():
                    continue

                async with x as x_data:
                    if isinstance(x_data, Queue):
                        x_data, eot = x_data
                    else:
                        eot = 0

                    if not isinstance(x_data, Array):
                        x_data = [x_data]

                    for i, v in enumerate(x_data):
                        point = (ch, (timestep() + i / len(x_data)) / clk_freq,
                                 float(v), int(eot))

                        for b in backends:
                            b.send(point)

            await clk()

    except GearDone:
        for b in backends:
            b.close()
        raise GearDone
Beispiel #23
0
def shr(din: Integral, *, shamt) -> b'din >> shamt':
    return module().tout(din >> shamt)
Beispiel #24
0
def shl(din: Integral, *, shamt) -> b'din << shamt':
    return module().tout(din << shamt)
Beispiel #25
0
async def state_din(din, *, init) -> None:
    async with din as data:
        pass

    await delta()
    module().val = data
Beispiel #26
0
async def sdp_wr_port(din, *, depth) -> None:
    async with din as (addr, data):
        module().ram[int(addr)] = data
Beispiel #27
0
async def sdp_rd_port(addr, *, t, depth) -> b't':
    ram = module().sdp_wr_port.ram

    async with addr as a:
        yield ram[int(a)]