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