hwt/hdl/frameTmpl.py
def framesFromTransTmpl(transaction: 'TransTmpl',
                            wordWidth: int,
                            maxFrameLen: Union[int, float]=inf,
                            maxPaddingWords: Union[int, float]=inf,
                            trimPaddingWordsOnStart: bool=False,
                            trimPaddingWordsOnEnd: bool=False) -> Generator[
                                'FrameTmpl', None, None]:
        """
        Convert transaction template into FrameTmpls

        :param transaction: transaction template used which are FrameTmpls
            created from
        :param wordWidth: width of data signal in target interface
            where frames will be used
        :param maxFrameLen: maximum length of frame in bits,
            if exceeded another frame will be created
        :param maxPaddingWords: maximum of continual padding words in frame,
            if exceed frame is split and words are cut of
        :attention: if maxPaddingWords<inf trimPaddingWordsOnEnd
            or trimPaddingWordsOnStart has to be True
            to decide where padding should be trimmed
        :param trimPaddingWordsOnStart: trim padding from start of frame
            at word granularity
        :param trimPaddingWordsOnEnd: trim padding from end of frame
            at word granularity
        """
        isFirstInFrame = True
        partsPending = False

        startOfThisFrame = 0
        assert maxFrameLen > 0
        assert maxPaddingWords >= 0
        if maxPaddingWords < inf:
            assert trimPaddingWordsOnStart or trimPaddingWordsOnEnd, \
                "Padding has to be cut off somewhere"

        it = TransTmplWordIterator(wordWidth)
        lastWordI = 0
        endOfThisFrame = maxFrameLen
        parts = []
        for wordI, word in it.groupByWordIndex(transaction, 0):
            if wordI * wordWidth >= endOfThisFrame:
                # now in first+ word behind the frame
                # cut off padding at end of frame
                paddingWords = wordI - lastWordI
                if trimPaddingWordsOnEnd and paddingWords > maxPaddingWords:
                    # cut off padding and align end of frame to word
                    _endOfThisFrame = (lastWordI + 1) * wordWidth
                else:
                    _endOfThisFrame = wordI * wordWidth

                yield FrameTmpl(transaction,
                                wordWidth,
                                startOfThisFrame,
                                _endOfThisFrame,
                                parts)

                # prepare for start of new frame
                parts = []
                isFirstInFrame = True
                partsPending = False
                # start on new word
                startOfThisFrame = _endOfThisFrame
                endOfThisFrame = startOfThisFrame + maxFrameLen
                lastWordI = wordI

            # check if padding at potential end of frame can be cut off
            if (not isFirstInFrame
                    and trimPaddingWordsOnEnd
                    and wordI - lastWordI > 1):
                # there is too much continual padding,
                # cut it out and start new frame
                _endOfThisFrame = (lastWordI + 1) * wordWidth
                yield FrameTmpl(transaction,
                                wordWidth,
                                startOfThisFrame,
                                _endOfThisFrame,
                                parts)

                # prepare for start of new frame
                parts = []
                isFirstInFrame = True
                partsPending = False
                # start on new word
                startOfThisFrame = _endOfThisFrame
                endOfThisFrame = startOfThisFrame + maxFrameLen
                lastWordI = wordI - 1

            if isFirstInFrame:
                partsPending = True
                isFirstInFrame = False
                # cut off padding at start of frame
                paddingWords = wordI - lastWordI
                if trimPaddingWordsOnStart and paddingWords > maxPaddingWords:
                    startOfThisFrame += paddingWords * wordWidth

                endOfThisFrame = startOfThisFrame + maxFrameLen

            # resolve end of this part
            parts.extend(word)
            lastWordI = wordI

        # reminder in "parts" after last iteration
        endOfThisFrame = transaction.bitAddrEnd
        withPadding = not (trimPaddingWordsOnEnd or trimPaddingWordsOnStart)
        if partsPending or (withPadding
                            and endOfThisFrame != startOfThisFrame):
            # cut off padding at end of frame
            endOfLastWord = (lastWordI + 1) * wordWidth
            if endOfThisFrame < endOfLastWord:
                endOfThisFrame = endOfLastWord
            else:
                paddingWords = it.fullWordCnt(endOfLastWord, endOfThisFrame)
                if trimPaddingWordsOnEnd and paddingWords > maxPaddingWords:
                    endOfThisFrame -= paddingWords * wordWidth
                    # align end of frame to word
            endOfThisFrame = min(startOfThisFrame +
                                 maxFrameLen, endOfThisFrame)

            yield FrameTmpl(transaction,
                            wordWidth,
                            startOfThisFrame,
                            endOfThisFrame,
                            parts)
            parts = []
            startOfThisFrame = endOfThisFrame

        # final padding on the end
        while withPadding and startOfThisFrame < transaction.bitAddrEnd:
            endOfThisFrame = min(startOfThisFrame +
                                 maxFrameLen, transaction.bitAddrEnd)

            yield FrameTmpl(transaction,
                            wordWidth,
                            startOfThisFrame,
                            endOfThisFrame,
                            [])

            startOfThisFrame = endOfThisFrame
def framesFromTransTmpl(transaction: 'TransTmpl',
                            wordWidth: int,
                            maxFrameLen: Union[int, float]=inf,
                            maxPaddingWords: Union[int, float]=inf,
                            trimPaddingWordsOnStart: bool=False,
                            trimPaddingWordsOnEnd: bool=False) -> Generator[
                                'FrameTmpl', None, None]:
        """
        Convert transaction template into FrameTmpls

        :param transaction: transaction template used which are FrameTmpls
            created from
        :param wordWidth: width of data signal in target interface
            where frames will be used
        :param maxFrameLen: maximum length of frame in bits,
            if exceeded another frame will be created
        :param maxPaddingWords: maximum of continual padding words in frame,
            if exceed frame is split and words are cut of
        :attention: if maxPaddingWords<inf trimPaddingWordsOnEnd
            or trimPaddingWordsOnStart has to be True
            to decide where padding should be trimmed
        :param trimPaddingWordsOnStart: trim padding from start of frame
            at word granularity
        :param trimPaddingWordsOnEnd: trim padding from end of frame
            at word granularity
        """
        isFirstInFrame = True
        partsPending = False

        startOfThisFrame = 0
        assert maxFrameLen > 0
        assert maxPaddingWords >= 0
        if maxPaddingWords < inf:
            assert trimPaddingWordsOnStart or trimPaddingWordsOnEnd, \
                "Padding has to be cut off somewhere"

        it = TransTmplWordIterator(wordWidth)
        lastWordI = 0
        endOfThisFrame = maxFrameLen
        parts = []
        for wordI, word in it.groupByWordIndex(transaction, 0):
            if wordI * wordWidth >= endOfThisFrame:
                # now in first+ word behind the frame
                # cut off padding at end of frame
                paddingWords = wordI - lastWordI
                if trimPaddingWordsOnEnd and paddingWords > maxPaddingWords:
                    # cut off padding and align end of frame to word
                    _endOfThisFrame = (lastWordI + 1) * wordWidth
                else:
                    _endOfThisFrame = wordI * wordWidth

                yield FrameTmpl(transaction,
                                wordWidth,
                                startOfThisFrame,
                                _endOfThisFrame,
                                parts)

                # prepare for start of new frame
                parts = []
                isFirstInFrame = True
                partsPending = False
                # start on new word
                startOfThisFrame = _endOfThisFrame
                endOfThisFrame = startOfThisFrame + maxFrameLen
                lastWordI = wordI

            # check if padding at potential end of frame can be cut off
            if (not isFirstInFrame
                    and trimPaddingWordsOnEnd
                    and wordI - lastWordI > 1):
                # there is too much continual padding,
                # cut it out and start new frame
                _endOfThisFrame = (lastWordI + 1) * wordWidth
                yield FrameTmpl(transaction,
                                wordWidth,
                                startOfThisFrame,
                                _endOfThisFrame,
                                parts)

                # prepare for start of new frame
                parts = []
                isFirstInFrame = True
                partsPending = False
                # start on new word
                startOfThisFrame = _endOfThisFrame
                endOfThisFrame = startOfThisFrame + maxFrameLen
                lastWordI = wordI - 1

            if isFirstInFrame:
                partsPending = True
                isFirstInFrame = False
                # cut off padding at start of frame
                paddingWords = wordI - lastWordI
                if trimPaddingWordsOnStart and paddingWords > maxPaddingWords:
                    startOfThisFrame += paddingWords * wordWidth

                endOfThisFrame = startOfThisFrame + maxFrameLen

            # resolve end of this part
            parts.extend(word)
            lastWordI = wordI

        # reminder in "parts" after last iteration
        endOfThisFrame = transaction.bitAddrEnd
        withPadding = not (trimPaddingWordsOnEnd or trimPaddingWordsOnStart)
        if partsPending or (withPadding
                            and endOfThisFrame != startOfThisFrame):
            # cut off padding at end of frame
            endOfLastWord = (lastWordI + 1) * wordWidth
            if endOfThisFrame < endOfLastWord:
                endOfThisFrame = endOfLastWord
            else:
                paddingWords = it.fullWordCnt(endOfLastWord, endOfThisFrame)
                if trimPaddingWordsOnEnd and paddingWords > maxPaddingWords:
                    endOfThisFrame -= paddingWords * wordWidth
                    # align end of frame to word
            endOfThisFrame = min(startOfThisFrame +
                                 maxFrameLen, endOfThisFrame)

            yield FrameTmpl(transaction,
                            wordWidth,
                            startOfThisFrame,
                            endOfThisFrame,
                            parts)
            parts = []
            startOfThisFrame = endOfThisFrame

        # final padding on the end
        while withPadding and startOfThisFrame < transaction.bitAddrEnd:
            endOfThisFrame = min(startOfThisFrame +
                                 maxFrameLen, transaction.bitAddrEnd)

            yield FrameTmpl(transaction,
                            wordWidth,
                            startOfThisFrame,
                            endOfThisFrame,
                            [])

            startOfThisFrame = endOfThisFrame
Convert transaction template into FrameTmpls

        :param transaction: transaction template used which are FrameTmpls
            created from
        :param wordWidth: width of data signal in target interface
            where frames will be used
        :param maxFrameLen: maximum length of frame in bits,
            if exceeded another frame will be created
        :param maxPaddingWords: maximum of continual padding words in frame,
            if exceed frame is split and words are cut of
        :attention: if maxPaddingWords<inf trimPaddingWordsOnEnd
            or trimPaddingWordsOnStart has to be True
            to decide where padding should be trimmed
        :param trimPaddingWordsOnStart: trim padding from start of frame
            at word granularity
        :param trimPaddingWordsOnEnd: trim padding from end of frame
            at word granularity