class MultilaneStreamInterface(PureInterface): def __init__(self, signature, *, path, src_loc_at = 0): super().__init__(signature, path = path, src_loc_at = src_loc_at + 1) if signature.backpressure == False: self.ready = C(1) async def recv_packet(self, sim): assert 'last' in self.signature.members await self.ready.set(1) values = [] done = False while not done: await sim.tick().until(self.valid) for i in range(self.signature.lanes): v = await self.data[i].get() values.append(v) if await self.last[i].get(): done = True break await sim.tick() await self.ready.set(0) return values async def send_packet(self, sim, values): transactions = list(itertools.batched(values, self.signature.lanes)) first = 0 last = len(transactions) - 1 await self.valid.set(1) for transaction_num, data in enumerate(transactions): for i, value in enumerate(data): await self.data[i].set(value) if 'first' in self.signature.members: await self.first[i].set(transaction_num == first and i == 0) if 'last' in self.signature.members: await self.last[i].set(transaction_num == last and i == len(data) - 1) await sim.tick().until(self.ready) await sim.tick() await self.valid.set(0) class StreamSignature(Signature): def __init__(self, data_shape, *, backpressure = True, first = False, last = False, lanes = None): members = { 'data': Out(data_shape), 'valid': Out(1), 'ready': In(1), } if first: members['first'] = Out(1) if last: members['last'] = Out(1) if lanes is not None: for name in ['data', 'first', 'last']: if name in members: members[name] = members[name].array(lanes) super().__init__(members) self.backpressure = backpressure self.lanes = lanes def create(self, *, path = (), src_loc_at = 0): if self.lanes is None: return StreamInterface(self, path = path, src_loc_at = src_loc_at + 1) else: return MultilaneStreamInterface(self, path = path, src_loc_at = src_loc_at + 1)