Beispiel #1
0
def get_int_type(val):
    if val == 0:
        return Uint[1]
    elif val > 0:
        return Uint[bitw(val)]
    else:
        return Int[bitw(val)]
Beispiel #2
0
def funclut(x: Fixpnumber, *, f, precision=b'x.width', dtype=None):
    '''Implement arbitrary 1 input parameter function as Lookup-table for
    integers. f is arbitrary function e.g. math.sqrt, precision is a number of
    bits the function result will be represented with,

    sqrt_lut: x | funclut(f=math.sqrt, precision=4)

    '''

    din_t = x.dtype

    step = 2**(-din_t.fract)
    w_din = len(din_t)

    def gen_vals_signed():
        for i in range(2**w_din):
            if i < (1 << (w_din - 1)):
                yield f(step * i)
            else:
                yield f(step * (i - (1 << w_din)))

    def gen_vals_unsigned():
        for i in range(2**w_din):
            yield f(step * i)

    def gen_vals():
        if din_t.signed:
            yield from gen_vals_signed()
        else:
            yield from gen_vals_unsigned()

    if dtype is None:
        float_res_list = list(gen_vals())
        vmin = min(map(round, float_res_list))
        vmax = max(map(round, float_res_list))

        if vmin < 0:
            dtype = Fixp[bitw(
                max(2 * abs(vmin), 2 * (vmax) +
                    (1 if vmax > 0 else 0))), precision]
        else:
            dtype = Ufixp[bitw(max(vmax, vmin)), precision]

        lut_list = [dtype(v) for v in float_res_list]
    else:
        lut_list = [dtype(v) for v in gen_vals()]

    dout = x >> Uint[w_din] | rom(data=lut_list, dtype=dtype)
    return dout
def test_buck_converter():
    spice_library = SpiceLibrary(os.path.abspath(os.path.dirname(__file__)))
    spice_library['1N4148']

    Vin = 20 @ u_V
    Vout = 15 @ u_V
    Vpulse = 5 @ u_V
    ratio = Vout / Vin

    clk_freq = 1 @ u_MHz
    clk_period = clk_freq.period

    sw_freq = 50 @ u_kHz
    sw_period = sw_freq.period

    sw_period_cnt = int(sw_period / clk_period)
    sw_width_cnt = int(sw_period_cnt * (1 - ratio))
    w_period = bitw(sw_period_cnt)

    def buck_converter(c, ins, outs):
        c.include(spice_library['1N4148'])
        ins.append(('gate', c.gnd))
        outs.append(('output', c.gnd))

        Rload = 3 @ u_Ohm
        L = 750 @ u_uH
        Cout = 0.47 @ u_uF

        c.V('input', 'vin', c.gnd, Vin)

        c.VCS(name='sw1',
              input_plus='gate',
              input_minus=c.gnd,
              output_minus='vin',
              output_plus='sw_out',
              model='SW',
              initial_state='off')
        c.model('SW', 'SW', Ron=1 @ u_mOhm, Roff=100 @ u_MOhm, Vt=1.1 @ u_V)

        c.X('D1', '1N4148', c.gnd, 'sw_out')
        c.L(1, 'sw_out', 'output', L)
        c.R(1, 'output', c.gnd, Rload)
        c.C(1, 'output', c.gnd, Cout)

    seq = [(sw_period_cnt, sw_width_cnt)] * 1000

    din = drv(t=Tuple[Uint[w_period], Uint[w_period]], seq=seq) \
        | pulse \
        | flatten \
        | Float

    din = din * int(Vpulse)

    dout = din | ngspice(f=buck_converter, init_x=0)

    dout | scope
    dout | shred

    verilate('/pulse')
    sim(timeout=4000, check_activity=False)
Beispiel #4
0
def test_mapped_directed(sim_cls, din_delay, cfg_delay, dout_delay, branches):

    t_ctrl = Uint[bitw(branches - 1)]

    ref = [(i, i) for i in range(branches)]

    mapping = {}
    for i in range(branches):
        mapping[i] = (i + 1) if (i + 1) < branches else 0

    ctrl = list(range(branches))

    seqs = [[(i - 1) if (i - 1) >= 0 else (branches - 1)]
            for i in range(branches)]

    drvs = [
        drv(t=Uint[s[0] + 1], seq=s) | delay_rng(din_delay, din_delay)
        for s in seqs
    ]

    directed(drv(t=t_ctrl, seq=ctrl) | delay_rng(cfg_delay, cfg_delay),
             *drvs,
             f=mux(mapping=mapping, sim_cls=sim_cls),
             delays=[delay_rng(dout_delay, dout_delay)],
             ref=ref)

    sim()
Beispiel #5
0
async def qdeal_impl_same_lvl(din: Queue,
                              *,
                              num,
                              lvl=b'din.lvl-1') -> b'Union[(din, ) * num]':
    for i in range(num):
        async for (data, eot) in din:
            d = data if lvl == 0 else (data, eot)

            yield (d, trunc(i, Uint[bitw(num - 1)]))
Beispiel #6
0
    async def test(din: Array[Maybe, 'num']) -> b'Array[Uint[bitw(num-1)], num]':
        num = len(din.dtype)
        TIndex = Uint[bitw(num - 1)]
        data = Array[TIndex, num]()
        async with din as d:
            cnt = TIndex(0)
            for i in range(num):
                data[i] = cnt
                if d[i].ctrl:
                    cnt += 1

            yield data
Beispiel #7
0
def ii_gen(din: Queue[Uint['w_din'], 2], *, frame_size=(25, 25)):
    fifo_depth = 2**bitw(frame_size[1])

    accum_s = din | dreg_sp | accum_wrap(add_num=frame_size[0] * frame_size[1])

    fifo_out = Intf(accum_s.dtype[0])

    add_s = ccat(accum_s[0], fifo_out) | add

    fifo_in = ccat(add_s, accum_s[1]) | Queue[add_s.dtype, 2]

    fifo_out |= fifo_in | decouple | flatten | fifo2(
        depth=fifo_depth, preload=frame_size[1], regout=False)

    ii_s = fifo_in

    return ii_s | dreg_sp
Beispiel #8
0
async def qdeal_same_lvl(din: Queue,
                         *,
                         num,
                         lvl=b'din.lvl-1') -> b'(din, ) * num':

    i = Uint[bitw(num)](0)

    while i != num:
        async for (data, eot) in din:
            dout = data if lvl == 0 else (data, eot)

            yield demux(i,
                        dout,
                        use_dflt=False,
                        mapping={n: n
                                 for n in range(num)})

        i += 1
Beispiel #9
0
def schedule(block, ctx):
    ctx.scope['_rst_cond'] = ir.Variable('_rst_cond', Bool)
    block.stmts.insert(
        0, ir.AssignValue(ctx.ref('_rst_cond', 'store'), res_false))

    block.stmts.append(
        ir.AssignValue(ctx.ref('_rst_cond', 'store'), res_true))

    Scheduler(ctx).visit(block)
    # print('*** Schedule ***')
    # print(PPrinter(ctx).visit(block))
    state_num = len(block.state)

    if state_num > 1:
        ctx.scope['_state'] = ir.Variable(
            '_state',
            val=ir.ResExpr(Uint[bitw(state_num - 1)](0)),
            reg=True,
        )

    stateblock = ir.IfElseBlock(stmts=[])
    for i in range(state_num):
        v = StateIsolator(ctx, i)
        res = v.visit(block)
        if isinstance(res, list):
            res = ir.HDLBlock(stmts=res)

        res.exit_cond = res_false

        stateblock.stmts.append(res)

        if state_num > 1:
            res.in_cond = ir.BinOpExpr((ctx.ref('_state'), ir.ResExpr(i)),
                                       ir.opc.Eq)

    if state_num > 1:
        modblock = ir.CombBlock(stmts=[stateblock])
    else:
        modblock = ir.CombBlock(stmts=stateblock.stmts[0].stmts)

    modblock = infer_cycle_done(modblock, ctx)

    return modblock
Beispiel #10
0
async def qdeal_impl(
        din: Queue,
        *,
        num,
        lvl=b'din.lvl-1') -> b'Union[(Queue[din.data, din.lvl-1], ) * num]':

    i = Uint[bitw(num - 1)](0)

    async for (data, eot) in din:
        out_eot = eot[:lvl]

        d = data if lvl == 0 else (data, out_eot)

        yield (d, i)

        if all(out_eot):
            if i == (num - 1):
                i = 0
            else:
                i += 1
Beispiel #11
0
    async def test(din, *, chunk_len, num_workers) -> b'din':
        counter = Uint[bitw(chunk_len * chunk_len)](0)
        chunk_pow = chunk_len * chunk_len
        async for arr, last_arr in din:
            if counter >= chunk_pow:
                counter = 0
            if not last_arr:
                yield arr, last_arr
                counter += 1
            if last_arr:
                if counter == chunk_pow - 1:
                    yield arr, last_arr
                else:
                    yield arr, Uint[1](0)
                    counter += 1
                    while counter < chunk_pow - 1 and last_arr:
                        yield [[0] * chunk_len] * num_workers, Uint[1](0)
                        counter += 1

                    yield [[0] * chunk_len] * num_workers, Uint[1](1)
Beispiel #12
0
async def qdeal(din: Queue,
                *,
                num,
                lvl=b'din.lvl-1') -> b'(Queue[din.data, din.lvl-1], ) * num':

    i = Uint[bitw(num)](0)

    async for (data, eot) in din:
        out_eot = eot[:lvl]

        dout = data if lvl == 0 else (data, out_eot)

        yield demux(i,
                    dout,
                    use_dflt=False,
                    mapping={n: n
                             for n in range(num)})

        if all(out_eot):
            if i == (num - 1):
                i = 0
            else:
                i += 1
Beispiel #13
0
async def serialize_plain(din) -> Queue['din[0]']:
    i = Uint[bitw(len(din.dtype) - 1)](0)

    async with din as val:
        for i, last in qrange(len(din.dtype)):
            yield val[i], last
Beispiel #14
0
def schedule(cfg, ctx):
    ctx.scope['_state'] = ir.Variable(
        '_state',
        val=ir.ResExpr(Uint[1](0)),
        reg=True,
    )

    loops = []
    LoopBreaker(ctx, loops).visit(cfg)

    v = ReachingNodes()
    v.visit(cfg)
    reaching_nodes = v.reaching

    state_cfg = {0: cfg}

    isolated_loops = {}
    for l in loops:
        isolated_loops[l.value.state_id] = isolate(ctx, l)

    state_in_scope = [{} for _ in range(1 + len(loops))]
    piggied = set()
    i = 0
    order = list(state_cfg.keys())
    while i < len(order):
        state_id = order[i]
        cfg = state_cfg[state_id]
        # print(f'[{state_id}]: Scoping')
        new_states = {}
        # print_cfg_ir(cfg)

        if loops:
            non_local, piggied_cur = discover_piggieback_states(cfg, ctx, state_in_scope[state_id],
                                                                state_id, reaching_nodes,
                                                                state_cfg)

        VarScope(ctx, state_in_scope, state_id, new_states).visit(cfg)
        cfg.value.states.append(state_id)

        if loops:
            for nl in non_local:
                state_cfg[nl] = isolated_loops[nl]
                order.insert(i + 1, nl)

            cfg.value.states.extend(piggied_cur)

            piggied.update(piggied_cur)

        state_num = len(state_in_scope) - len(new_states)
        if new_states:
            # print(f'[{state_id}]: Isolating')
            state_cfg[state_id] = isolate(ctx, cfg, exits=new_states, state_num=state_num)

            # draw_scheduled_cfg(state_cfg[state_id], simple=False)
            # print_cfg_ir(state_cfg[state_id])
            for si, ns in enumerate(new_states):
                new_state_id = state_num + si

                # order.insert(i + 1, len(state_cfg))
                # print(f'[{len(state_cfg)}]: Isolating')
                # state_cfg.append(isolate(ctx, ns))

                order.insert(i + 1, new_state_id)
                # print(f'[{len(state_cfg)}]: Isolating')
                state_cfg[new_state_id] = isolate(ctx, ns)
                # draw_scheduled_cfg(state_cfg[new_state_id], simple=False)

        i += 1
        if i == len(order):
            missing = (piggied | state_cfg.keys()) ^ set(range(len(state_in_scope)))
            for s in missing:
                # TODO: Can this really be done after all stmts have been inlined?
                state_cfg[s] = isolated_loops[s]
                order.append(s)

    for i, s in state_cfg.items():
        in_scope = state_in_scope[i]

        # draw_scheduled_cfg(s, simple=True)
        # draw_scheduled_cfg(s, simple=False)
        append_state_epilog(s, ctx)
        prepend_state_prolog(s, ctx, in_scope)
        ResolveBlocking(ctx).visit(s)
        # print_cfg_ir(s)
        RebuildStateIR().visit(s)

        # print(f'------------- State {i} --------------')
        # print_cfg_ir(s)

    states = {i: s.value for i, s in state_cfg.items()}

    for i, s in states.items():
        test = ir.res_false
        for j in s.states:
            state_test = ir.BinOpExpr((ctx.ref('_state'), ir.ResExpr(j)), ir.opc.Eq)
            test = ir.BinOpExpr([test, state_test], ir.opc.Or)

    # state_num = len(states)
    state_num = len(state_in_scope)
    ctx.scope['_state'].val = ir.ResExpr(Uint[bitw(state_num - 1)](0))
    ctx.scope['_state'].dtype = Uint[bitw(state_num - 1)]

    stateblock = ir.HDLBlock()
    for i, s in states.items():
        test = ir.res_false
        for j in s.states:
            state_test = ir.BinOpExpr((ctx.ref('_state'), ir.ResExpr(j)), ir.opc.Eq)
            test = ir.BinOpExpr([test, state_test], ir.opc.Or)

        stateblock.add_branch(ir.Branch(stmts=s.stmts, test=test))

    modblock = ir.Module(stmts=[stateblock])

    return modblock