示例#1
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
示例#2
0
文件: axi_ram.py 项目: mfkiwl/hwtLib
    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)
示例#3
0
    def _declr(self):
        addClkRstn(self)

        with self._paramsShared():
            self.r = RamHsR()
            self.w = AddrDataHs()

            self.conv = RamAsHs()
            self.ram = RamSingleClock()
示例#4
0
    def _declr(self):
        HashTableCoreWithRam._declr_common(self)
        t = self.table = RamSingleClock()
        t.PORT_CNT = 1
        t.ADDR_WIDTH = log2ceil(self.ITEMS_CNT)
        t.DATA_WIDTH = self.KEY_WIDTH + self.DATA_WIDTH + 1  # +1 for item_vld

        tc = self.tableConnector = RamAsHs()
        tc.ADDR_WIDTH = t.ADDR_WIDTH
        tc.DATA_WIDTH = t.DATA_WIDTH
示例#5
0
文件: flipRam.py 项目: mfkiwl/hwtLib
    def _declr(self):
        PORT_CNT = self.PORT_CNT

        with self._paramsShared():
            self.clk = Clk()

            # to let IDEs resolve type of port
            self.firstA = BramPort_withoutClk()
            self.secondA = BramPort_withoutClk()

            if PORT_CNT == 2:
                self.firstB = BramPort_withoutClk()
                self.secondB = BramPort_withoutClk()
            elif PORT_CNT > 2:
                raise NotImplementedError()

            self.select_sig = Signal()

            self.ram0 = RamSingleClock()
            self.ram1 = RamSingleClock()
示例#6
0
    def _declr(self):
        self.PAGE_OFFSET_WIDTH = log2ceil(self.PAGE_SIZE).val
        self.LVL1_PAGE_TABLE_INDX_WIDTH = log2ceil(
            self.LVL1_PAGE_TABLE_ITEMS).val
        self.LVL2_PAGE_TABLE_INDX_WIDTH = int(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_LEN.set(1)

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

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

        self.lvl1Table = BramPort_withoutClk()

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

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

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

        self.pageOffsetFifo = HandshakedFifo(Handshaked)
        self.pageOffsetFifo.DEPTH.set(self.MAX_OVERLAP)
        self.pageOffsetFifo.DATA_WIDTH.set(self.PAGE_OFFSET_WIDTH)
示例#7
0
    def _declr(self):
        assert self.HAS_BE
        assert len(
            self.PORT_CNT) >= 2, "Requres at least 1 WRITE and 1 READ port"
        assert self.PORT_CNT == (
            WRITE,
            *(READ for _ in range(len(self.PORT_CNT) - 1))),\
            self.PORT_CNT
        addClkRstn(self)
        RamSingleClock._declr_ports(self)

        self.MASK_W = self.DATA_WIDTH // 8
        # padding to make mask width % 8 == 0
        self.MASK_PADDING_W = ceil(self.MASK_W / 8) * 8 - self.MASK_W
        with self._paramsShared(exclude=({"DATA_WIDTH"}, {})):
            ram = self.ram = RamSingleClock()
            ram.DATA_WIDTH = self.DATA_WIDTH + self.MASK_PADDING_W + self.MASK_W
示例#8
0
    def _declr(self):
        addClkRstn(self)

        with self._paramsShared():
            if self.HAS_R:
                self.r = RamHsR()
            if self.HAS_W:
                self.w = AddrDataHs()

            self.conv = RamAsHs()
            r = self.ram = RamSingleClock()
            if not self.HAS_W:
                assert self.INIT_DATA is not None
                assert self.HAS_R
                r.PORT_CNT = (READ,)
            elif not self.HAS_R:
                assert self.HAS_W
                r.PORT_CNT = (WRITE,)
示例#9
0
    def _declr(self):
        self._compupte_tag_index_offset_widths()
        self.tag_record_t = self.define_tag_record_t()
        addClkRstn(self)
        with self._paramsShared():
            self.lookup = HObjList(AddrHs() for _ in range(self.PORT_CNT))
            self.lookupRes = HObjList(AxiCacheTagArrayLookupResIntf()._m()
                                      for _ in range(self.PORT_CNT))
            for i in self.lookupRes:
                i.TAG_T = self.tag_record_t
            self.update = HObjList(AxiCacheTagArrayUpdateIntf()
                                   for _ in range(self.UPDATE_PORT_CNT))

        tag_mem = self.tag_mem = RamSingleClock()
        tag_mem.ADDR_WIDTH = log2ceil(self.CACHE_LINE_CNT // self.WAY_CNT - 1)
        tag_mem.DATA_WIDTH = self.tag_record_t.bit_length() * self.WAY_CNT
        tag_mem.MAX_BLOCK_DATA_WIDTH = self.MAX_BLOCK_DATA_WIDTH
        tag_mem.PORT_CNT = (
            *(WRITE for _ in range(self.UPDATE_PORT_CNT)),
            *(READ for _ in range(self.PORT_CNT)),
        )
        tag_mem.HAS_BE = True
示例#10
0
    def _declr(self):
        addClkRstn(self)
        self._init_constants()

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

        self.ooo_fifo = FifoOutOfOrderRead()
        self.ooo_fifo.ITEMS = 2 ** self.ID_WIDTH

        sa = self.state_array = RamSingleClock()
        sa.PORT_CNT = (WRITE, READ)
        sa.ADDR_WIDTH = self.ID_WIDTH

        TRANSACTION_STATE_T = self.TRANSACTION_STATE_T
        # address + TRANSACTION_STATE_T
        sa.DATA_WIDTH = self.MAIN_STATE_INDEX_WIDTH + (
            0 if TRANSACTION_STATE_T is None else
            TRANSACTION_STATE_T.bit_length()
        )

        self._declr_io()
示例#11
0
    def _declr(self):
        addClkRstn(self)
        assert int(self.KEY_WIDTH) > 0
        assert int(self.DATA_WIDTH) >= 0
        assert int(self.ITEMS_CNT) > 1

        self.HASH_WITH = log2ceil(self.ITEMS_CNT).val

        assert self.HASH_WITH < int(self.KEY_WIDTH), (
            "It makes no sense to use hash table when you can use key directly as index",
            self.HASH_WITH, self.KEY_WIDTH)

        with self._paramsShared():
            self.insert = InsertIntf()
            self.insert.HASH_WIDTH.set(self.HASH_WITH)

            self.lookup = LookupKeyIntf()

            self.lookupRes = LookupResultIntf()._m()
            self.lookupRes.HASH_WIDTH.set(self.HASH_WITH)

        t = self.table = RamSingleClock()
        t.PORT_CNT.set(1)
        t.ADDR_WIDTH.set(log2ceil(self.ITEMS_CNT))
        t.DATA_WIDTH.set(self.KEY_WIDTH + self.DATA_WIDTH +
                         1)  # +1 for vldFlag

        tc = self.tableConnector = RamAsHs()
        tc.ADDR_WIDTH.set(t.ADDR_WIDTH.get())
        tc.DATA_WIDTH.set(t.DATA_WIDTH.get())

        hashWidth = max(int(self.KEY_WIDTH), int(self.HASH_WITH))
        h = self.hash = CrcComb()
        h.DATA_WIDTH.set(hashWidth)
        h.setConfig(self.POLYNOME)
        h.POLY_WIDTH.set(hashWidth)
示例#12
0
文件: ramXor.py 项目: mfkiwl/hwtLib
    def _impl(self):
        if self._can_be_primitive_ram:
            super(RamXorSingleClock, self)._impl()
        else:
            if self.PRIMITIVE_MEMORY_PORTS != (WRITE, READ):
                raise NotImplementedError(self.PRIMITIVE_MEMORY_PORTS)
            if self._rw_ports:
                raise NotImplementedError("RW ports (supports only write and read ports)")

            r_ports = self._r_ports
            assert r_ports
            w_ports = self._w_ports
            assert w_ports
            # 1. construct a matrix N x N where N is a number of wrie ports
            # the diagonal is set to None because we do not need to synchronize the port with itself
            w_rams = HObjList(
                HObjList(
                    RamSingleClock() if x != y else None
                    for x in w_ports
                )
                for y in w_ports)
            # construct a matrix M x N where M is number of read ports
            r_rams = HObjList(HObjList(RamSingleClock() for _ in w_ports)
                              for _ in range(len(r_ports)))

            for row in w_rams + r_rams:
                for r in row:
                    if r is None:
                        continue
                    r._updateParamsFrom(self, exclude=(("PORT_CNT",), ()))
                    r.PORT_CNT = self.PRIMITIVE_MEMORY_PORTS
                    if self.INIT_DATA is not None:
                        raise NotImplementedError()
                    r.INIT_DATA = tuple(0 for _ in range(2 ** r.ADDR_WIDTH))
            self.w_rams = w_rams
            self.r_rams = r_rams

            # :type: List[Tuple[RtlSignal, RtlSignal, RtlSignal]]
            # List of tuples (en, address, write data), used for write forwarding on read ports
            write_in_progress_staus = []

            # 2. connect them with XOR logic
            # add the register on write address and data because we need to load the data for XOR first
            for i, w in enumerate(w_ports):
                xor_src = []
                for mem in w_rams[i]:
                    if mem is not None:
                        xor_src.append(mem)

                xor_loaded_src = []
                for s in xor_src:
                    p = s.port[1]
                    p.addr(w.addr)
                    p.en(w.en)
                    xor_loaded_src.append(p.dout)

                w_addr_reg = self._reg(f"{w._name}_addr_reg", w.addr._dtype)
                w_addr_reg(w.addr)
                w_en_reg = self._reg(f"{w._name}_en_reg", def_val=0)
                w_en_reg(w.en)
                w_data_reg = self._reg(f"{w._name}_data_reg", w.din._dtype)
                w_data_reg(w.din)

                xored_data = Xor(w_data_reg, *xor_loaded_src)
                for ram_row in w_rams + r_rams:
                    xor_dst = ram_row[i]
                    if xor_dst is None:
                        continue
                    xor_dst = xor_dst.port[0]
                    xor_dst.addr(w_addr_reg)
                    xor_dst.en(w_en_reg)
                    xor_dst.din(xored_data)
                write_in_progress_staus.append((w_en_reg, w_addr_reg, xored_data))

            # 3. connect read ports to memories
            for (i, r), r_ram_column in zip(enumerate(r_ports), r_rams):
                out_xor_inputs = []
                for r_ram, (w_en_reg, w_addr_reg, w_xored_data) in zip(r_ram_column, write_in_progress_staus):
                    r_ram = r_ram.port[1]
                    s = (w_en_reg & w_addr_reg._eq(r.addr))._ternary(w_xored_data, r_ram.dout)
                    out_xor_inputs.append(s)
                    r_ram.addr(r.addr)
                    r_ram.en(r.en)

                r.dout(Xor(*out_xor_inputs))

            propagateClk(self)
示例#13
0
文件: ram_test.py 项目: mfkiwl/hwtLib
 def setUpClass(cls):
     u = cls.u = RamSingleClock()
     u.DATA_WIDTH = 8
     u.ADDR_WIDTH = 3
     cls.compileSim(u)