Ejemplo n.º 1
0
    def _declr(self) -> None:
        self._normalize_config()
        addClkRstn(self)

        slavePorts = HObjList()
        for _ in self.MASTERS:
            s = Mi32()
            s._updateParamsFrom(self)
            slavePorts.append(s)

        self.s = slavePorts

        masterPorts = HObjList()
        for _, size in self.SLAVES:
            m = Mi32()._m()
            m.ADDR_WIDTH = log2ceil(size - 1)
            m.DATA_WIDTH = self.DATA_WIDTH
            masterPorts.append(m)

        self.m = masterPorts

        # fifo which keeps index of slave for master read transaction
        # so the interconnect can delivery the read data to master
        # which asked for it
        f = self.r_data_order = HandshakedFifo(Handshaked)
        f.DEPTH = self.MAX_TRANS_OVERLAP
        f.DATA_WIDTH = log2ceil(len(self.SLAVES))
Ejemplo n.º 2
0
    def _declr(self):
        AxiInterconnectCommon._declr(self, has_r=False, has_w=True)
        masters_for_slave = AxiInterconnectMatrixCrossbar._masters_for_slave(
            self.MASTERS, len(self.SLAVES))

        # fifo for master index for each slave so slave knows
        # which master did read and where is should send it
        order_m_index_for_s_data = HObjList()
        order_m_index_for_s_b = HObjList()
        for connected_masters in masters_for_slave:
            if len(connected_masters) > 1:
                f_w = HandshakedFifo(Handshaked)
                f_b = HandshakedFifo(Handshaked)
                for _f in [f_w, f_b]:
                    _f.DEPTH = self.MAX_TRANS_OVERLAP
                    _f.DATA_WIDTH = log2ceil(len(self.MASTERS))
            else:
                f_w, f_b = None, None
            order_m_index_for_s_data.append(f_w)
            order_m_index_for_s_b.append(f_b)
        self.order_m_index_for_s_data = order_m_index_for_s_data
        self.order_m_index_for_s_b = order_m_index_for_s_b
        # fifo for slave index for each master
        # so master knows where it should expect the data
        order_s_index_for_m_data = HObjList()
        order_s_index_for_m_b = HObjList()
        for connected_slaves in self.MASTERS:
            if len(connected_slaves) > 1:
                f_w = HandshakedFifo(Handshaked)
                f_b = HandshakedFifo(Handshaked)

                for f in [f_w, f_b]:
                    f.DEPTH = self.MAX_TRANS_OVERLAP
                    f.DATA_WIDTH = log2ceil(len(self.SLAVES))
            else:
                f_w, f_b = None, None
            order_s_index_for_m_data.append(f_w)
            order_s_index_for_m_b.append(f_b)
        self.order_s_index_for_m_data = order_s_index_for_m_data
        self.order_s_index_for_m_b = order_s_index_for_m_b

        AXI = self.intfCls
        with self._paramsShared():
            self.addr_crossbar = AxiInterconnectMatrixAddrCrossbar(AXI.AW_CLS)

        with self._paramsShared():
            c = self.data_crossbar = AxiInterconnectMatrixCrossbar(AXI.W_CLS)
            c.INPUT_CNT = len(self.MASTERS)
            W_OUTPUTS = [set() for _ in self.SLAVES]
            for m_i, accessible_slaves in enumerate(self.MASTERS):
                for s_i in accessible_slaves:
                    W_OUTPUTS[s_i].add(m_i)
            c.OUTPUTS = W_OUTPUTS

        with self._paramsShared():
            c = self.b_crossbar = AxiInterconnectMatrixCrossbarB(AXI.B_CLS)
            c.INPUT_CNT = len(self.SLAVES)
            c.OUTPUTS = self.MASTERS
Ejemplo n.º 3
0
    def _impl(self):
        propagateClkRstn(self)
        dIn = AxiSBuilder(self, self.dataIn).buff().end

        sb = self.sizesBuff
        db = self.dataBuff

        wordCntr = self._reg("wordCntr",
                             Bits(log2ceil(self.MAX_LEN) + 1),
                             def_val=0)

        overflow = wordCntr._eq(self.MAX_LEN)
        last = dIn.last | overflow
        If(
            StreamNode(masters=[dIn], slaves=[sb.dataIn, db.dataIn]).ack(),
            If(last, wordCntr(0)).Else(wordCntr(wordCntr + 1)))

        length = self._sig("length", wordCntr._dtype)
        BYTE_CNT = dIn.data._dtype.bit_length() // 8
        if dIn.USE_STRB:
            # compress strb mask as binary number
            rem = self._sig("rem", Bits(log2ceil(BYTE_CNT)))

            SwitchLogic(cases=[(dIn.strb[i],
                                rem(0 if i == BYTE_CNT - 1 else i + 1))
                               for i in reversed(range(BYTE_CNT))],
                        default=[
                            rem(0),
                        ])
            if self.EXPORT_ALIGNMENT_ERROR:
                errorAlignment = self._reg("errorAlignment_reg", def_val=0)
                self.errorAlignment(errorAlignment)
                If(dIn.valid & (dIn.strb != mask(BYTE_CNT)) & ~dIn.last,
                   errorAlignment(1))

            If(last & (dIn.strb != mask(BYTE_CNT)),
               length(wordCntr)).Else(length(wordCntr + 1))
        else:
            length(wordCntr + 1)
            rem = Bits(log2ceil(BYTE_CNT)).from_py(0)

        sb.dataIn.data(Concat(length, rem))

        db.dataIn(dIn, exclude=[dIn.valid, dIn.ready, dIn.last])
        db.dataIn.last(last)

        StreamNode(masters=[dIn],
                   slaves=[sb.dataIn, db.dataIn],
                   extraConds={
                       sb.dataIn: last
                   }).sync()

        self.sizes(sb.dataOut)
        self.dataOut(db.dataOut)
Ejemplo n.º 4
0
Archivo: r.py Proyecto: mfkiwl/hwtLib
 def _declr(self):
     if self.ID_WIDTH:
         self.id = VectSignal(self.ID_WIDTH)
     # rem is number of bits in last word which is valid - 1,
     # if rem == 0 it means all bytes are valid
     self.rem = VectSignal(log2ceil(self.DATA_WIDTH // 8))
     if self.SHIFT_OPTIONS != (0, ):
         self.shift = VectSignal(log2ceil(len(self.SHIFT_OPTIONS)))
     if self.HAS_PROPAGATE_LAST:
         self.propagateLast = Signal()
     HandshakeSync._declr(self)
Ejemplo n.º 5
0
    def _declr(self):
        if self.ID_WIDTH:
            self.id = VectSignal(self.ID_WIDTH)

        self.addr = VectSignal(self.ADDR_WIDTH)
        assert self.MAX_LEN >= 0, self.MAX_LEN
        if self.MAX_LEN > 0:
            self.len = VectSignal(log2ceil(self.MAX_LEN + 1))

        # rem is number of bytes in last word which are valid - 1
        self.rem = VectSignal(log2ceil(self.DATA_WIDTH // 8))

        HandshakeSync._declr(self)
Ejemplo n.º 6
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
Ejemplo n.º 7
0
    def get_lru(self):
        """
        To find LRU, we can perform a depth-first-search starting from root,
        and traverse nodes in lower levels. If the node is 0, then we traverse the left sub-tree;
        otherwise, we traverse the right sub-tree. In the diagram above, the LRU is set 3.
        """
        # node_index: bits  rlu register
        node_paths = {}
        self._build_node_paths(node_paths, 0, tuple())
        # also number of levels of rlu tree
        bin_index_w = log2ceil(
            self.lru_reg_items(self.lru_regs._dtype.bit_length()))

        lru_index_bin = []
        # msb first in lru binary index
        for output_bit_i in range(bin_index_w):
            items_on_current_level = int(2**output_bit_i)
            current_level_offset = 2**output_bit_i - 1
            possible_paths = []
            for node_i in range(current_level_offset,
                                current_level_offset + items_on_current_level):
                p = node_paths[node_i]
                possible_paths.append(And(*p))
            lru_index_bin.append(Or(*possible_paths))

        # MSB was first so the result is in little endian MSB..LSB
        return Concat(*lru_index_bin)
Ejemplo n.º 8
0
    def _declr(self):
        addClkRstn(self)

        with self._paramsShared():
            # read interface for datapump
            # interface which sending requests to download addr of next block
            self.rDatapump = AxiRDatapumpIntf()._m()
            # because we are downloading only addres of next block
            self.rDatapump.MAX_LEN = 1

            # write interface for datapump
            self.wDatapump = AxiWDatapumpIntf()._m()
            self.wDatapump.MAX_LEN = self.BUFFER_CAPACITY // 2
            assert self.BUFFER_CAPACITY <= self.ITEMS_IN_BLOCK

            # interface for items which should be written into list
            self.dataIn = Handshaked()

        # interface to control internal register
        a = self.baseAddr = RegCntrl()
        a.DATA_WIDTH = self.ADDR_WIDTH

        self.rdPtr = RegCntrl()
        self.wrPtr = RegCntrl()
        for ptr in [self.rdPtr, self.wrPtr]:
            ptr.DATA_WIDTH = self.PTR_WIDTH

        f = self.dataFifo = HandshakedFifo(Handshaked)
        f.EXPORT_SIZE = True
        f.DATA_WIDTH = self.DATA_WIDTH
        f.DEPTH = self.BUFFER_CAPACITY

        self.ALIGN_BITS = log2ceil(self.DATA_WIDTH // 8)
Ejemplo n.º 9
0
 def timeoutHandler(self, rst, incr):
     timeoutCntr = self._reg("timeoutCntr",
                             Bits(log2ceil(self.TIMEOUT) + 1, signed=False),
                             def_val=self.TIMEOUT)
     If(rst, timeoutCntr(self.TIMEOUT)).Elif((timeoutCntr != 0) & incr,
                                             timeoutCntr(timeoutCntr - 1))
     return timeoutCntr._eq(0)
Ejemplo n.º 10
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)
Ejemplo n.º 11
0
    def _instantiateTimer(parentUnit, timer, enableSig=None, rstSig=None):
        """
        :param enableSig: enable signal for all counters
        :param rstSig: reset signal for all counters
        """

        if timer.parent is None:
            maxVal = timer.maxVal - 1
            # use original to propagate parameter
            origMaxVal = timer.maxValOriginal - 1
            assert maxVal >= 0

            if maxVal == 0:
                if enableSig is None:
                    tick = 1
                else:
                    tick = enableSig
            else:
                timer.cntrRegister = parentUnit._reg(
                    f"{timer.name:s}timerCntr{timer.maxVal:d}",
                    Bits(log2ceil(maxVal + 1)), maxVal)
                tick = TimerInfo._instantiateTimerTickLogic(
                    parentUnit, timer, origMaxVal, enableSig, rstSig)

            timer.tick = parentUnit._sig(
                f"{timer.name:s}timerTick{timer.maxVal:d}", )
            timer.tick(tick)
        else:
            TimerInfo._instantiateTimerWithParent(parentUnit, timer,
                                                  timer.parent, enableSig,
                                                  rstSig)
Ejemplo n.º 12
0
    def _downscale(self, factor):
        inputRegs_cntr = self._reg("inputRegs_cntr",
                                   Bits(log2ceil(factor + 1), False),
                                   def_val=0)

        # instantiate HandshakedReg, handshaked builder is not used to avoid dependencies
        inReg = HandshakedReg(self.intfCls)
        inReg._updateParamsFrom(self.dataIn)
        self.inReg = inReg
        inReg.clk(self.clk)
        inReg.rst_n(self.rst_n)
        inReg.dataIn(self.dataIn)
        dataIn = inReg.dataOut
        dataOut = self.dataOut

        # create output mux
        for din, dout in zip(self.get_data(dataIn), self.get_data(dataOut)):
            widthOfPart = din._dtype.bit_length() // factor
            inParts = iterBits(din, bitsInOne=widthOfPart)
            Switch(inputRegs_cntr).add_cases(
                [(i, dout(inPart)) for i, inPart in enumerate(inParts)]
                )
        vld = self.get_valid_signal
        rd = self.get_ready_signal
        vld(dataOut)(vld(dataIn))
        self.get_ready_signal(dataIn)(inputRegs_cntr._eq(factor - 1) & rd(dataOut))

        If(vld(dataIn) & rd(dataOut),
            If(inputRegs_cntr._eq(factor - 1),
               inputRegs_cntr(0)
            ).Else(
               inputRegs_cntr(inputRegs_cntr + 1)
            )
        )
Ejemplo n.º 13
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)
Ejemplo n.º 14
0
    def _impl(self) -> None:
        if len(self.MASTERS) > 1:
            raise NotImplementedError()

        m = self.s[0]

        wrack = rdack = err = BIT.from_py(0)
        AW = int(self.ADDR_WIDTH)
        rdata = []
        for i, (s, (s_offset, s_size)) in\
                enumerate(zip(self.m, self.SLAVES)):
            s.bus2ip_addr(m.bus2ip_addr, fit=True)
            s.bus2ip_be(m.bus2ip_be)
            s.bus2ip_rnw(m.bus2ip_rnw)
            s.bus2ip_data(m.bus2ip_data)

            bitsOfSubAddr = log2ceil(s_size - 1)
            prefix = get_bit_range(s_offset, bitsOfSubAddr, AW - bitsOfSubAddr)
            cs = self._sig(f"m_cs_{i:d}")
            cs(m.bus2ip_addr[AW:bitsOfSubAddr]._eq(prefix))
            s.bus2ip_cs(m.bus2ip_cs & cs)

            err = err | (cs & s.ip2bus_error)
            rdack = rdack | (cs & s.ip2bus_rdack)
            wrack = wrack | (cs & s.ip2bus_wrack)
            rdata.append((cs, s.ip2bus_data))

        m.ip2bus_error(err)
        m.ip2bus_rdack(rdack)
        m.ip2bus_wrack(wrack)

        SwitchLogic([(sel, m.ip2bus_data(data)) for sel, data in rdata],
                    default=m.ip2bus_data(None))
Ejemplo n.º 15
0
 def _declr(self):
     if self.ID_WIDTH:
         self.id = VectSignal(self.ID_WIDTH)
     self.index = VectSignal(self.INDEX_WIDTH)
     if self.WAY_CNT > 1:
         self.way = VectSignal(log2ceil(self.WAY_CNT - 1))
     HandshakeSync._declr(self)
Ejemplo n.º 16
0
    def _declr(self):
        self._compute_constants()
        addClkRstn(self)
        # used to initialize the LRU data (in the case of cache reset)
        # while set port is active all other ports are blocked
        s = self.set = AddrDataHs()
        s.ADDR_WIDTH = self.INDEX_W
        s.DATA_WIDTH = self.LRU_WIDTH

        # used to increment the LRU data in the case of hit
        self.incr = HObjList(IndexWayHs() for _ in range(self.INCR_PORT_CNT))
        for i in self.incr:
            i.INDEX_WIDTH = self.INDEX_W
            i.WAY_CNT = self.WAY_CNT

        # get a victim for a selected cacheline index
        # The cacheline returned as a victim is also marked as used just now
        vr = self.victim_req = AddrHs()
        vr.ADDR_WIDTH = self.INDEX_W
        vr.ID_WIDTH = 0
        vd = self.victim_data = Handshaked()._m()
        vd.DATA_WIDTH = log2ceil(self.WAY_CNT - 1)

        m = self.lru_mem = RamXorSingleClock()
        m.ADDR_WIDTH = self.INDEX_W
        m.DATA_WIDTH = self.LRU_WIDTH
        m.PORT_CNT = (
            # victim_req preload, victim_req write back or set,
            READ, WRITE,
            #  incr preload, incr write back...
            *flatten((READ, WRITE) for _ in range(self.INCR_PORT_CNT))
        )
Ejemplo n.º 17
0
    def _declr(self):
        assert self.CACHE_LINE_CNT > 0, self.CACHE_LINE_CNT
        assert self.WAY_CNT > 0, self.WAY_CNT
        assert self.CACHE_LINE_CNT % self.WAY_CNT == 0, (self.CACHE_LINE_CNT,
                                                         self.WAY_CNT)
        self._compupte_tag_index_offset_widths()

        addClkRstn(self)
        with self._paramsShared():
            self.s = Axi4()
            self.m = Axi4()._m()

            rc = self.read_cancel = AddrHs()._m()
            rc.ID_WIDTH = 0

            self.tag_array = AxiCacheTagArray()
            self.lru_array = AxiCacheLruArray()
            for a in [self.tag_array, self.lru_array]:
                a.PORT_CNT = 2  # r+w

        # self.flush = HandshakeSync()
        # self.init = HandshakeSync()

        data_array = self.data_array = RamSingleClock()
        data_array.MAX_BLOCK_DATA_WIDTH = self.MAX_BLOCK_DATA_WIDTH
        data_array.DATA_WIDTH = self.DATA_WIDTH
        data_array.ADDR_WIDTH = log2ceil(
            self.CACHE_LINE_CNT *
            ceil(self.CACHE_LINE_SIZE * 8 / self.DATA_WIDTH))
        data_array.PORT_CNT = (READ, WRITE)
        data_array.HAS_BE = True
Ejemplo n.º 18
0
    def _declr(self):
        addClkRstn(self)
        self.ALIGN_BITS_IN = log2ceil((self.DATA_WIDTH // 8) - 1)
        self.ALIGN_BITS_OUT = log2ceil((self.OUT_DATA_WIDTH // 8) - 1)
        assert self.ALIGN_BITS_IN <= self.ADDR_WIDTH, (self.ALIGN_BITS_IN,
                                                       self.ADDR_WIDTH)
        assert self.ALIGN_BITS_OUT <= self.OUT_ADDR_WIDTH, (
            self.ALIGN_BITS_OUT, self.OUT_ADDR_WIDTH)

        with self._paramsShared():
            self.s = self.intfCls()

        with self._paramsShared():
            self.m = self.intfCls()._m()
            self.m.ADDR_WIDTH = self.OUT_ADDR_WIDTH
            self.m.DATA_WIDTH = self.OUT_DATA_WIDTH
Ejemplo n.º 19
0
    def _mkFieldInterface(self, structIntf: HStruct, field: HStructField):
        t = field.dtype

        if isinstance(t, Bits):
            p = RegCntrl()
            dw = t.bit_length()
        elif isinstance(t, HArray):
            field_path = structIntf._field_path / field.name
            if self.shouldEnterFn(field_path)[0]:
                if isinstance(t.element_t, Bits):
                    p = HObjList(RegCntrl() for _ in range(int(t.size)))
                    dw = t.element_t.bit_length()
                else:
                    p = HObjList([StructIntf(
                        t.element_t,
                        field_path,
                        instantiateFieldFn=self._mkFieldInterface)
                        for _ in range(int(t.size))])
                    return p
            else:
                p = BramPort_withoutClk()
                dw = t.element_t.bit_length()
                p.ADDR_WIDTH = log2ceil(int(t.size) - 1)
        else:
            raise NotImplementedError(t)

        p.DATA_WIDTH = dw

        return p
Ejemplo n.º 20
0
    def _impl(self):
        st_t = HEnum("state_t", ["IDLE", "LOAD_SR", "CONVERTING", "DONE"])
        st = self._reg("st", st_t, def_val=st_t.IDLE)
        sr_shift = st.next._eq(st_t.CONVERTING)

        bcd = self.din
        bin_ = self.dout
        bcd_sr = self._reg("bcd_sr", bcd.data._dtype, def_val=0)
        binary_sr = self._reg("binary_sr", bin_.data._dtype, def_val=0)
        next_bcd = rename_signal(self, bcd_sr >> 1, "next_bcd")

        MAX_COUNT = binary_sr._dtype.bit_length()
        bit_count = self._reg("bit_count", Bits(log2ceil(MAX_COUNT), signed=False), def_val=MAX_COUNT)
        If(sr_shift,
           bit_count(bit_count - 1),
        ).Else(
           bit_count(MAX_COUNT),
        )
        # dabble the digits
        digits = []
        for i in range(self.BCD_DIGITS):
            d = next_bcd[(i + 1) * 4:i * 4]._unsigned()
            d_sig = (d < 7)._ternary(d, d - 3)
            digits.append(d_sig)

        If(st.next._eq(st_t.LOAD_SR),
           bcd_sr(bcd.data),
           binary_sr(0),
        ).Elif(sr_shift,
           # shift right
           binary_sr(Concat(bcd_sr[0], binary_sr[:1])),
           bcd_sr(Concat(*reversed(digits))),
        )

        bin_.data(binary_sr)

        Switch(st)\
        .Case(st_t.IDLE,
            If(bcd.vld,
                st(st_t.LOAD_SR),  # load the shift registers
            ))\
        .Case(st_t.LOAD_SR,
            # shift right each cycle
            st(st_t.CONVERTING),
        )\
        .Case(st_t.CONVERTING,
            If(bit_count._eq(0),
                # indicate completion
                st(st_t.DONE),
            )
        )\
        .Case(st_t.DONE,
            If(bcd.vld & bin_.rd,
                st(st_t.LOAD_SR),
            ).Elif(bin_.rd,
                st(st_t.IDLE),
            )
        )
        bcd.rd(st._eq(st_t.IDLE) | (st._eq(st_t.DONE) & bin_.rd))
        bin_.vld(st._eq(st_t.DONE))
Ejemplo n.º 21
0
 def _declr(self):
     addClkRstn(self)
     BCD_DIGITS = self.BCD_DIGITS
     bcd = self.din = Handshaked()  # BCD data to convert
     bcd.DATA_WIDTH = 4 * BCD_DIGITS
     bin_ = self.dout = Handshaked()._m()
     bin_.DATA_WIDTH = log2ceil(10 ** BCD_DIGITS - 1)  # Converted output. Retained until next conversion
Ejemplo n.º 22
0
    def _declr(self):
        addClkRstn(self)

        with self._paramsShared():
            # interface which sending requests to download data
            # and interface which is collecting all data and only data with specified id are processed
            self.rDatapump = AxiRDatapumpIntf()._m()
            self.rDatapump.MAX_BYTES = self.BUFFER_CAPACITY // 2 * self.DATA_WIDTH // 8

            self.dataOut = Handshaked()._m()

        # (how much of items remains in block)
        self.inBlockRemain = VectSignal(log2ceil(self.ITEMS_IN_BLOCK + 1))._m()

        # interface to control internal register
        a = self.baseAddr = RegCntrl()
        a.DATA_WIDTH = self.ADDR_WIDTH
        self.rdPtr = RegCntrl()
        self.wrPtr = RegCntrl()
        for ptr in [self.rdPtr, self.wrPtr]:
            ptr.DATA_WIDTH = self.PTR_WIDTH

        f = self.dataFifo = HandshakedFifo(Handshaked)
        f.EXPORT_SIZE = True
        f.DATA_WIDTH = self.DATA_WIDTH
        f.DEPTH = self.BUFFER_CAPACITY
Ejemplo n.º 23
0
    def fifo_pointers(self, DEPTH: int,
                      write_en_wait: Tuple[RtlSignal, RtlSignal],
                      read_en_wait_list: List[Tuple[RtlSignal, RtlSignal]])\
                      -> List[Tuple[RtlSignal, RtlSignal]]:
        """
        Create fifo writer and reader pointers and enable/wait logic
        This functions supports multiple reader pointers

        :attention: writer pointer next logic check only last reader pointer
        :return: list, tule(en, ptr) for writer and each reader
        """
        index_t = Bits(log2ceil(DEPTH), signed=False)
        # assert isPow2(DEPTH), DEPTH
        MAX_DEPTH = DEPTH - 1
        s = self._sig
        r = self._reg
        fifo_write = s("fifo_write")
        write_ptr = _write_ptr = r("write_ptr", index_t, 0)
        ack_ptr_list = [
            (fifo_write, write_ptr),
        ]
        # update writer (head) pointer as needed
        If(
            fifo_write,
            If(write_ptr._eq(MAX_DEPTH),
               write_ptr(0)).Else(write_ptr(write_ptr + 1)))

        write_en, _ = write_en_wait
        # instantiate all read pointers
        for i, (read_en, read_wait) in enumerate(read_en_wait_list):
            read_ptr = r(f"read_ptr{i:d}", index_t, 0)
            fifo_read = s(f"fifo_read{i:d}")
            ack_ptr_list.append((fifo_read, read_ptr))
            # update reader (tail) pointer as needed
            If(
                fifo_read,
                If(read_ptr._eq(MAX_DEPTH),
                   read_ptr(0)).Else(read_ptr(read_ptr + 1)))

            looped = r(f"looped{i:d}", def_val=False)
            # looped logic
            If(write_en & write_ptr._eq(MAX_DEPTH),
               looped(True)).Elif(read_en & read_ptr._eq(MAX_DEPTH),
                                  looped(False))

            # Update Empty and Full flags
            read_wait(write_ptr._eq(read_ptr) & ~looped)
            fifo_read(read_en & (looped | (write_ptr != read_ptr)))
            # previous reader is next port writer (producer) as it next reader can continue only if previous reader did consume the item
            write_en, _ = read_en, read_wait
            write_ptr = read_ptr

        write_en, write_wait = write_en_wait
        write_ptr = _write_ptr
        # Update Empty and Full flags
        write_wait(write_ptr._eq(read_ptr) & looped)
        fifo_write(write_en & (~looped | (write_ptr != read_ptr)))

        return ack_ptr_list
Ejemplo n.º 24
0
    def _impl(self) -> None:
        start = self._sig("start")
        part_res_t = Bits(self.DATA_WIDTH)
        # High-order n bits of product
        a = self._reg("a", part_res_t)
        # multiplicand
        m = self._reg("m", part_res_t)
        # Initially holds multiplier, ultimately holds low-order n bits of product
        q = self._reg("q", part_res_t)
        # previous bit 0 of q
        q_1 = self._reg("q_1")

        din = self.dataIn
        dout = self.dataOut

        counter = self._reg(
            "counter",
            Bits(log2ceil(self.DATA_WIDTH + 1), signed=False),
            def_val=0)
        done = counter._eq(0)
        waitinOnConsumer = self._reg("waitinOnConsumer", def_val=0)

        add = rename_signal(self, (a + m)._signed(), "add")
        sub = rename_signal(self, (a - m)._signed(), "sub")

        If(start,
            a(0),
            m(din.a),
            q(din.b),
            q_1(0),
            counter(self.DATA_WIDTH),
        ).Elif(~done,
            Switch(Concat(q[0], q_1))
            .Case(0b01,
                # add multiplicand to left half of product
                a(add >> 1),
                q(Concat(add[0], q[:1])),
            ).Case(0b10,
                # substract multiplicand from left half of product
                a(sub >> 1),
                q(Concat(sub[0], q[:1])),
            ).Default(
                a(a._signed() >> 1),
                q(Concat(a[0], q[:1])),
            ),
            q_1(q[0]),
            counter(counter - 1)
        )

        If(start,
            waitinOnConsumer(1)
        ).Elif(done & dout.rd,
            waitinOnConsumer(0),
        )

        dout.data(Concat(a, q)._vec())
        dout.vld(done & waitinOnConsumer)
        start(din.vld & done & ~waitinOnConsumer)
        din.rd(done & ~waitinOnConsumer)
Ejemplo n.º 25
0
 def setUpClass(cls):
     cls.u = u = AxiInterconnectMatrixR(Axi4)
     u.MASTERS = ({0},)
     u.SLAVES = (
         (0x0000, 0x1000),
     )
     u.ADDR_WIDTH = log2ceil(0x1000 - 1)
     cls.compileSim(u)
Ejemplo n.º 26
0
    def _declr(self) -> None:
        addClkRstn(self)

        with self._paramsShared():
            self.s = Axi4()
            self.ram = RamSingleClock()
            self.ram.ADDR_WIDTH = self.ADDR_WIDTH - log2ceil(self.DATA_WIDTH //
                                                             8 - 1)
Ejemplo n.º 27
0
 def _declr(self):
     self.data = VectSignal(self.DATA_WIDTH)
     self.rem = VectSignal(log2ceil(self.DATA_WIDTH // 8))
     self.src_rdy_n = Signal()
     self.dst_rdy_n = Signal(masterDir=DIRECTION.IN)
     self.sof_n = Signal()
     self.eof_n = Signal()
     self.eop_n = Signal()
     self.sop_n = Signal()
Ejemplo n.º 28
0
 def setUpClass(cls):
     cls.u = u = AxiInterconnectMatrixAddrCrossbar(Axi4.AR_CLS)
     u.MASTERS = ({0}, {0}, {1}, {1}, {0, 1})
     u.SLAVES = (
         (0x0000, 0x1000),
         (0x1000, 0x1000),
     )
     u.ADDR_WIDTH = log2ceil(0x2000 - 1)
     cls.compileSim(u)
Ejemplo n.º 29
0
    def _declr(self):
        addClkRstn(self)

        self.cntrl = HandshakeSync()

        self.COUNTER_WIDTH = log2ceil(self.ITERATIONS)
        self.index = VectSignal(self.COUNTER_WIDTH)._m()
        self.body = HandshakeSync()._m()
        self.bodyBreak = Signal()
Ejemplo n.º 30
0
    def _declr(self):
        self.PAGE_OFFSET_WIDTH = log2ceil(self.PAGE_SIZE)
        self.LVL1_PAGE_TABLE_INDX_WIDTH = log2ceil(self.LVL1_PAGE_TABLE_ITEMS)
        self.LVL2_PAGE_TABLE_INDX_WIDTH = self.ADDR_WIDTH - self.LVL1_PAGE_TABLE_INDX_WIDTH - self.PAGE_OFFSET_WIDTH
        self.LVL2_PAGE_TABLE_ITEMS = 2 ** int(self.LVL2_PAGE_TABLE_INDX_WIDTH)
        assert self.LVL1_PAGE_TABLE_INDX_WIDTH > 0, self.LVL1_PAGE_TABLE_INDX_WIDTH
        assert self.LVL2_PAGE_TABLE_INDX_WIDTH > 0, self.LVL2_PAGE_TABLE_INDX_WIDTH
        assert self.LVL2_PAGE_TABLE_ITEMS > 1, self.LVL2_PAGE_TABLE_ITEMS

        # public interfaces
        addClkRstn(self)
        with self._paramsShared():
            self.rDatapump = AxiRDatapumpIntf()._m()
            self.rDatapump.MAX_BYTES = self.DATA_WIDTH // 8

        i = self.virtIn = Handshaked()
        i.DATA_WIDTH = self.VIRT_ADDR_WIDTH

        i = self.physOut = Handshaked()._m()
        i.DATA_WIDTH = self.ADDR_WIDTH
        self.segfault = Signal()._m()

        self.lvl1Table = BramPort_withoutClk()

        # internal components
        self.lvl1Storage = RamSingleClock()
        self.lvl1Storage.PORT_CNT = 1
        self.lvl1Converter = RamAsHs()
        for u in [self.lvl1Table, self.lvl1Converter, self.lvl1Storage]:
            u.DATA_WIDTH = self.ADDR_WIDTH
            u.ADDR_WIDTH = self.LVL1_PAGE_TABLE_INDX_WIDTH

        with self._paramsShared():
            self.lvl2get = ArrayItemGetter()
        self.lvl2get.ITEM_WIDTH = self.ADDR_WIDTH
        self.lvl2get.ITEMS = self.LVL2_PAGE_TABLE_ITEMS

        self.lvl2indxFifo = HandshakedFifo(Handshaked)
        self.lvl2indxFifo.DEPTH = self.MAX_OVERLAP // 2
        self.lvl2indxFifo.DATA_WIDTH = self.LVL2_PAGE_TABLE_INDX_WIDTH

        self.pageOffsetFifo = HandshakedFifo(Handshaked)
        self.pageOffsetFifo.DEPTH = self.MAX_OVERLAP
        self.pageOffsetFifo.DATA_WIDTH = self.PAGE_OFFSET_WIDTH