Пример #1
0
    def _impl(self):
        req = self.wDatapump.req
        w = self.wDatapump.w
        ack = self.wDatapump.ack

        # multi frame
        if self.MAX_OVERLAP > 1:
            ackPropageteInfo = HandshakedFifo(Handshaked)
            ackPropageteInfo.DEPTH = self.MAX_OVERLAP
        else:
            ackPropageteInfo = HandshakedReg(Handshaked)
        ackPropageteInfo.DATA_WIDTH = 1
        self.ackPropageteInfo = ackPropageteInfo

        if self.WRITE_ACK:
            _set = self.set
        else:
            _set = HsBuilder(self, self.set).buff().end

        if self.ID_WIDTH:
            req.id(self.ID)

        def propagateRequest(frame, indx):
            inNode = StreamNode(slaves=[req, ackPropageteInfo.dataIn])
            ack = inNode.ack()
            isLastFrame = indx == len(self._frames) - 1
            statements = [
                req.addr(_set.data + frame.startBitAddr // 8),
                req.len(frame.getWordCnt() - 1),
                self.driveReqRem(
                    req, frame.parts[-1].endOfPart - frame.startBitAddr),
                ackPropageteInfo.dataIn.data(SKIP if indx != 0 else PROPAGATE),
                inNode.sync(_set.vld),
                _set.rd(ack if isLastFrame else 0),
            ]

            return statements, ack & _set.vld

        StaticForEach(self, self._frames, propagateRequest)

        # connect write channel
        w(self.frameAssember.dataOut)

        # propagate ack
        StreamNode(masters=[ack, ackPropageteInfo.dataOut],
                   slaves=[self.writeAck],
                   skipWhen={
                       self.writeAck:
                       ackPropageteInfo.dataOut.data._eq(PROPAGATE)
                   }).sync()

        # connect fields to assembler
        for _, transTmpl in self._tmpl.walkFlatten():
            f = transTmpl.getFieldPath()
            intf = self.frameAssember.dataIn._fieldsToInterfaces[f]
            intf(self.dataIn._fieldsToInterfaces[f])

        propagateClkRstn(self)
Пример #2
0
    def _declr(self):
        AxiInterconnectCommon._declr(self, has_r=True, has_w=False)
        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()
        for connected_masters in masters_for_slave:
            if len(connected_masters) > 1:
                f = HandshakedFifo(Handshaked)
                f.DEPTH = self.MAX_TRANS_OVERLAP
                f.DATA_WIDTH = log2ceil(len(self.MASTERS))
            else:
                f = None
            order_m_index_for_s_data.append(f)
        self.order_m_index_for_s_data = order_m_index_for_s_data
        # fifo for slave index for each master
        # so master knows where it should expect the data
        order_s_index_for_m_data = HObjList()
        for connected_slaves in self.MASTERS:
            if len(connected_slaves) > 1:
                f = HandshakedFifo(Handshaked)
                f.DEPTH = self.MAX_TRANS_OVERLAP
                f.DATA_WIDTH = log2ceil(len(self.SLAVES))
            else:
                f = None
            order_s_index_for_m_data.append(f)
        self.order_s_index_for_m_data = order_s_index_for_m_data

        with self._paramsShared():
            self.addr_crossbar = AxiInterconnectMatrixAddrCrossbar(
                self.intfCls.AR_CLS)

        with self._paramsShared():
            c = self.data_crossbar = AxiInterconnectMatrixCrossbar(
                self.intfCls.R_CLS)
            c.INPUT_CNT = len(self.SLAVES)
            c.OUTPUTS = self.MASTERS
Пример #3
0
    def connect_r_fifo(self, avalon: AvalonMM, axi: Axi4):
        # buffer for read data to allow forward dispatch of the read requests
        # the availability of the space in fifo is checked using r_data_fifo_capacity counter
        f = HandshakedFifo(Handshaked)
        f.DEPTH = self.R_DATA_FIFO_DEPTH
        f.DATA_WIDTH = self.DATA_WIDTH
        self.r_data_fifo = f

        # f.dataIn.rd ignored because the request should not be dispatched in the first place
        f.dataIn.data(avalon.readData)
        f.dataIn.vld(avalon.readDataValid)

        sf = self.r_size_fifo
        wordIndexCntr = self._reg(
            "wordIndexCntr",
            HStruct(
                (sf.dataOut.len._dtype, "len"),
                (axi.r.id._dtype, "id"),
                (BIT, "vld")
            ),
            def_val={"vld": 0}
        )

        r_out_node = StreamNode([f.dataOut], [axi.r])
        r_out_node.sync(wordIndexCntr.vld)

        # load word index counter if it is invalid else decrement on data transaction
        newSizeAck = (~wordIndexCntr.vld | (wordIndexCntr.len._eq(0) & r_out_node.ack()))
        If(newSizeAck,
            wordIndexCntr.id(sf.dataOut.id),
            wordIndexCntr.len(sf.dataOut.len),
            wordIndexCntr.vld(sf.dataOut.vld),
        ).Elif(r_out_node.ack(),
            wordIndexCntr.len(wordIndexCntr.len - 1),
            wordIndexCntr.vld(wordIndexCntr.len != 0),
        )
        sf.dataOut.rd(newSizeAck)

        axi.r.id(wordIndexCntr.id)
        axi.r.data(f.dataOut.data)
        axi.r.resp(RESP_OKAY)
        axi.r.last(wordIndexCntr.len._eq(0))
        return rename_signal(self, r_out_node.ack(), "r_data_ack")
Пример #4
0
    def _declr(self):
        addClkRstn(self)

        self.items = Handshaked()
        self.items.DATA_WIDTH = self.ITEM_WIDTH

        with self._paramsShared():
            self.wDatapump = AxiWDatapumpIntf()._m()

        self.uploaded = VectSignal(16)._m()

        self.baseAddr = RegCntrl()
        self.baseAddr.DATA_WIDTH = self.ADDR_WIDTH

        self.buff_remain = VectSignal(16)._m()

        b = HandshakedFifo(Handshaked)
        b.DATA_WIDTH = self.ITEM_WIDTH
        b.EXPORT_SIZE = True
        b.DEPTH = self.BUFF_DEPTH
        self.buff = b
Пример #5
0
    def propagate_addr(self, m_a, s_a):
        name_prefix = m_a._name + "_"
        AL_IN_W = self.ALIGN_BITS_IN
        AL_OUT_W = self.ALIGN_BITS_OUT
        ALIG_W = AL_OUT_W - AL_IN_W
        assert ALIG_W > 0, ALIG_W
        m_a = AxiSBuilder(self, m_a).buff().end

        align_fifo = HandshakedFifo(Handshaked)
        align_fifo.DATA_WIDTH = ALIG_W
        align_fifo.DEPTH = self.MAX_TRANS_OVERLAP
        setattr(self, name_prefix + "align_fifo", align_fifo)

        aligned_addr = Concat(m_a.addr[:AL_OUT_W], Bits(AL_OUT_W).from_py(0))
        align_fifo.dataIn.data(m_a.addr[AL_OUT_W:AL_IN_W])

        s_a(m_a, exclude={m_a.addr, m_a.valid, m_a.ready})
        StreamNode(
            masters=[m_a],
            slaves=[s_a, align_fifo.dataIn],
        ).sync()
        s_a.addr(aligned_addr, fit=self.ADDR_WIDTH != self.OUT_ADDR_WIDTH)

        return align_fifo