Пример #1
0
    def _declr(self):
        assert int(self.DEPTH) > 0, "FifoAsync is disabled in this case, do not use it entirely"

        assert isPow2(self.DEPTH), "FifoAsync DEPTH has to be power of 2" 
        # pow 2 because of gray conter counters

        if int(self.EXPORT_SIZE) or int(self.EXPORT_SPACE):
            raise NotImplementedError()

        self.dataIn_clk = Clk()
        self.dataOut_clk = Clk()
        self.rst_n = Rst_n()

        with self._paramsShared():
            with self._associated(clk=self.dataIn_clk):
                self.dataIn = FifoWriter()

            with self._associated(clk=self.dataOut_clk):
                self.dataOut = FifoReader()._m()

        self.pWr = GrayCntr()
        self.pRd = GrayCntr()
        self.addrW = log2ceil(self.DEPTH)

        for cntr in [self.pWr, self.pRd]:
            cntr.DATA_WIDTH.set(self.addrW)
Пример #2
0
    def _declr(self):
        addClkRstn(self)
        # addr of start of array
        self.base = VectSignal(self.ADDR_WIDTH)

        # input index of item to get
        self.index = Handshaked()
        self.index.DATA_WIDTH.set(log2ceil(self.ITEMS))

        # output item from array
        self.item = Handshaked()._m()
        self.item.DATA_WIDTH.set(self.ITEM_WIDTH)

        self.ITEMS_IN_DATA_WORD = int(self.DATA_WIDTH) // int(self.ITEM_WIDTH)

        with self._paramsShared():
            # interface for communication with datapump
            self.rDatapump = AxiRDatapumpIntf()._m()
            self.rDatapump.MAX_LEN.set(1)

        if self.ITEMS_IN_DATA_WORD > 1:
            assert isPow2(self.ITEMS_IN_DATA_WORD)
            f = self.itemSubIndexFifo = HandshakedFifo(Handshaked)
            f.DATA_WIDTH.set(log2ceil(self.ITEMS_IN_DATA_WORD))
            f.DEPTH.set(self.MAX_TRANS_OVERLAP)
Пример #3
0
    def _declr(self):
        addClkRstn(self)
        # addr of start of array
        self.base = VectSignal(self.ADDR_WIDTH)

        # input index of item to get
        self.index = Handshaked()
        self.index.DATA_WIDTH.set(log2ceil(self.ITEMS))

        # output item from array
        self.item = Handshaked()._m()
        self.item.DATA_WIDTH.set(self.ITEM_WIDTH)

        self.ITEMS_IN_DATA_WORD = int(self.DATA_WIDTH) // int(self.ITEM_WIDTH)

        with self._paramsShared():
            # interface for communication with datapump
            self.rDatapump = AxiRDatapumpIntf()._m()
            self.rDatapump.MAX_LEN.set(1)

        if self.ITEMS_IN_DATA_WORD > 1:
            assert isPow2(self.ITEMS_IN_DATA_WORD)
            f = self.itemSubIndexFifo = HandshakedFifo(Handshaked)
            f.DATA_WIDTH.set(log2ceil(self.ITEMS_IN_DATA_WORD))
            f.DEPTH.set(self.MAX_TRANS_OVERLAP)
Пример #4
0
    def _declr(self):
        assert int(
            self.DEPTH
        ) > 0, "FifoAsync is disabled in this case, do not use it entirely"

        assert isPow2(self.DEPTH), "FifoAsync DEPTH has to be power of 2"
        # pow 2 because of gray conter counters

        if int(self.EXPORT_SIZE) or int(self.EXPORT_SPACE):
            raise NotImplementedError()

        self.dataIn_clk = Clk()
        self.dataOut_clk = Clk()
        self.rst_n = Rst_n()

        with self._paramsShared():
            with self._associated(clk=self.dataIn_clk):
                self.dataIn = FifoWriter()

            with self._associated(clk=self.dataOut_clk):
                self.dataOut = FifoReader()._m()

        self.pWr = GrayCntr()
        self.pRd = GrayCntr()
        self.addrW = log2ceil(self.DEPTH)

        for cntr in [self.pWr, self.pRd]:
            cntr.DATA_WIDTH.set(self.addrW)
Пример #5
0
    def _instantiateTimerWithParent(parentUnit, timer, parent, enableSig, rstSig):
        p = parent
        if not hasattr(p, "tick"):
            TimerInfo._instantiateTimer(parentUnit, p, enableSig, rstSig)
        assert hasattr(p, "tick")

        if p.maxVal == timer.maxVal:
            timer.cntrRegister = p.cntrRegister
            timer.tick = p.tick

        elif p.maxVal < timer.maxVal:
            maxVal = (timer.maxVal // p.maxVal) - 1
            assert maxVal >= 0
            timer.tick = parentUnit._sig(
                timer.name + "timerTick%d" % timer.maxVal)

            timer.cntrRegister = parentUnit._reg(
                timer.name + "timerCntr%d" % timer.maxVal,
                Bits(log2ceil(maxVal + 1)),
                maxVal
            )

            en = p.tick
            if enableSig is not None:
                en = en & enableSig

            tick = TimerInfo._instantiateTimerTickLogic(
                parentUnit,
                timer,
                (timer.maxValOriginal // p.maxValOriginal) - 1,
                en,
                rstSig)

            timer.tick(tick & p.tick)

        else:
            # take specific bit from wider counter
            assert isPow2(timer.maxVal), timer.maxVal
            bitIndx = log2ceil(timer.maxVal)

            timer.cntrRegister = p.cntrRegister

            timer.tick = p.cntrRegister[bitIndx:]._eq(0)
            if enableSig is not None:
                timer.tick = timer.tick & enableSig
Пример #6
0
    def __init__(self, masters: List[Tuple[int, Set]],
                 slaves: List[Tuple[Union[int, AUTO_ADDR], int, Set]]):
        """
        :param masters: list of tuples (offset, features) for each master
        :param slaves: list of tuples (offset, size, features) for each slave
        :note: features can be found on definition of this class
        """
        self._masters = masters

        _slaves = []
        maxAddr = 0
        for offset, size, features in slaves:
            if not isPow2(size):
                raise AssertionError(
                    "Size which is not power of 2 is suboptimal for interconnects"
                )
            if offset == AUTO_ADDR:
                offset = maxAddr
                isAligned = (offset % size) == 0
                if not isAligned:
                    offset = ((offset // size) + 1) * size
            else:
                isAligned = (offset % size) == 0
                if not isAligned:
                    raise AssertionError(
                        "Offset which is not aligned to size is suboptimal")

            maxAddr = max(maxAddr, offset + size)
            _slaves.append((offset, size, features))

        self._slaves = sorted(_slaves, key=lambda x: x[0])

        # check for address space colisions
        lastAddr = -1
        for offset, size, features in self._slaves:
            if lastAddr >= offset:
                raise ValueError(
                    "Address space on address 0x%X colliding with previous" %
                    offset)
            lastAddr = offset + size - 1

        super(BusInterconnect, self).__init__()
Пример #7
0
    def _instantiateTimerWithParent(parentUnit, timer, parent, enableSig,
                                    rstSig):
        p = parent
        if not hasattr(p, "tick"):
            TimerInfo._instantiateTimer(parentUnit, p, enableSig, rstSig)
        assert hasattr(p, "tick")

        if p.maxVal == timer.maxVal:
            timer.cntrRegister = p.cntrRegister
            timer.tick = p.tick

        elif p.maxVal < timer.maxVal:
            maxVal = (timer.maxVal // p.maxVal) - 1
            assert maxVal >= 0
            timer.tick = parentUnit._sig(timer.name +
                                         "timerTick%d" % timer.maxVal)

            timer.cntrRegister = parentUnit._reg(
                timer.name + "timerCntr%d" % timer.maxVal,
                Bits(log2ceil(maxVal + 1)), maxVal)

            en = p.tick
            if enableSig is not None:
                en = en & enableSig

            tick = TimerInfo._instantiateTimerTickLogic(
                parentUnit, timer,
                (timer.maxValOriginal // p.maxValOriginal) - 1, en, rstSig)

            timer.tick(tick & p.tick)

        else:
            # take specific bit from wider counter
            assert isPow2(timer.maxVal), timer.maxVal
            bitIndx = log2ceil(timer.maxVal)

            timer.cntrRegister = p.cntrRegister

            timer.tick = p.cntrRegister[bitIndx:]._eq(0)
            if enableSig is not None:
                timer.tick = timer.tick & enableSig
Пример #8
0
    def __init__(self,
                 masters: List[Tuple[int, Set]],
                 slaves: List[Tuple[Union[int, AUTO_ADDR], int, Set]]):
        """
        :param masters: list of tuples (offset, features) for each master
        :param slaves: list of tuples (offset, size, features) for each slave
        :note: features can be found on definition of this class
        """
        self._masters = masters

        _slaves = []
        maxAddr = 0
        for offset, size, features in slaves:
            if not isPow2(size):
                raise AssertionError(
                    "Size which is not power of 2 is suboptimal for interconnects")
            if offset == AUTO_ADDR:
                offset = maxAddr
                isAligned = (offset % size) == 0
                if not isAligned:
                    offset = ((offset // size) + 1) * size
            else:
                isAligned = (offset % size) == 0
                if not isAligned:
                    raise AssertionError("Offset which is not aligned to size is suboptimal")

            maxAddr = max(maxAddr, offset + size)
            _slaves.append((offset, size, features))

        self._slaves = sorted(_slaves, key=lambda x: x[0])

        # check for address space colisions
        lastAddr = -1
        for offset, size, features in self._slaves:
            if lastAddr >= offset:
                raise ValueError(
                    "Address space on address 0x%X colliding with previous" % offset)
            lastAddr = offset + size - 1

        super(BusInterconnect, self).__init__()
Пример #9
0
    def _declr(self):
        addClkRstn(self)
        with self._paramsShared():
            self.dataIn = AxiStream()
            self.dataOut = AxiStream()._m()
            db = self.dataBuff = AxiSFifo()
            # to place fifo in bram
            db.DEPTH.set((self.MAX_LEN + 1) * 2)

        self.sizes = Handshaked()._m()
        self.sizes.DATA_WIDTH.set(
            log2ceil(self.MAX_LEN) + 1 + self.getAlignBitsCnt())

        sb = self.sizesBuff = HandshakedFifo(Handshaked)
        sb.DEPTH.set(self.SIZES_BUFF_DEPTH)
        sb.DATA_WIDTH.set(self.sizes.DATA_WIDTH.get())

        if self.EXPORT_ALIGNMENT_ERROR:
            assert self.USE_STRB, "Error can not happend when there is no validity mask for alignment"
            self.errorAlignment = Signal()._m()

        assert isPow2(self.DATA_WIDTH)
Пример #10
0
    def _declr(self):
        addClkRstn(self)
        with self._paramsShared():
            self.dataIn = AxiStream()
            self.dataOut = AxiStream()._m()
            db = self.dataBuff = AxiSFifo()
            # to place fifo in bram
            db.DEPTH.set((self.MAX_LEN + 1) * 2)

        self.sizes = Handshaked()._m()
        self.sizes.DATA_WIDTH.set(log2ceil(self.MAX_LEN)
                                  + 1
                                  + self.getAlignBitsCnt())

        sb = self.sizesBuff = HandshakedFifo(Handshaked)
        sb.DEPTH.set(self.SIZES_BUFF_DEPTH)
        sb.DATA_WIDTH.set(self.sizes.DATA_WIDTH.get())

        if self.EXPORT_ALIGNMENT_ERROR:
            assert self.USE_STRB, "Error can not happend when there is no validity mask for alignment"
            self.errorAlignment = Signal()._m()
           
        assert isPow2(self.DATA_WIDTH)
Пример #11
0
 def resolveSharing(timers):
     # filter out timers with maxVal == 1 because they are only clock
     timers = sorted(where(timers, lambda t: t.maxVal != 1),
                     key=lambda t: t.maxVal,
                     reverse=True)
     for i, t in enumerate(timers):
         if isPow2(t.maxVal):
             # this timer will be driven from bit of some larger
             # counter if there is suitable
             for possibleParent in timers[:i]:
                 if possibleParent.maxVal % t.maxVal == 0:
                     if possibleParent.parent is not None:
                         continue
                     t.parent = possibleParent
                     break
         else:
             # this timer will have its own timer which will be enabled by
             # some other timer if there is suitable
             for possibleParent in timers[(i + 1):]:
                 if t.maxVal % possibleParent.maxVal == 0:
                     if possibleParent.parent is t:
                         continue
                     t.parent = possibleParent
                     break
Пример #12
0
 def resolveSharing(timers):
     # filter out timers with maxVal == 1 because they are only clock
     timers = sorted(where(timers,
                           lambda t: t.maxVal != 1),
                     key=lambda t: t.maxVal, reverse=True)
     for i, t in enumerate(timers):
         if isPow2(t.maxVal):
             # this timer will be driven from bit of some larger
             # counter if there is suitable
             for possibleParent in timers[:i]:
                 if possibleParent.maxVal % t.maxVal == 0:
                     if possibleParent.parent is not None:
                         continue
                     t.parent = possibleParent
                     break
         else:
             # this timer will have its own timer which will be enabled by
             # some other timer if there is suitable
             for possibleParent in timers[(i + 1):]:
                 if t.maxVal % possibleParent.maxVal == 0:
                     if possibleParent.parent is t:
                         continue
                     t.parent = possibleParent
                     break
Пример #13
0
    def _impl(self):
        """
        Iterate over words in template and create stream output mux and fsm.
        Frame specifier can contains unions/streams/padding/unaligned items and other
        features which makes code below complex.
        Frame specifier can also describe multiple frames.
        """
        if self.IS_BIGENDIAN:
            byteOrderCare = reverseByteOrder
        else:
            def byteOrderCare(sig):
                return sig
        self.byteOrderCare = byteOrderCare

        words = list(self.chainFrameWords())
        dout = self.dataOut
        self.parseTemplate()
        maxWordIndex = words[-1][0]
        multipleWords = maxWordIndex > 0
        if multipleWords:
            # multiple word frame
            wordCntr_inversed = self._reg("wordCntr_inversed",
                                          Bits(log2ceil(maxWordIndex + 1), False),
                                          defVal=maxWordIndex)
            wcntrSw = Switch(wordCntr_inversed)

        # inversed indexes of ends of frames
        endsOfFrames = []
        extra_strbs = []
        for i, transParts, isLast in words:
            inversedIndx = maxWordIndex - i

            # input ports for value of this output word
            inPorts = []
            # input ports witch value should be consumed on this word
            lastInPorts = []
            if multipleWords:
                wordData = self._sig("word%d" % i, dout.data._dtype)
            else:
                wordData = self.dataOut.data

            for tPart in transParts:
                extra_strb = self.connectPartsOfWord(
                    wordData, tPart,
                    inPorts,
                    lastInPorts)
                if extra_strb is not None:
                    if len(transParts) > 1:
                        raise NotImplementedError(
                            "Construct rest of the strb signal")
                    extra_strbs.append((inversedIndx, extra_strb))

            if multipleWords:
                en = wordCntr_inversed._eq(inversedIndx)
            else:
                en = True
            en = self.dataOut.ready & en

            ack = self.handshakeLogicForWord(inPorts, lastInPorts, en)

            inStreamLast = True
            for p in inPorts:
                if isinstance(p, AxiStream):
                    inStreamLast = p.last & inStreamLast

            if multipleWords:
                # word cntr next logic
                if i == maxWordIndex:
                    nextWordIndex = maxWordIndex
                else:
                    nextWordIndex = wordCntr_inversed - 1

                _ack = dout.ready & ack & inStreamLast

                a = [If(_ack,
                        wordCntr_inversed(nextWordIndex)
                        ),
                     ]
            else:
                a = []

            a.append(dout.valid(ack))

            # frame with multiple words (using wordCntr_inversed)
            if multipleWords:
                # data out logic
                a.append(dout.data(wordData))
                wcntrSw.Case(inversedIndx, a)

            # is last word in frame
            if isLast:
                endsOfFrames.append((inversedIndx, inStreamLast))

        # to prevent latches
        if not multipleWords:
            pass
        elif not isPow2(maxWordIndex + 1):
            default = wordCntr_inversed(maxWordIndex)
            default.append(dout.valid(0))
            default.append(dout.data(None))

            wcntrSw.Default(default)

        if multipleWords:
            last = False
            last_last = last
            for indexOrTuple in endsOfFrames:
                i, en = indexOrTuple
                last_last = wordCntr_inversed._eq(i) & en
                last = (last_last) | last

            selectRegLoad = last_last & dout.ready & ack
        else:
            last = endsOfFrames[0][1]
            selectRegLoad = dout.ready & ack

        for r in self._tmpRegsForSelect.values():
            r.rd(selectRegLoad)
        dout.last(last)

        strb = dout.strb
        STRB_ALL = mask(int(self.DATA_WIDTH // 8))
        if multipleWords:

            Switch(wordCntr_inversed).addCases([
                (i, strb(v)) for i, v in extra_strbs
            ]).Default(
                strb(STRB_ALL)
            )
        else:
            if extra_strbs:
                strb(extra_strbs[0][1])
            else:
                strb(STRB_ALL)
Пример #14
0
    def _impl(self):
        """
        Iterate over words in template and create stream output mux and fsm.
        Frame specifier can contains unions/streams/padding/unaligned items and other
        features which makes code below complex.
        Frame specifier can also describe multiple frames.
        """
        if self.IS_BIGENDIAN:
            byteOrderCare = reverseByteOrder
        else:

            def byteOrderCare(sig):
                return sig

        self.byteOrderCare = byteOrderCare

        words = list(self.chainFrameWords())
        dout = self.dataOut
        self.parseTemplate()
        maxWordIndex = words[-1][0]
        multipleWords = maxWordIndex > 0
        if multipleWords:
            # multiple word frame
            wordCntr_inversed = self._reg("wordCntr_inversed",
                                          Bits(log2ceil(maxWordIndex + 1),
                                               False),
                                          defVal=maxWordIndex)
            wcntrSw = Switch(wordCntr_inversed)

        # inversed indexes of ends of frames
        endsOfFrames = []
        extra_strbs = []
        for i, transParts, isLast in words:
            inversedIndx = maxWordIndex - i

            # input ports for value of this output word
            inPorts = []
            # input ports witch value should be consumed on this word
            lastInPorts = []
            if multipleWords:
                wordData = self._sig("word%d" % i, dout.data._dtype)
            else:
                wordData = self.dataOut.data

            for tPart in transParts:
                extra_strb = self.connectPartsOfWord(wordData, tPart, inPorts,
                                                     lastInPorts)
                if extra_strb is not None:
                    if len(transParts) > 1:
                        raise NotImplementedError(
                            "Construct rest of the strb signal")
                    extra_strbs.append((inversedIndx, extra_strb))

            if multipleWords:
                en = wordCntr_inversed._eq(inversedIndx)
            else:
                en = True
            en = self.dataOut.ready & en

            ack = self.handshakeLogicForWord(inPorts, lastInPorts, en)

            inStreamLast = True
            for p in inPorts:
                if isinstance(p, AxiStream):
                    inStreamLast = p.last & inStreamLast

            if multipleWords:
                # word cntr next logic
                if i == maxWordIndex:
                    nextWordIndex = maxWordIndex
                else:
                    nextWordIndex = wordCntr_inversed - 1

                _ack = dout.ready & ack & inStreamLast

                a = [
                    If(_ack, wordCntr_inversed(nextWordIndex)),
                ]
            else:
                a = []

            a.append(dout.valid(ack))

            # frame with multiple words (using wordCntr_inversed)
            if multipleWords:
                # data out logic
                a.append(dout.data(wordData))
                wcntrSw.Case(inversedIndx, a)

            # is last word in frame
            if isLast:
                endsOfFrames.append((inversedIndx, inStreamLast))

        # to prevent latches
        if not multipleWords:
            pass
        elif not isPow2(maxWordIndex + 1):
            default = wordCntr_inversed(maxWordIndex)
            default.append(dout.valid(0))
            default.append(dout.data(None))

            wcntrSw.Default(default)

        if multipleWords:
            last = False
            last_last = last
            for indexOrTuple in endsOfFrames:
                i, en = indexOrTuple
                last_last = wordCntr_inversed._eq(i) & en
                last = (last_last) | last

            selectRegLoad = last_last & dout.ready & ack
        else:
            last = endsOfFrames[0][1]
            selectRegLoad = dout.ready & ack

        for r in self._tmpRegsForSelect.values():
            r.rd(selectRegLoad)
        dout.last(last)

        strb = dout.strb
        STRB_ALL = mask(int(self.DATA_WIDTH // 8))
        if multipleWords:

            Switch(wordCntr_inversed).addCases([
                (i, strb(v)) for i, v in extra_strbs
            ]).Default(strb(STRB_ALL))
        else:
            if extra_strbs:
                strb(extra_strbs[0][1])
            else:
                strb(STRB_ALL)