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 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)