def parseTemplate(self): if self._tmpl is None: self._tmpl = TransTmpl(self._structT) if self._frames is None: DW = int(self.DATA_WIDTH) frames = FrameTmpl.framesFromTransTmpl( self._tmpl, DW, trimPaddingWordsOnStart=True, trimPaddingWordsOnEnd=True) self._frames = list(frames)
def instantiateFrameForge(self, structT, DATA_WIDTH=64, maxFrameLen=inf, maxPaddingWords=inf, trimPaddingWordsOnStart=False, trimPaddingWordsOnEnd=False, randomized=True): tmpl = TransTmpl(structT) frames = list(FrameTmpl.framesFromTransTmpl( tmpl, DATA_WIDTH, maxFrameLen=maxFrameLen, maxPaddingWords=maxPaddingWords, trimPaddingWordsOnStart=trimPaddingWordsOnStart, trimPaddingWordsOnEnd=trimPaddingWordsOnEnd)) u = self.u = AxiS_frameForge(structT, tmpl, frames) self.DATA_WIDTH = DATA_WIDTH self.m = mask(self.DATA_WIDTH // 8) u.DATA_WIDTH.set(self.DATA_WIDTH) self.prepareUnit(self.u) if randomized: self.randomize(u.dataOut) for intf in u.dataIn._fieldsToInterfaces.values(): self.randomize(intf)
def _decorateWithRegisters(self, memHandler, structT): """ Decorate this object with attributes from memory space (name is same as specified in register map) :param memHandler: instance of AbstractMemSpaceMaster(subclass of) :param structT: instance of HStruct or TransTmpl used as template """ if isinstance(structT, TransTmpl): tmpl = structT else: tmpl = TransTmpl(structT) for trans in tmpl.children: t = trans.dtype if isinstance(t, HArray): msi = MemorySpaceItemArr(memHandler, trans, offset=self._offset) elif isinstance(t, HStruct): msi = MemorySpaceItemStruct(memHandler, trans, offset=self._offset) else: msi = MemorySpaceItem(memHandler, trans, offset=self._offset) name = trans.origin.name assert not hasattr(self, name), name setattr(self, name, msi)
def test_sWithPadding(self): DW = 64 tmpl = TransTmpl(sWithPadding) frames = FrameTmpl.framesFromTransTmpl(tmpl, DW) frames = list(frames) self.assertEqual(len(frames), 1) self.assertEqual(sWithPadding_str, frames[0].__repr__())
def test_union0at16b(self): DW = 16 tmpl = TransTmpl(union0) frames = FrameTmpl.framesFromTransTmpl(tmpl, DW) frames = list(frames) self.assertEqual(len(frames), 1) self.assertEqual(repr(frames[0]), union0_16b_str)
def _test(self, DW, t, ref_str): tmpl = TransTmpl(t) frames = FrameTmpl.framesFromTransTmpl(tmpl, DW) frames = list(frames) self.assertEqual(len(frames), len(ref_str)) for f, ref in zip(frames, ref_str): self.assertEqual(repr(f), ref)
def _parseTemplate(self): self._directlyMapped = [] self._bramPortMapped = [] self.ADRESS_MAP = [] self.WORD_ADDR_STEP = self._getWordAddrStep() self.ADDR_STEP = self._getAddrStep() AW = int(self.ADDR_WIDTH) SUGGESTED_AW = self._suggestedAddrWidth() assert SUGGESTED_AW <= AW, (SUGGESTED_AW, AW) tmpl = TransTmpl(self.STRUCT_TEMPLATE) for transTmpl, intf in self.walkFieldsAndIntf(tmpl, self.decoded): intfClass = intf.__class__ if issubclass(intfClass, RegCntrl): self._directlyMapped.append(transTmpl) elif issubclass(intfClass, BramPort_withoutClk): self._bramPortMapped.append(transTmpl) else: raise NotImplementedError(intf) self.ADRESS_MAP.append(transTmpl)
def test_stream1_32(self): DW = 32 tmpl = TransTmpl(stream0) frames = list(FrameTmpl.framesFromTransTmpl(tmpl, DW)) self.assertEqual(len(frames), 1) s = frames[0].__repr__() self.assertEqual(stream1_32bit_str, s)
def test_frameHeader(self): DW = 64 tmpl = TransTmpl(frameHeader) frames = FrameTmpl.framesFromTransTmpl(tmpl, DW) frames = list(frames) self.assertEqual(len(frames), 1) self.assertEqual(frameHeader_str, frames[0].__repr__())
def parseTemplate(self): if self._tmpl is None: self._tmpl = TransTmpl(self._structT) if self._frames is None: DW = int(self.DATA_WIDTH) frames = FrameTmpl.framesFromTransTmpl(self._tmpl, DW) self._frames = list(frames)
def test_basic_tripleFrame(self): DW = 64 tmpl = TransTmpl(s_basic) frames = FrameTmpl.framesFromTransTmpl(tmpl, DW, maxFrameLen=64) frames = list(frames) self.assertEqual(len(frames), 3) for f, ref in zip(frames, s_basic_3frame_srt): self.assertEqual(repr(f), ref)
def test_frameHeader_trimmed(self): DW = 64 tmpl = TransTmpl(frameHeader) frames = FrameTmpl.framesFromTransTmpl(tmpl, DW, trimPaddingWordsOnStart=True, trimPaddingWordsOnEnd=True) frames = list(frames) self.assertEqual([f.__repr__() for f in frames], frameHeader_trimm_str)
def test_s2_oneFrame(self): DW = 64 tmpl = TransTmpl(s2) frames = FrameTmpl.framesFromTransTmpl( tmpl, DW, ) frames = list(frames) self.assertEqual(len(frames), 1) self.assertEqual(repr(frames[0]), s2_oneFrame)
def test_struct_with_union(self): DW = 64 tmpl = TransTmpl(struct_with_union) frames = FrameTmpl.framesFromTransTmpl( tmpl, DW, ) frames = list(frames) self.assertEqual(len(frames), 1) self.assertEqual(repr(frames[0]), struct_with_union_str)
def test_multiframe(self): tmpl = TransTmpl(s0) DATA_WIDTH = 64 frames = list( FrameTmpl.framesFromTransTmpl(tmpl, DATA_WIDTH, maxPaddingWords=0, trimPaddingWordsOnStart=True, trimPaddingWordsOnEnd=True)) u = StructReader(s0, tmpl=tmpl, frames=frames) self._test_s0(u)
def test_s2_oneFrame_tryToTrim(self): DW = 64 tmpl = TransTmpl(s2) frames = FrameTmpl.framesFromTransTmpl(tmpl, DW, maxPaddingWords=0, trimPaddingWordsOnStart=True, trimPaddingWordsOnEnd=True) frames = list(frames) self.assertEqual(len(frames), 1) self.assertEqual(repr(frames[0]), s2_oneFrame)
def test_sWithStartPaddingKept(self): DW = 64 tmpl = TransTmpl(sWithStartPadding) frames = FrameTmpl.framesFromTransTmpl(tmpl, DW, maxPaddingWords=2, trimPaddingWordsOnStart=True, trimPaddingWordsOnEnd=True) frames = list(frames) self.assertEqual(len(frames), 1) self.assertEqual(sWithStartPadding_strKept, frames[0].__repr__())
def test_sWithPaddingMultiFrame(self): DW = 64 tmpl = TransTmpl(sWithPadding) frames = FrameTmpl.framesFromTransTmpl(tmpl, DW, maxPaddingWords=0, trimPaddingWordsOnStart=True, trimPaddingWordsOnEnd=True) frames = list(frames) self.assertEqual(len(frames), 2) for frame, s in zip(frames, sWithPaddingMultiframe_str): self.assertEqual(s, frame.__repr__())
def test_frameHeader_splited(self): DW = 64 tmpl = TransTmpl(frameHeader) frames = FrameTmpl.framesFromTransTmpl(tmpl, DW, maxPaddingWords=0, trimPaddingWordsOnStart=True, trimPaddingWordsOnEnd=True) frames = list(frames) self.assertEqual(len(frames), 2) for frame, s, end in zip(frames, frameHeader_split_str, [2 * DW, 5 * DW]): self.assertEqual(s, frame.__repr__()) self.assertEqual(frame.endBitAddr, end)
def test_simpleOp(self): DW = 64 AW = 32 u = EthAddrUpdater() u.DATA_WIDTH.set(DW) u.ADDR_WIDTH.set(AW) self.prepareUnit(u) r = self.randomize r(u.axi_m.ar) r(u.axi_m.r) r(u.axi_m.aw) r(u.axi_m.w) r(u.axi_m.b) m = Axi3DenseMem(u.clk, u.axi_m) tmpl = TransTmpl(frameHeader) frameTmpl = list(FrameTmpl.framesFromTransTmpl(tmpl, DW))[0] def randFrame(): rand = self._rand.getrandbits data = { "eth": { "src": rand(48), "dst": rand(48) }, "ipv4": { "src": rand(32), "dst": rand(32) } } d = list(frameTmpl.packData(data)) ptr = m.calloc(ceil(frameHeader.bit_length() / DW), DW // 8, initValues=d) return ptr, data framePtr, frameData = randFrame() u.packetAddr._ag.data.append(framePtr) self.runSim(1000 * Time.ns) updatedFrame = m.getStruct(framePtr, tmpl) self.assertValEqual(updatedFrame.eth.src, frameData["eth"]['dst']) self.assertValEqual(updatedFrame.eth.dst, frameData["eth"]['src']) self.assertValEqual(updatedFrame.ipv4.src, frameData["ipv4"]['dst']) self.assertValEqual(updatedFrame.ipv4.dst, frameData["ipv4"]['src'])
def shouldEnterFn(trans_tmpl: TransTmpl): p = trans_tmpl.getFieldPath() intf = self.decoded._fieldsToInterfaces[p] if isinstance(intf, (StructIntf, UnionSink, UnionSource, HObjList)): shouldEnter = True shouldUse = False elif isinstance(intf, BramPort_withoutClk): shouldEnter = False shouldUse = True else: shouldEnter = False shouldUse = False return shouldEnter, shouldUse
def propagateAddr(self, src_addr_sig: RtlSignal, src_addr_step: int, dst_addr_sig: RtlSignal, dst_addr_step: int, transTmpl: TransTmpl): """ :param src_addr_sig: input signal with address :param src_addr_step: how many bits is addressing one unit of src_addr_sig :param dst_addr_sig: output signal for address :param dst_addr_step: how many bits is addressing one unit of dst_addr_sig :param transTmpl: TransTmpl which has meta-informations about this address space transition """ IN_W = src_addr_sig._dtype.bit_length() # _prefix = transTmpl.getMyAddrPrefix(src_addr_step) assert dst_addr_step % src_addr_step == 0 if not isinstance(transTmpl.dtype, HArray): raise TypeError(transTmpl.dtype) assert transTmpl.bitAddr % dst_addr_step == 0, ( f"Has to be addressable by address with this step ({transTmpl})") addrIsAligned = transTmpl.bitAddr % transTmpl.bit_length() == 0 bitsForAlignment = AddressStepTranslation(src_addr_step, dst_addr_step).align_bits bitsOfSubAddr = ((transTmpl.bitAddrEnd - transTmpl.bitAddr - 1) // dst_addr_step).bit_length() if addrIsAligned: bitsOfAddr = bitsOfSubAddr + bitsForAlignment bitsOfPrefix = IN_W - bitsOfAddr prefix = (transTmpl.bitAddr // src_addr_step) >> bitsOfAddr if bitsOfPrefix == 0: addrIsInRange = True else: addrIsInRange = src_addr_sig[:(IN_W - bitsOfPrefix)]._eq(prefix) addr_tmp = src_addr_sig else: _addr = transTmpl.bitAddr // src_addr_step _addrEnd = transTmpl.bitAddrEnd // src_addr_step addrIsInRange = inRange(src_addr_sig, _addr, _addrEnd) addr_tmp = self._sig(dst_addr_sig._name + "_addr_tmp", Bits(self.ADDR_WIDTH)) addr_tmp(src_addr_sig - _addr) addr_h = bitsOfSubAddr + bitsForAlignment connectedAddr = dst_addr_sig(addr_tmp[addr_h:bitsForAlignment]) return (addrIsInRange, connectedAddr)
def propagateAddr(self, srcAddrSig: RtlSignal, srcAddrStep: int, dstAddrSig: RtlSignal, dstAddrStep: int, transTmpl: TransTmpl): """ :param srcAddrSig: input signal with address :param srcAddrStep: how many bits is addressing one unit of srcAddrSig :param dstAddrSig: output signal for address :param dstAddrStep: how many bits is addressing one unit of dstAddrSig :param transTmpl: TransTmpl which has meta-informations about this address space transition """ IN_ADDR_WIDTH = srcAddrSig._dtype.bit_length() # _prefix = transTmpl.getMyAddrPrefix(srcAddrStep) assert dstAddrStep % srcAddrStep == 0 if not isinstance(transTmpl.dtype, HArray): raise TypeError(transTmpl.dtype) assert transTmpl.bitAddr % dstAddrStep == 0, ( "Has to be addressable by address with this step (%r)" % ( transTmpl)) addrIsAligned = transTmpl.bitAddr % transTmpl.bit_length() == 0 bitsForAlignment = ((dstAddrStep // srcAddrStep) - 1).bit_length() bitsOfSubAddr = ( (transTmpl.bitAddrEnd - transTmpl.bitAddr - 1) // dstAddrStep).bit_length() if addrIsAligned: bitsOfPrefix = IN_ADDR_WIDTH - bitsOfSubAddr - bitsForAlignment prefix = (transTmpl.bitAddr // srcAddrStep) >> (bitsForAlignment + bitsOfSubAddr) addrIsInRange = srcAddrSig[IN_ADDR_WIDTH:( IN_ADDR_WIDTH - bitsOfPrefix)]._eq(prefix) addr_tmp = srcAddrSig else: _addr = transTmpl.bitAddr // srcAddrStep _addrEnd = transTmpl.bitAddrEnd // srcAddrStep addrIsInRange = inRange(srcAddrSig, _addr, _addrEnd) addr_tmp = self._sig(dstAddrSig._name + "_addr_tmp", Bits(self.ADDR_WIDTH)) addr_tmp(srcAddrSig - _addr) connectedAddr = (dstAddrSig( addr_tmp[(bitsOfSubAddr + bitsForAlignment):(bitsForAlignment)])) return (addrIsInRange, connectedAddr)
def TransTmpl_get_max_addr(t: TransTmpl): if t.itemCnt is None: offset = 0 else: item_size = t.bit_length() // t.itemCnt offset = t.bitAddr + (t.itemCnt - 1) * item_size if not t.children: return t.bitAddrEnd elif isinstance(t.children, list) and t.children: for c in reversed(t.children): r = TransTmpl_get_max_addr(c) if r is not None: return offset + r return None else: return offset + TransTmpl_get_max_addr(t.children)
def getArray(self, addr: int, item_size: int, item_cnt: int): """ Get array stored in memory """ baseIndex = addr // self.cellSize if item_size != self.cellSize or baseIndex * self.cellSize != addr: return self._getArray(addr * 8, TransTmpl(Bits(item_size * 8)[item_cnt])) else: out = [] for i in range(baseIndex, baseIndex + item_cnt): try: v = self.data[i] except KeyError: v = None out.append(v) return out
def propagateAddr(self, srcAddrSig: RtlSignal, srcAddrStep: int, dstAddrSig: RtlSignal, dstAddrStep: int, transTmpl: TransTmpl): """ :param srcAddrSig: input signal with address :param srcAddrStep: how many bits is addressing one unit of srcAddrSig :param dstAddrSig: output signal for address :param dstAddrStep: how many bits is addressing one unit of dstAddrSig :param transTmpl: TransTmpl which has meta-informations about this address space transition """ IN_ADDR_WIDTH = srcAddrSig._dtype.bit_length() # _prefix = transTmpl.getMyAddrPrefix(srcAddrStep) assert dstAddrStep % srcAddrStep == 0 if not isinstance(transTmpl.dtype, HArray): raise TypeError(transTmpl.dtype) assert transTmpl.bitAddr % dstAddrStep == 0, ( "Has to be addressable by address with this step (%r)" % (transTmpl)) addrIsAligned = transTmpl.bitAddr % transTmpl.bit_length() == 0 bitsForAlignment = ((dstAddrStep // srcAddrStep) - 1).bit_length() bitsOfSubAddr = ((transTmpl.bitAddrEnd - transTmpl.bitAddr - 1) // dstAddrStep).bit_length() if addrIsAligned: bitsOfPrefix = IN_ADDR_WIDTH - bitsOfSubAddr - bitsForAlignment prefix = (transTmpl.bitAddr // srcAddrStep) >> (bitsForAlignment + bitsOfSubAddr) addrIsInRange = srcAddrSig[IN_ADDR_WIDTH:( IN_ADDR_WIDTH - bitsOfPrefix)]._eq(prefix) addr_tmp = srcAddrSig else: _addr = transTmpl.bitAddr // srcAddrStep _addrEnd = transTmpl.bitAddrEnd // srcAddrStep addrIsInRange = inRange(srcAddrSig, _addr, _addrEnd) addr_tmp = self._sig(dstAddrSig._name + "_addr_tmp", Bits(self.ADDR_WIDTH)) addr_tmp(srcAddrSig - _addr) connectedAddr = (dstAddrSig( addr_tmp[(bitsOfSubAddr + bitsForAlignment):(bitsForAlignment)])) return (addrIsInRange, connectedAddr)
def test_simpleOp(self): DW = self.DW u = self.u r = self.randomize r(u.axi_m.ar) r(u.axi_m.r) r(u.axi_m.aw) r(u.axi_m.w) r(u.axi_m.b) m = AxiSimRam(u.axi_m) tmpl = TransTmpl(frameHeader) frameTmpl = list(FrameTmpl.framesFromTransTmpl(tmpl, DW))[0] def randFrame(): rand = self._rand.getrandbits data = { "eth": { "src": rand(48), "dst": rand(48), }, "ipv4": { "src": rand(32), "dst": rand(32), } } d = list(frameTmpl.packData(data)) ptr = m.calloc( ceil(frameHeader.bit_length() / DW), DW // 8, initValues=d, keepOut=self.OFFSET, ) return ptr, data framePtr, frameData = randFrame() u.packetAddr._ag.data.append(framePtr) self.runSim(100 * CLK_PERIOD) updatedFrame = m.getStruct(framePtr, tmpl) self.assertValEqual(updatedFrame.eth.src, frameData["eth"]['dst']) self.assertValEqual(updatedFrame.eth.dst, frameData["eth"]['src']) self.assertValEqual(updatedFrame.ipv4.src, frameData["ipv4"]['dst']) self.assertValEqual(updatedFrame.ipv4.dst, frameData["ipv4"]['src'])
def getStruct(self, addr, structT, bitAddr=None): """ Get HStruct from memory :param addr: address where get struct from :param structT: instance of HStruct or FrameTmpl generated from it to resove structure of data :param bitAddr: optional bit precisse address is is not None param addr has to be None """ if bitAddr is None: assert bitAddr is None bitAddr = addr * 8 else: assert addr is not None if isinstance(structT, TransTmpl): transTmpl = structT structT = transTmpl.origin else: assert isinstance(structT, HStruct) transTmpl = TransTmpl(structT) return self._getStruct(bitAddr, transTmpl)
def instantiate(self, structT, DATA_WIDTH=64, maxFrameLen=inf, maxPaddingWords=inf, trimPaddingWordsOnStart=False, trimPaddingWordsOnEnd=False, randomized=True, use_strb=False, use_keep=True): if maxFrameLen is not inf\ or maxPaddingWords is not inf\ or trimPaddingWordsOnStart is not False\ or trimPaddingWordsOnEnd is not False: tmpl = TransTmpl(structT) frames = list( FrameTmpl.framesFromTransTmpl( tmpl, DATA_WIDTH, maxFrameLen=maxFrameLen, maxPaddingWords=maxPaddingWords, trimPaddingWordsOnStart=trimPaddingWordsOnStart, trimPaddingWordsOnEnd=trimPaddingWordsOnEnd)) else: tmpl = None frames = None u = self.u = AxiS_frameDeparser(structT, tmpl, frames) u.DATA_WIDTH = self.DATA_WIDTH = DATA_WIDTH u.USE_STRB = use_strb u.USE_KEEP = use_keep self.m = mask(self.DATA_WIDTH // 8) self.compileSimAndStart(self.u) if randomized: self.randomize(u.dataOut) for intf in u.dataIn._fieldsToInterfaces.values(): self.randomize(intf)
def test_s2Pading_spliting(self): structT = s2Pading self.DATA_WIDTH = 64 tmpl = TransTmpl(structT) frames = list(FrameTmpl.framesFromTransTmpl( tmpl, self.DATA_WIDTH, maxPaddingWords=0, trimPaddingWordsOnStart=True, trimPaddingWordsOnEnd=True)) u = self.u = AxiS_frameForge(structT, tmpl, frames) u.DATA_WIDTH.set(self.DATA_WIDTH) m = mask(self.DATA_WIDTH // 8) self.prepareUnit(self.u) def enDataOut(s): u.dataOut._ag.enable = False yield s.wait(50 * Time.ns) u.dataOut._ag.enable = True self.procs.append(enDataOut) MAGIC = 468 u.dataIn.item0_0._ag.data.append(MAGIC) u.dataIn.item0_1._ag.data.append(MAGIC + 1) u.dataIn.item1_0._ag.data.append(MAGIC + 2) u.dataIn.item1_1._ag.data.append(MAGIC + 3) t = 200 self.runSim(t * Time.ns) self.assertValSequenceEqual(u.dataOut._ag.data, [(MAGIC, m, 0), (MAGIC + 1, m, 1), (MAGIC + 2, m, 0), (MAGIC + 3, m, 1), ])
def test_sBasic(self): tmpl = TransTmpl(s_basic) self.assertEqual(s_basic_srt, tmpl.__repr__())
class StructReader(AxiS_frameParser): """ This unit downloads required structure fields over rDatapump interface from address specified by get interface :ivar MAX_DUMMY_WORDS: Param, specifies maximum dummy bus words between fields if there is more of ignored space transaction will be split to :ivar ID: Param, id for transactions on bus :ivar READ_ACK: Param, if true ready on "get" will be set only when component is in idle (if false "get" is regular handshaked interface) :ivar SHARED_READY: Param, if this is true field interfaces will be of type VldSynced and single ready signal will be used for all else every interface will be instance of Handshaked and it will have it's own ready(rd) signal :attention: interfaces of field will not send data in same time .. aafig:: get (base addr) +---------+ +---------------- +------> field0 | | | +---------+ bus req +--v---+-+ <------------+ | +---------+ | reader +----> field1 | +------------> | +---------+ bus data +-------+-+ | +---------+ +------> field2 | +---------+ :note: names in the picture are just illustrative .. hwt-schematic:: _example_StructReader """ def __init__(self, structT, tmpl=None, frames=None): """ :param structT: instance of HStruct which specifies data format to download :param tmpl: instance of TransTmpl for this structT :param frames: list of FrameTmpl instances for this tmpl :note: if tmpl and frames are None they are resolved from structT parseTemplate :note: this unit can parse sequence of frames, if they are specified by "frames" :attention: interfaces for each field in struct will be dynamically created :attention: structT can not contain fields with variable size like HStream """ Unit.__init__(self) assert isinstance(structT, HStruct) self._structT = structT if tmpl is not None: assert frames is not None, "tmpl and frames can be used only together" else: assert frames is None, "tmpl and frames can be used only together" self._tmpl = tmpl self._frames = frames def _config(self): self.ID = Param(0) AxiRDatapumpIntf._config(self) self.USE_STRB.set(False) self.READ_ACK = Param(False) self.SHARED_READY = Param(False) def maxWordIndex(self): return max(map(lambda f: f.endBitAddr - 1, self._frames)) // int(self.DATA_WIDTH) def parseTemplate(self): if self._tmpl is None: self._tmpl = TransTmpl(self._structT) if self._frames is None: DW = int(self.DATA_WIDTH) frames = FrameTmpl.framesFromTransTmpl( self._tmpl, DW, trimPaddingWordsOnStart=True, trimPaddingWordsOnEnd=True) self._frames = list(frames) def _declr(self): addClkRstn(self) self.dataOut = StructIntf(self._structT, self._mkFieldIntf)._m() g = self.get = Handshaked() # data signal is addr of structure to download g._replaceParam(g.DATA_WIDTH, self.ADDR_WIDTH) self.parseTemplate() with self._paramsShared(): # interface for communication with datapump self.rDatapump = AxiRDatapumpIntf()._m() self.rDatapump.MAX_LEN.set(self.maxWordIndex() + 1) with self._paramsShared(exclude={self.ID_WIDTH}): self.parser = AxiS_frameParser(self._structT, tmpl=self._tmpl, frames=self._frames) self.parser.SYNCHRONIZE_BY_LAST.set(False) if self.SHARED_READY: self.ready = Signal() def _impl(self): propagateClkRstn(self) req = self.rDatapump.req req.rem(0) if self.READ_ACK: get = self.get else: get = HsBuilder(self, self.get).buff().end def f(frame, indx): s = [req.addr(get.data + frame.startBitAddr // 8), req.len(frame.getWordCnt() - 1), req.vld(get.vld) ] isLastFrame = indx == len(self._frames) - 1 if isLastFrame: rd = req.rd else: rd = 0 s.append(get.rd(rd)) ack = StreamNode(masters=[get], slaves=[self.rDatapump.req]).ack() return s, ack StaticForEach(self, self._frames, f) r = self.rDatapump.r data_sig_to_exclude = [] req.id(self.ID) if hasattr(r, "id"): data_sig_to_exclude.append(r.id) if hasattr(r, "strb"): data_sig_to_exclude.append(r.strb) connect(r, self.parser.dataIn, exclude=data_sig_to_exclude) for _, field in self._tmpl.walkFlatten(): myIntf = self.dataOut._fieldsToInterfaces[field.origin] parserIntf = self.parser.dataOut._fieldsToInterfaces[field.origin] myIntf(parserIntf)