Пример #1
0
    def translate_addr_signal(self, mem_map, sig_in, sig_out):
        cases = []
        AW = sig_in._dtype.bit_length()

        for (offset_in, size, offset_out) in mem_map:
            in_is_aligned = offset_in % size == 0 and isPow2(size)
            out_is_aligned = offset_out % size == 0 and isPow2(size)
            if in_is_aligned:
                L = (size - 1).bit_length()
                en_sig = sig_in[:L]._eq(offset_in >> L)
                _sig_in = sig_in[L:]
                if out_is_aligned:
                    addr_drive = Concat(
                        Bits(AW - L).from_py(offset_out), _sig_in)
                else:
                    addr_drive = Concat(Bits(AW - L).from_py(0),
                                        _sig_in) + offset_out
            else:
                en_sig = inRange(sig_in, offset_in, offset_in + size)
                if offset_in == offset_out:
                    addr_drive = sig_in
                elif offset_in < offset_out:
                    addr_drive = sig_in + (offset_out - offset_in)
                else:
                    # offset_in > offset_out:
                    addr_drive = sig_in - (offset_in - offset_out)
            cases.append((en_sig, sig_out(addr_drive)))
        SwitchLogic(cases, default=sig_out(sig_in))
Пример #2
0
    def _declr(self):
        addClkRstn(self)
        assert self.ALIGNAS % 8 == 0 and self.ALIGNAS > 0 and self.ALIGNAS <= self.DATA_WIDTH
        assert isPow2(self.ALIGNAS), self.ALIGNAS
        if self.MAX_CHUNKS != 1:
            assert self.CHUNK_WIDTH % 8 == 0, self.CHUNK_WIDTH
            assert isPow2(self.CHUNK_WIDTH)
        assert self.MAX_CHUNKS > 0, self.MAX_CHUNKS

        with self._paramsShared():
            # address channel to axi
            self.axi = self._axiCls()._m()
Пример #3
0
    def __init__(self, src_addr_step: int = 8, dst_addr_step: int = 8):
        self.src_addr_step = src_addr_step
        self.dst_addr_step = dst_addr_step
        assert isPow2(src_addr_step), src_addr_step
        assert isPow2(dst_addr_step), dst_addr_step

        if src_addr_step == dst_addr_step:
            align_bits = 0
        elif src_addr_step < dst_addr_step:
            align_bits = log2ceil((dst_addr_step // src_addr_step) - 1)
        else:
            align_bits = log2ceil((src_addr_step // dst_addr_step) - 1)
        self.align_bits = align_bits
Пример #4
0
    def _declr(self):
        assert isPow2(self.DEPTH - 1), (
            "DEPTH has to be 2**n + 1"
            " because fifo has have DEPTH 2**n"
            " and 1 item is stored on output reg", self.DEPTH)
        self.dataIn_clk = Clk()
        self.dataOut_clk = Clk()
        with self._paramsShared():
            with self._associated(clk=self.dataIn_clk):
                self.dataIn_rst_n = Rst_n()
                with self._associated(rst=self.dataIn_rst_n):
                    self.dataIn = self.intfCls()

            with self._associated(clk=self.dataOut_clk):
                self.dataOut_rst_n = Rst_n()
                with self._associated(rst=self.dataOut_rst_n):
                    self.dataOut = self.intfCls()._m()

        f = self.fifo = FifoAsync()
        f.IN_FREQ = self.IN_FREQ
        f.OUT_FREQ = self.OUT_FREQ
        DW = self.dataIn._bit_length() - 2  # 2 for control (valid, ready)
        f.DATA_WIDTH = DW
        # because the output register is used as another item storage
        f.DEPTH = self.DEPTH - 1
        f.EXPORT_SIZE = self.EXPORT_SIZE
        f.EXPORT_SPACE = self.EXPORT_SPACE

        SIZE_W = log2ceil(self.DEPTH + 1 + 1)
        if self.EXPORT_SIZE:
            self.size = VectSignal(SIZE_W, signed=False)
        if self.EXPORT_SPACE:
            self.space = VectSignal(SIZE_W, signed=False)
Пример #5
0
    def _declr(self):
        assert int(
            self.DEPTH
        ) > 0, "FifoAsync is disabled in this case, do not use it entirely"
        assert isPow2(
            self.DEPTH), f"DEPTH has to be power of 2, is {self.DEPTH:d}"
        # pow 2 because of gray conter counters

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

        self.dataIn_clk = Clk()
        self.dataIn_clk.FREQ = self.IN_FREQ
        self.dataOut_clk = Clk()
        self.dataOut_clk.FREQ = self.OUT_FREQ

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

            with self._associated(clk=self.dataOut_clk):
                self.dataOut_rst_n = Rst_n()
                with self._associated(rst=self.dataOut_rst_n):
                    self.dataOut = FifoReader()._m()
        self.AW = log2ceil(self.DEPTH)
Пример #6
0
    def _setup_clk_rst_n(self):
        self.clk.FREQ = self.M_FREQ
        self.rst_n._make_association(clk=self.clk)

        self.s._make_association(clk=self.clk, rst=self.rst_n)

        self.m_clk = Clk()
        self.m_clk.FREQ = self.S_FREQ

        self.m_rst_n = Rst_n()
        self.m_rst_n._make_association(clk=self.m_clk)

        self.m._make_association(clk=self.m_clk, rst=self.m_rst_n)
        assert self.ADDR_BUFF_DEPTH == 1 or isPow2(self.ADDR_BUFF_DEPTH - 1), (
            self.ADDR_BUFF_DEPTH, "size 2**n + 1 for output reg")
        assert self.DATA_BUFF_DEPTH == 1 or isPow2(self.DATA_BUFF_DEPTH - 1), (
            self.DATA_BUFF_DEPTH, "size 2**n + 1 for output reg")
Пример #7
0
 def _declr(self):
     assert isPow2(self.WINDOW_SIZE), self.WINDOW_SIZE
     assert self.M_ADDR_WIDTH > self.ADDR_WIDTH, (self.M_ADDR_WIDTH,
                                                  self.ADDR_WIDTH)
     assert (2**self.M_ADDR_WIDTH) >= self.WINDOW_SIZE, (
         "has to be large enough in order to address whole window",
         self.M_ADDR_WIDTH, self.WINDOW_SIZE)
     addClkRstn(self)
     with self._paramsShared(exclude=({"ADDR_WIDTH"}, {})):
         self.m = Mi32()._m()
         self.m.ADDR_WIDTH = self.M_ADDR_WIDTH
         self.s = Mi32()
         self.s.ADDR_WIDTH = self.ADDR_WIDTH
Пример #8
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(
                f"{timer.name:s}timerTick{timer.maxVal:d}")

            timer.cntrRegister = parentUnit._reg(
                f"{timer.name:s}timerCntr{timer.maxVal:d}",
                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
Пример #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 = (self.MAX_LEN + 1) * 2

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

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

        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 resolveSharing(timers):
     # filter out timers with maxVal == 1 because they are only clock
     timers = sorted((t for t in timers if 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
Пример #11
0
 def _declr(self):
     assert isPow2(self.DATA_WIDTH), self.DATA_WIDTH
     self.data_in = VectSignal(self.DATA_WIDTH)
     self.data_out = VectSignal(log2ceil(self.DATA_WIDTH + 1))._m()
Пример #12
0
    def _create_frame_build_logic(self):
        self.byteOrderCare = get_byte_order_modifier(self.dataOut)

        STRB_ALL = mask(int(self.DATA_WIDTH // 8))
        words = list(self.chainFrameWords())
        dout = self.dataOut
        maxWordIndex = words[-1][0]
        multipleWords = maxWordIndex > 0
        if multipleWords:
            # multiple word frame
            wordCntr_inversed = self._reg("wordCntr_inversed",
                                          Bits(log2ceil(maxWordIndex + 1),
                                               False),
                                          def_val=maxWordIndex)
            wcntrSw = Switch(wordCntr_inversed)

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

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

            sk_stash = StrbKeepStash()
            for tPart in transParts:
                strb, keep = self.connectPartsOfWord(wordData, tPart, inPorts,
                                                     lastInPorts)
                sk_stash.push(strb, keep)
            sk_stash.pop(inversedIndx, extra_strbs, extra_keeps, STRB_ALL)

            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)

        if multipleWords:
            if self.USE_STRB:
                strb = dout.strb
                Switch(wordCntr_inversed).add_cases([
                    (i, strb(v)) for i, v in extra_strbs
                ]).Default(strb(STRB_ALL))
            if self.USE_KEEP:
                keep = dout.keep
                Switch(wordCntr_inversed).add_cases([
                    (i, keep(v)) for i, v in extra_keeps
                ]).Default(keep(STRB_ALL))
        else:
            if extra_strbs:
                m = extra_strbs[0][1]
            else:
                m = STRB_ALL
            if self.USE_STRB:
                dout.strb(m)

            if extra_keeps:
                m = extra_keeps[0][1]
            else:
                m = STRB_ALL

            if self.USE_KEEP:
                dout.keep(m)
Пример #13
0
 def __init__(self, lru_reg: RtlSignal):
     assert isPow2(lru_reg._dtype.bit_length() -
                   1) or lru_reg._dtype.bit_length(
                   ) == 1, lru_reg._dtype.bit_length()
     self.lru_regs = lru_reg