mem-ruby,mem-cache: ruby supports classic pfs
This patch adds RubyPrefetcherProxy, which provides means to inject requests generated by the "classic" prefetchers into a SLICC prefetch queue. It defines defines notifyPf* functions to be used by protocols to notify a prefetcher. It also includes the probes required to interface with the classic implementation. AbstractController defines the accessor needed to snoop the caches. A followup patch will add support for RubyPrefetcherProxy in the CHI protocol. Related JIRA: https://gem5.atlassian.net/browse/GEM5-457 https://gem5.atlassian.net/browse/GEM5-1112 Additional authors: Tuan Ta <tuan.ta2@arm.com> Change-Id: Ie908150b510f951cdd6fd0fd9c95d9760ff70fb0 Signed-off-by: Tiago Mück <tiago.muck@arm.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# -*- mode:python -*-
|
||||
|
||||
# Copyright (c) 2021 Arm Limited
|
||||
# Copyright (c) 2021,2023 Arm Limited
|
||||
# All rights reserved.
|
||||
#
|
||||
# The license below extends only to copyright in the software and shall
|
||||
@@ -111,6 +111,7 @@ MakeInclude('structures/DirectoryMemory.hh')
|
||||
MakeInclude('structures/PerfectCacheMemory.hh')
|
||||
MakeInclude('structures/PersistentTable.hh')
|
||||
MakeInclude('structures/RubyPrefetcher.hh')
|
||||
MakeInclude('structures/RubyPrefetcherProxy.hh')
|
||||
MakeInclude('structures/TBEStorage.hh')
|
||||
if env['PROTOCOL'] == 'CHI':
|
||||
MakeInclude('structures/MN_TBEStorage.hh')
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 ARM Limited
|
||||
* Copyright (c) 2020-2021,2023 ARM Limited
|
||||
* All rights reserved.
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
@@ -51,6 +51,8 @@ external_type(Addr, primitive="yes");
|
||||
external_type(Cycles, primitive="yes", default="Cycles(0)");
|
||||
external_type(Tick, primitive="yes", default="0");
|
||||
external_type(RequestPtr, primitive="yes", default="nullptr");
|
||||
external_type(RequestorID, primitive="yes");
|
||||
external_type(prefetch::Base, primitive="yes");
|
||||
|
||||
structure(WriteMask, external="yes", desc="...") {
|
||||
void clear();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 ARM Limited
|
||||
* Copyright (c) 2020-2021,2023 ARM Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
@@ -259,3 +259,14 @@ structure (RubyPrefetcher, external = "yes") {
|
||||
void observePfHit(Addr);
|
||||
void observePfMiss(Addr);
|
||||
}
|
||||
|
||||
structure(RubyPrefetcherProxy, external = "yes") {
|
||||
void notifyPfHit(RequestPtr, bool, DataBlock);
|
||||
void notifyPfMiss(RequestPtr, bool, DataBlock);
|
||||
void notifyPfFill(RequestPtr, DataBlock, bool);
|
||||
void notifyPfEvict(Addr, bool, RequestorID);
|
||||
void completePrefetch(Addr);
|
||||
// SLICC controller must define its own regProbePoints and call
|
||||
// this for every RubyPrefetcherProxy object present
|
||||
void regProbePoints();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 ARM Limited
|
||||
* Copyright (c) 2021,2023 ARM Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
@@ -60,3 +60,4 @@ Addr makeNextStrideAddress(Addr addr, int stride);
|
||||
structure(BoolVec, external="yes") {
|
||||
}
|
||||
int countBoolVec(BoolVec bVec);
|
||||
RequestorID getRequestorID(RequestPtr req);
|
||||
|
||||
@@ -367,6 +367,28 @@ class AbstractController : public ClockedObject, public Consumer
|
||||
void wakeUpAllBuffers();
|
||||
bool serviceMemoryQueue();
|
||||
|
||||
/**
|
||||
* Functions needed by CacheAccessor. These are implemented in SLICC,
|
||||
* thus the const& for all args to match the generated code.
|
||||
*/
|
||||
virtual bool inCache(const Addr &addr, const bool &is_secure)
|
||||
{ fatal("inCache: prefetching not supported"); return false; }
|
||||
|
||||
virtual bool hasBeenPrefetched(const Addr &addr, const bool &is_secure)
|
||||
{ fatal("hasBeenPrefetched: prefetching not supported"); return false; }
|
||||
|
||||
virtual bool hasBeenPrefetched(const Addr &addr, const bool &is_secure,
|
||||
const RequestorID &requestor)
|
||||
{ fatal("hasBeenPrefetched: prefetching not supported"); return false; }
|
||||
|
||||
virtual bool inMissQueue(const Addr &addr, const bool &is_secure)
|
||||
{ fatal("inMissQueue: prefetching not supported"); return false; }
|
||||
|
||||
virtual bool coalesce()
|
||||
{ fatal("coalesce: prefetching not supported"); return false; }
|
||||
|
||||
friend class RubyPrefetcherProxy;
|
||||
|
||||
protected:
|
||||
const NodeID m_version;
|
||||
MachineID m_machineID;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2021 ARM Limited
|
||||
* Copyright (c) 2020-2021,2023 ARM Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
@@ -316,6 +316,12 @@ countBoolVec(BoolVec bVec)
|
||||
return count;
|
||||
}
|
||||
|
||||
inline RequestorID
|
||||
getRequestorID(RequestPtr req)
|
||||
{
|
||||
return req->requestorId();
|
||||
}
|
||||
|
||||
} // namespace ruby
|
||||
} // namespace gem5
|
||||
|
||||
|
||||
234
src/mem/ruby/structures/RubyPrefetcherProxy.cc
Normal file
234
src/mem/ruby/structures/RubyPrefetcherProxy.cc
Normal file
@@ -0,0 +1,234 @@
|
||||
/*
|
||||
* Copyright (c) 2023 ARM Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
* not be construed as granting a license to any other intellectual
|
||||
* property including but not limited to intellectual property relating
|
||||
* to a hardware implementation of the functionality of the software
|
||||
* licensed hereunder. You may use the software subject to the license
|
||||
* terms below provided that you ensure that this notice is replicated
|
||||
* unmodified and in its entirety in all distributions of the software,
|
||||
* modified or unmodified, in source code or in binary form.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "mem/ruby/structures/RubyPrefetcherProxy.hh"
|
||||
|
||||
#include "debug/HWPrefetch.hh"
|
||||
#include "mem/ruby/system/RubySystem.hh"
|
||||
|
||||
namespace gem5
|
||||
{
|
||||
|
||||
namespace ruby
|
||||
{
|
||||
|
||||
RubyPrefetcherProxy::RubyPrefetcherProxy(AbstractController* _parent,
|
||||
prefetch::Base* _prefetcher,
|
||||
MessageBuffer *_pf_queue)
|
||||
:Named(_parent->name()),
|
||||
prefetcher(_prefetcher),
|
||||
cacheCntrl(_parent),
|
||||
pfQueue(_pf_queue),
|
||||
pfEvent([this]{ issuePrefetch(); }, name()),
|
||||
ppHit(nullptr), ppMiss(nullptr),
|
||||
ppFill(nullptr), ppDataUpdate(nullptr)
|
||||
{
|
||||
fatal_if(!cacheCntrl,
|
||||
"initializing a RubyPrefetcherProxy without a parent");
|
||||
if (prefetcher) {
|
||||
fatal_if(!pfQueue,
|
||||
"%s initializing a RubyPrefetcherProxy without a prefetch queue",
|
||||
name());
|
||||
prefetcher->setParentInfo(
|
||||
cacheCntrl->params().system,
|
||||
cacheCntrl->getProbeManager(),
|
||||
RubySystem::getBlockSizeBytes());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RubyPrefetcherProxy::scheduleNextPrefetch()
|
||||
{
|
||||
if (pfEvent.scheduled())
|
||||
return;
|
||||
|
||||
Tick next_pf_time = std::max(prefetcher->nextPrefetchReadyTime(),
|
||||
cacheCntrl->clockEdge(Cycles(1)));
|
||||
if (next_pf_time != MaxTick) {
|
||||
DPRINTF(HWPrefetch, "Next prefetch ready at %d\n", next_pf_time);
|
||||
cacheCntrl->schedule(&pfEvent, next_pf_time);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RubyPrefetcherProxy::deschedulePrefetch()
|
||||
{
|
||||
if (pfEvent.scheduled())
|
||||
cacheCntrl->deschedule(&pfEvent);
|
||||
}
|
||||
|
||||
void
|
||||
RubyPrefetcherProxy::completePrefetch(Addr addr)
|
||||
{
|
||||
assert(makeLineAddress(addr) == addr);
|
||||
assert(issuedPfPkts.count(addr) == 1);
|
||||
DPRINTF(HWPrefetch, "Prefetch request for addr %#x completed\n", addr);
|
||||
delete issuedPfPkts[addr];
|
||||
issuedPfPkts.erase(addr);
|
||||
}
|
||||
|
||||
void
|
||||
RubyPrefetcherProxy::issuePrefetch()
|
||||
{
|
||||
assert(prefetcher);
|
||||
assert(pfQueue);
|
||||
|
||||
if (pfQueue->areNSlotsAvailable(1, curTick())) {
|
||||
PacketPtr pkt = prefetcher->getPacket();
|
||||
|
||||
if (pkt) {
|
||||
DPRINTF(HWPrefetch, "Next prefetch ready %s\n", pkt->print());
|
||||
unsigned blk_size = RubySystem::getBlockSizeBytes();
|
||||
Addr line_addr = pkt->getBlockAddr(blk_size);
|
||||
|
||||
if (issuedPfPkts.count(line_addr) == 0) {
|
||||
DPRINTF(HWPrefetch, "Issued PF request for paddr=%#x, "
|
||||
"line_addr=%#x, is_write=%d\n",
|
||||
pkt->getAddr(), line_addr,
|
||||
pkt->needsWritable());
|
||||
|
||||
RubyRequestType req_type = pkt->needsWritable() ?
|
||||
RubyRequestType_ST : RubyRequestType_LD;
|
||||
|
||||
std::shared_ptr<RubyRequest> msg =
|
||||
std::make_shared<RubyRequest>(cacheCntrl->clockEdge(),
|
||||
pkt->getAddr(),
|
||||
blk_size,
|
||||
0, // pc
|
||||
req_type,
|
||||
RubyAccessMode_Supervisor,
|
||||
pkt,
|
||||
PrefetchBit_Yes);
|
||||
|
||||
// enqueue request into prefetch queue to the cache
|
||||
pfQueue->enqueue(msg, cacheCntrl->clockEdge(),
|
||||
cacheCntrl->cyclesToTicks(Cycles(1)));
|
||||
|
||||
// track all pending PF requests
|
||||
issuedPfPkts[line_addr] = pkt;
|
||||
} else {
|
||||
DPRINTF(HWPrefetch, "Aborted PF request for address being "
|
||||
"prefetched\n");
|
||||
delete pkt;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
DPRINTF(HWPrefetch, "No prefetch slots are available\n");
|
||||
}
|
||||
|
||||
scheduleNextPrefetch();
|
||||
}
|
||||
|
||||
void
|
||||
RubyPrefetcherProxy::notifyPfHit(const RequestPtr& req, bool is_read,
|
||||
const DataBlock& data_blk)
|
||||
{
|
||||
assert(ppHit);
|
||||
assert(req);
|
||||
Packet pkt(req, is_read ? Packet::makeReadCmd(req) :
|
||||
Packet::makeWriteCmd(req));
|
||||
// NOTE: for now we only communicate physical address with prefetchers
|
||||
pkt.dataStaticConst<uint8_t>(data_blk.getData(getOffset(req->getPaddr()),
|
||||
pkt.getSize()));
|
||||
DPRINTF(HWPrefetch, "notify hit: %s\n", pkt.print());
|
||||
ppHit->notify(CacheAccessProbeArg(&pkt, *this));
|
||||
scheduleNextPrefetch();
|
||||
}
|
||||
|
||||
void
|
||||
RubyPrefetcherProxy::notifyPfMiss(const RequestPtr& req, bool is_read,
|
||||
const DataBlock& data_blk)
|
||||
{
|
||||
assert(ppMiss);
|
||||
assert(req);
|
||||
Packet pkt(req, is_read ? Packet::makeReadCmd(req) :
|
||||
Packet::makeWriteCmd(req));
|
||||
// NOTE: for now we only communicate physical address with prefetchers
|
||||
pkt.dataStaticConst<uint8_t>(data_blk.getData(getOffset(req->getPaddr()),
|
||||
pkt.getSize()));
|
||||
DPRINTF(HWPrefetch, "notify miss: %s\n", pkt.print());
|
||||
ppMiss->notify(CacheAccessProbeArg(&pkt, *this));
|
||||
scheduleNextPrefetch();
|
||||
}
|
||||
|
||||
void
|
||||
RubyPrefetcherProxy::notifyPfFill(const RequestPtr& req,
|
||||
const DataBlock& data_blk,
|
||||
bool from_pf)
|
||||
{
|
||||
assert(ppFill);
|
||||
assert(req);
|
||||
Packet pkt(req, Packet::makeReadCmd(req));
|
||||
if (from_pf)
|
||||
pkt.cmd = Packet::Command::HardPFReq;
|
||||
// NOTE: for now we only communicate physical address with prefetchers
|
||||
pkt.dataStaticConst<uint8_t>(data_blk.getData(getOffset(req->getPaddr()),
|
||||
pkt.getSize()));
|
||||
DPRINTF(HWPrefetch, "notify fill: %s\n", pkt.print());
|
||||
ppFill->notify(CacheAccessProbeArg(&pkt, *this));
|
||||
scheduleNextPrefetch();
|
||||
}
|
||||
|
||||
void
|
||||
RubyPrefetcherProxy::notifyPfEvict(Addr blkAddr, bool hwPrefetched,
|
||||
RequestorID requestorID)
|
||||
{
|
||||
DPRINTF(HWPrefetch, "notify evict: %#x hw_pf=%d\n", blkAddr, hwPrefetched);
|
||||
CacheDataUpdateProbeArg data_update(
|
||||
blkAddr, false, requestorID, *this);
|
||||
data_update.hwPrefetched = hwPrefetched;
|
||||
ppDataUpdate->notify(data_update);
|
||||
scheduleNextPrefetch();
|
||||
}
|
||||
|
||||
void
|
||||
RubyPrefetcherProxy::regProbePoints()
|
||||
{
|
||||
assert(cacheCntrl);
|
||||
ppHit = new ProbePointArg<CacheAccessProbeArg>(
|
||||
cacheCntrl->getProbeManager(), "Hit");
|
||||
ppMiss = new ProbePointArg<CacheAccessProbeArg>(
|
||||
cacheCntrl->getProbeManager(), "Miss");
|
||||
ppFill = new ProbePointArg<CacheAccessProbeArg>(
|
||||
cacheCntrl->getProbeManager(), "Fill");
|
||||
ppDataUpdate =
|
||||
new ProbePointArg<CacheDataUpdateProbeArg>(
|
||||
cacheCntrl->getProbeManager(), "Data Update");
|
||||
}
|
||||
|
||||
} // namespace ruby
|
||||
} // namespace gem5
|
||||
178
src/mem/ruby/structures/RubyPrefetcherProxy.hh
Normal file
178
src/mem/ruby/structures/RubyPrefetcherProxy.hh
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (c) 2023 ARM Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
* not be construed as granting a license to any other intellectual
|
||||
* property including but not limited to intellectual property relating
|
||||
* to a hardware implementation of the functionality of the software
|
||||
* licensed hereunder. You may use the software subject to the license
|
||||
* terms below provided that you ensure that this notice is replicated
|
||||
* unmodified and in its entirety in all distributions of the software,
|
||||
* modified or unmodified, in source code or in binary form.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __MEM_RUBY_STRUCTURES_RUBY_PREFETCHER_WRAPPER_HH__
|
||||
#define __MEM_RUBY_STRUCTURES_RUBY_PREFETCHER_WRAPPER_HH__
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#include "mem/cache/cache_probe_arg.hh"
|
||||
#include "mem/cache/prefetch/base.hh"
|
||||
#include "mem/ruby/slicc_interface/AbstractController.hh"
|
||||
#include "mem/ruby/slicc_interface/RubyRequest.hh"
|
||||
|
||||
namespace gem5
|
||||
{
|
||||
|
||||
namespace ruby
|
||||
{
|
||||
|
||||
/**
|
||||
* This is a proxy for prefetcher class in classic memory. This wrapper
|
||||
* enables a SLICC machine to interact with classic prefetchers.
|
||||
*
|
||||
* The expected use case for this class is to instantiate it in the SLICC
|
||||
* state machine definition and provide a pointer to the prefetcher object
|
||||
* (typically defined in SLICC as one of the SM's configuration parameters)
|
||||
* and the prefetch queue where prefetch requests will be inserted.
|
||||
*
|
||||
* The SLICC SM can them use the notifyPF* functions to notify the prefetcher.
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* This object's regProbePoints() must be called explicitly. The SLICC SM may
|
||||
* defined it's own regProbePoints() to call it.
|
||||
*
|
||||
* completePrefetch(Addr) must be called when a request injected into the
|
||||
* prefetch queue is completed.
|
||||
*
|
||||
* A nullptr prefetcher can be provided, in which case the notifyPf* are
|
||||
* no-ops.
|
||||
*
|
||||
*/
|
||||
class RubyPrefetcherProxy : public CacheAccessor, public Named
|
||||
{
|
||||
public:
|
||||
|
||||
RubyPrefetcherProxy(AbstractController* parent,
|
||||
prefetch::Base* prefetcher,
|
||||
MessageBuffer *pf_queue);
|
||||
|
||||
/** Deschedled the ready prefetch event */
|
||||
void deschedulePrefetch();
|
||||
|
||||
/** Notifies a completed prefetch request */
|
||||
void completePrefetch(Addr addr);
|
||||
|
||||
/**
|
||||
* Notify PF probes hit/miss/fill
|
||||
*/
|
||||
void notifyPfHit(const RequestPtr& req, bool is_read,
|
||||
const DataBlock& data_blk);
|
||||
void notifyPfMiss(const RequestPtr& req, bool is_read,
|
||||
const DataBlock& data_blk);
|
||||
void notifyPfFill(const RequestPtr& req, const DataBlock& data_blk,
|
||||
bool from_pf);
|
||||
void notifyPfEvict(Addr blkAddr, bool hwPrefetched,
|
||||
RequestorID requestorID);
|
||||
|
||||
/** Registers probes. */
|
||||
void regProbePoints();
|
||||
|
||||
private:
|
||||
|
||||
/** Schedule the next ready prefetch */
|
||||
void scheduleNextPrefetch();
|
||||
|
||||
/** Issue prefetch to the contoller prefetch queue */
|
||||
void issuePrefetch();
|
||||
|
||||
/** Prefetcher from classic memory */
|
||||
prefetch::Base* prefetcher;
|
||||
|
||||
/** Ruby cache controller */
|
||||
AbstractController* cacheCntrl;
|
||||
|
||||
/** Prefetch queue to the cache controller */
|
||||
MessageBuffer* pfQueue;
|
||||
|
||||
/** List of issued prefetch request packets */
|
||||
std::unordered_map<Addr, PacketPtr> issuedPfPkts;
|
||||
|
||||
/** Prefetch event */
|
||||
EventFunctionWrapper pfEvent;
|
||||
|
||||
/** To probe when a cache hit occurs */
|
||||
ProbePointArg<CacheAccessProbeArg> *ppHit;
|
||||
|
||||
/** To probe when a cache miss occurs */
|
||||
ProbePointArg<CacheAccessProbeArg> *ppMiss;
|
||||
|
||||
/** To probe when a cache fill occurs */
|
||||
ProbePointArg<CacheAccessProbeArg> *ppFill;
|
||||
|
||||
/**
|
||||
* To probe when the contents of a block are updated. Content updates
|
||||
* include data fills, overwrites, and invalidations, which means that
|
||||
* this probe partially overlaps with other probes.
|
||||
*/
|
||||
ProbePointArg<CacheDataUpdateProbeArg> *ppDataUpdate;
|
||||
|
||||
public:
|
||||
|
||||
/** Accessor functions */
|
||||
|
||||
bool inCache(Addr addr, bool is_secure) const override
|
||||
{
|
||||
return cacheCntrl->inCache(addr, is_secure);
|
||||
}
|
||||
|
||||
bool hasBeenPrefetched(Addr addr, bool is_secure) const override
|
||||
{
|
||||
return cacheCntrl->hasBeenPrefetched(addr, is_secure);
|
||||
}
|
||||
|
||||
bool hasBeenPrefetched(Addr addr, bool is_secure,
|
||||
RequestorID requestor) const override
|
||||
{
|
||||
return cacheCntrl->hasBeenPrefetched(addr, is_secure, requestor);
|
||||
}
|
||||
|
||||
bool inMissQueue(Addr addr, bool is_secure) const override
|
||||
{
|
||||
return cacheCntrl->inMissQueue(addr, is_secure);
|
||||
}
|
||||
|
||||
bool coalesce() const override
|
||||
{ return cacheCntrl->coalesce(); }
|
||||
|
||||
};
|
||||
|
||||
} // namespace ruby
|
||||
} // namespace gem5
|
||||
|
||||
#endif // __MEM_RUBY_STRUCTURES_RUBY_PREFETCHER_WRAPPER_HH__
|
||||
@@ -1,6 +1,6 @@
|
||||
# -*- mode:python -*-
|
||||
|
||||
# Copyright (c) 2021 ARM Limited
|
||||
# Copyright (c) 2021,2023 ARM Limited
|
||||
# All rights reserved.
|
||||
#
|
||||
# The license below extends only to copyright in the software and shall
|
||||
@@ -53,6 +53,7 @@ Source('CacheMemory.cc')
|
||||
Source('WireBuffer.cc')
|
||||
Source('PersistentTable.cc')
|
||||
Source('RubyPrefetcher.cc')
|
||||
Source('RubyPrefetcherProxy.cc')
|
||||
Source('TimerTable.cc')
|
||||
Source('BankedArray.cc')
|
||||
Source('TBEStorage.cc')
|
||||
|
||||
@@ -63,6 +63,7 @@ python_class_map = {
|
||||
"MessageBuffer": "MessageBuffer",
|
||||
"DMASequencer": "DMASequencer",
|
||||
"RubyPrefetcher": "RubyPrefetcher",
|
||||
"prefetch::Base": "BasePrefetcher",
|
||||
"Cycles": "Cycles",
|
||||
"Addr": "Addr",
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user