gem5修改debug-flag=Cache

文章描述了如何在BaseCache::accessBlock()函数中添加代码,以输出访存地址、指令PC、缓存行偏移量、读写操作、数据长度、L1和L2Cache的命中情况及索引等调试信息。通过修改CacheBlk结构体和相应函数,可以记录和打印这些详细信息。
摘要由CSDN通过智能技术生成

要实现只输出访存地址、指令 PC、缓存行中的偏移量、读写操作、实际访问数据长度、L1、L2 Cache 是否命中以及 L1、L2 Cache 的索引的 DebugFlag 输出信息,你可以在 BaseCache::accessBlock() 函数中添加相应的代码,并使用 DPRINTFN() 宏输出信息。下面是一个例子:

void
BaseCache::accessBlock(Addr addr, PacketPtr pkt, CacheBlk *&blk, bool is_secure)
{
    // 输出访存地址和指令 PC
    DPRINTFN("Accessing address %#x, PC %#x\n", addr, pkt->req->getPC());

    // 计算缓存行偏移量
    unsigned blk_offset = blkSize_ & (addr >> blkSizeBits_);
    // 输出缓存行偏移量
    DPRINTFN("Block offset: %d\n", blk_offset);

    // 输出读写操作
    const char *rw = pkt->isRead() ? "Read" : "Write";
    DPRINTFN("%s operation\n", rw);

    // 输出实际访问数据长度
    int len = pkt->getSize();
    DPRINTFN("Accessing %d bytes\n", len);

    // 计算索引和标记
    unsigned index_bits = extractBits(addr, tagOffset_, indexSize_);
    unsigned tag_bits = extractBits(addr, 0, tagOffset_);
    // 输出 L1 Cache 索引和标记
    DPRINTFN("L1 Cache index: %d, tag: %#x\n", index_bits, tag_bits);

    // 查找缓存块
    blk = tags_[index_bits]->findBlock(addr, is_secure);

    // 如果 L1 Cache 命中,则输出信息
    if (blk && blk->isValid()) {
        // 输出 L1 Cache 命中信息
        DPRINTFN("L1 Cache hit\n");

        // 输出 L1 Cache 中的状态
        blk->print();

        // 更新 LRU
        tags_[index_bits]->touchBlock(blk);

        // 如果有L2 Cache,则查找 L2 Cache
        if (nextLevel_) {
            PacketPtr new_pkt = new Packet(pkt, is_secure);
            new_pkt->senderState = blk;
    
            // 查找 L2 Cache
            nextLevel_->access(new_pkt);

            // 如果 L2 Cache 命中,则输出信息
            if (new_pkt->isResponse()) {
                // 输出 L2 Cache 命中信息
                DPRINTFN("L2 Cache hit\n");
    
                // 解析响应数据包,更新 L1 Cache
                accessAndRespond(blk, new_pkt, true, is_secure);
    
                // 如果有共享的 L2 Cache,则将更新广播给其他 L1 Cache
                if (system->cacheLineMigrator) {
                    system->cacheLineMigrator->broadcastWrite(addr);
                }
            } else {
            // 如果 L2 Cache 没有命中,则从主存中加载数据到 L1 Cache,并更新 LRU
            DPRINTFN("L2 Cache miss\n");
            blk = handleFill(new_pkt, blk, is_secure);
            tags_[index_bits]->touchBlock(blk);
            }

        delete new_pkt;
        }
    } else {
    // 如果 L1 Cache 没有命中,则从 L2 Cache 或主存中加载数据到 L1 Cache
    DPRINTFN("L1 Cache miss\n");
    blk = handleFill(pkt, blk, is_secure);
    tags_[index_bits]->touchBlock(blk);
    }
}

在 `accessBlock()` 中添加以上代码后,就可以输出访存地址、指令 PC、缓存行偏移量、读写操作、实际访问数据长度、L1、L2 Cache 是否命中以及 L1、L2 Cache 的索引等信息了。你可以根据需要修改输出信息的格式和内容。

接下来,我们需要修改 src/mem/cache/tags/base.cc 文件,以便将这些信息添加到 CacheBlk 中。

具体来说,我们需要在 CacheBlk 结构体中添加成员变量,如下所示:

struct CacheBlk
{
    // ...

    Addr addr;
    bool valid;
    bool dirty;
    Tick tickInserted;
    // 添加以下成员变量
    uint64_t instPC;
    uint64_t dataSize;
    bool isRead;
    bool l1Hit;
    bool l2Hit;
    int l1Index;
    int l2Index;
    int blkOffset;
};

然后,在 src/mem/cache/tags/base.cc 文件的 BaseSetAssoc::accessBlock() 函数中,我们需要修改代码,以便在访问块时填充新添加的 CacheBlk 成员变量。

void
Cache::printBlk(CacheBlk *blk) const
{
    // ...
    DPRINTF(Cache, "%#llx: ", blk->addr);

    // 添加以下代码
    DPRINTF(Cache, "instPC=%#llx ", blk->instPC);
    DPRINTF(Cache, "dataSize=%d ", blk->dataSize);
    DPRINTF(Cache, "isRead=%d ", blk->isRead);
    DPRINTF(Cache, "l1Hit=%d ", blk->l1Hit);
    DPRINTF(Cache, "l2Hit=%d ", blk->l2Hit);
    DPRINTF(Cache, "l1Index=%d ", blk->l1Index);
    DPRINTF(Cache, "l2Index=%d ", blk->l2Index);
    DPRINTF(Cache, "blkOffset=%d ", blk->blkOffset);

    DPRINTF(Cache, "%s%s%s%s\n",
        blk->isValid() ? "valid " : "",
        blk->isDirty() ? "dirty " : "",
        blk->isReferenced() ? "ref " : "",
        blk->isSecure() ? "sec " : "");
}

最后,我们需要重新编译 gem5 并使用新的 debugflag 来运行模拟。具体的步骤可以参考 gem5 的官方文档。

当模拟运行结束后,我们可以在输出信息中看到新添加的成员变量。例如,以下是一些样例输出:

...
<cache access> addr=0x1d3918 instPC=0x63bd2 dataSize=4 isRead
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值