def test_cast_union_of_units(lang): verif(drv(t=Tuple[Unit, Uint[1]], seq=[(Unit(), 0), (Unit(), 1)]), f=cast(name='dut', t=Union[Unit, Unit]), ref=code_gear(t=Union[Unit, Unit])) cosim('/dut', 'verilator', lang=lang) sim()
def test_unit_const(): @gear async def test() -> Queue[Unit]: yield Unit(), Bool(False) yield Unit(), Bool(True) directed(f=test(__sim__='verilator'), ref=[[Unit(), Unit()]]) sim(timeout=2)
def test_unit(): @gear async def test(din) -> Queue[Unit]: async for d, eot in din: yield Unit(), eot directed(drv(t=Queue[Uint[4]], seq=[[1, 2]]), f=test(__sim__='verilator'), ref=[[Unit(), Unit()]]) sim(timeout=2)
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()
def visit_ResExpr(self, node): if isinstance(node.val, tuple): res = [] for op in reversed(node.val): res_op = ir.ResExpr(op) if res_op != ir.ResExpr(Unit()) and res_op.dtype != Uint[0]: svexpr = self.visit(res_op) res.append(self.cast_svexpr(svexpr, res_op.dtype, type(op))) if not res: return None return '{' + ', '.join(res) + '}' if getattr(node.val, 'unknown', False): return f"{node.dtype.width}'bx" val = node.val if isinstance(node.val, ir.EmptyType): if node.dtype is None: return f"'x" else: return f"{node.dtype.width}'bx" elif not isinstance(node.val, Integer): val = Integer(code(node.val, int)) sign = '-' if val < 0 else '' return f"{sign}{val.width}'d{abs(int(val))}"
async def rd_sequence() -> Unit: for i in range(4): yield Unit() await clk() await clk() raise GearDone
def test_dout_queue_lvl_2_no_datacosim(cosim_cls): verif(drv(t=Queue[Unit, 3], seq=[[[[Unit() for _ in range(2)] for _ in range(2)] for _ in range(2)]]), f=flatten(sim_cls=cosim_cls), ref=flatten(name='ref_model')) sim()
def concat_resolver(opexp, ctx: Context): ops = tuple(op for op in reversed(opexp) if op.dtype.width) if len(ops) == 0: return ir.ResExpr(Unit()) elif len(ops) == 1: return ops[0] else: tuple_res = ir.ConcatExpr(ops) return ir.CastExpr(tuple_res, Uint[tuple_res.dtype.width])
async def cart_cat(*din) -> b'cart_type(din)': async with gather(*din) as data: dout_data = [] dout_eot = Unit() for d in data: if isinstance(d, Queue): dout_data.append(d.data) dout_eot = d.eot @ dout_eot else: dout_data.append(d) yield (dout_data, dout_eot)
def visit_ConcatExpr(self, node): svexprs = [] for op in reversed(node.operands): if op == ir.ResExpr(Unit()): continue sv = self.visit(op) if sv is None: continue svexprs.append(str(sv)) if svexprs: return '{' + ', '.join(svexprs) + '}' return None
async def cart_cat(*din, order=None) -> b'cart_type(din, order)': if order is None: order = range(len(din)) async with gather(*din) as data: dout_data = [] dout_eot = Unit() for o in order: d = data[o] # for d in data: if isinstance(d, Queue): dout_data.append(d.data) dout_eot = dout_eot @ d.eot else: dout_data.append(d) yield (dout_data, dout_eot)
def test_skip_sim(sim_cls): seq = [[list(range(1))], [list(range(1)), list(range(2))], [list(range(1)), list(range(2)), list(range(3))]] ref = [[Unit()], [Unit(), Unit()], [Unit(), Unit(), Unit()]] directed(drv(t=Queue[Uint[2], 3], seq=[seq]), f=quenvelope(lvl=2, sim_cls=sim_cls), ref=[ref]) sim()
def __new__(cls, val: Expr, index: Expr): const_index = get_contextpr(index) const_val = get_contextpr(val) if const_index is not None: if const_val is not None: return ResExpr(const_val[const_index]) if isinstance(val, ConcatExpr): return val.operands[const_index] inst = super().__new__(cls) inst.val = val inst.index = index if inst.dtype.width == 0: return ResExpr(Unit()) return inst
async def test() -> Queue[Unit]: yield Unit(), Bool(False) yield Unit(), Bool(True)
else: raise GearTypeNotSpecified( f"Value {val} not supported for const module") @gear(hdl={'impl': 'sustain'}) async def const(*, val, tout=b'get_literal_type(val)') -> b'tout': yield tout(val) @gear async def once(*, val, tout=b'get_literal_type(val)') -> b'tout': yield tout(val) while True: raise GearDone @gear async def fix(din, *, val, tout=b'get_literal_type(val)') -> b'tout': async with din: yield tout(val) ping = fix(val=Unit()) @gear async def void(*, dtype) -> b'dtype': raise GearDone
def test_unit(sim_cls): directed(f=const(sim_cls=sim_cls, val=Unit()), ref=[Unit(), Unit(), Unit(), Unit()]) sim(timeout=4)
async def test(din) -> Queue[Unit]: async for d, eot in din: yield Unit(), eot
def maybe_when(cond, din, *, f, fcat=ccat): return fcat(din, cond) \ | Union \ | unionmap(f=(fix(val=Unit()), f)) \ | Maybe