Exemplo n.º 1
0
    def connect_update_port(self, update: AxiCacheTagArrayUpdateIntf,
                            tag_mem_port_w: BramPort_withoutClk):
        update_tmp = self._reg("update_tmp",
                               HStruct(
                                   (update.addr._dtype, "addr"),
                                   (BIT, "delete"),
                                   (update.way_en._dtype, "way_en"),
                                   (BIT, "vld"),
                               ),
                               def_val={"vld": 0})
        update_tmp(update)
        tag, index, _ = self.parse_addr(update.addr)

        tag_mem_port_w.en(update.vld)
        tag_mem_port_w.addr(index)

        # construct the byte enable mask for various tag enable configurations
        # prepare write tag in every way but byte enable only requested ways
        tag_record = self.tag_record_t.from_py({
            "tag": tag,
            "valid": ~update.delete,
        })
        tag_record = tag_record._reinterpret_cast(
            Bits(self.tag_record_t.bit_length()))
        tag_mem_port_w.din(Concat(*(tag_record for _ in range(self.WAY_CNT))))
        tag_be_t = Bits(self.tag_record_t.bit_length() // 8)
        tag_en = tag_be_t.from_py(tag_be_t.all_mask())
        tag_not_en = tag_be_t.from_py(0)
        tag_mem_port_w.we(
            Concat(*reversed(
                [en._ternary(tag_en, tag_not_en) for en in update.way_en])))
        return update_tmp
Exemplo n.º 2
0
    def connect_lookup_port(self, lookup: AddrHs,
                            tag_mem_port_r: BramPort_withoutClk,
                            lookupRes: AxiCacheTagArrayLookupResIntf,
                            update_tmp: StructIntf):
        lookup_tmp = self._reg(
            "lookup_tmp",
            HStruct(*([(lookup.id._dtype, "id")] if lookup.ID_WIDTH else ()),
                    (lookup.addr._dtype, "addr"), (BIT, "vld")),
            def_val={"vld": 0})

        pa = self.parse_addr
        just_updated = rename_signal(
            self,
            # updated on same index (using "update" port) = the result which is currently on output
            # of the ram may be invalid
            update_tmp.vld
            & pa(lookup_tmp.addr)[1]._eq(pa(update_tmp.addr)[1]),
            "just_updated")

        # tag comparator
        tag, _, _ = self.parse_addr(lookup_tmp.addr)
        tags = tag_mem_port_r.dout._reinterpret_cast(
            self.tag_record_t[self.WAY_CNT])
        found = [
            # is matching and just this tag was not updated
            (t.valid & t.tag._eq(tag) &
             (~just_updated | (update_tmp.vld & ~update_tmp.way_en[i]))) | (
                 # or was updated to the matching tag
                 just_updated & update_tmp.way_en[i] & ~update_tmp.delete
                 & pa(lookup_tmp.addr)[0]._eq(pa(update_tmp.addr)[0]))
            for i, t in enumerate(tags)
        ]

        # if the data which is currently on output of the ram was
        # just updated it means that the data is invalid and the update
        # data will be lost in next clock cycle, if the consumer of lookupRes
        # can not consume the data just know, we need to perform lookup in tag_array
        # once again
        lookup.rd(~lookup_tmp.vld | lookupRes.rd)
        If(
            lookup.rd,
            lookup_tmp.id(lookup.id) if lookup.ID_WIDTH else [],
            lookup_tmp.addr(lookup.addr),
        )
        lookup_tmp.vld(lookup.vld | (lookup_tmp.vld & ~lookupRes.rd))

        tag_mem_port_r.addr((lookup_tmp.vld & ~lookupRes.rd)._ternary(
            self.parse_addr(lookup_tmp.addr)
            [1],  # lookup previous address and look for a change
            self.parse_addr(lookup.addr)[1],  # lookup a new address
        ))
        tag_mem_port_r.en(lookup.vld | (lookup_tmp.vld & ~lookupRes.rd))

        if lookupRes.ID_WIDTH:
            lookupRes.id(lookup_tmp.id)
        lookupRes.addr(lookup_tmp.addr)
        lookupRes.way(oneHotToBin(self, found))
        lookupRes.found(Or(*found))
        lookupRes.tags(tags)

        lookupRes.vld(lookup_tmp.vld)