46#include "debug/MemTest.hh"
86 noRequestEvent([
this]{ noRequest(); },
name()),
87 noResponseEvent([
this]{ noResponse(); },
name()),
93 percentReads(
p.percent_reads),
94 percentFunctional(
p.percent_functional),
95 percentUncacheable(
p.percent_uncacheable),
96 percentAtomic(
p.percent_atomic),
97 requestorId(
p.system->getRequestorId(
this)),
98 blockSize(
p.system->cacheLineSize()),
99 blockAddrMask(blockSize - 1),
100 sizeBlocks(size / blockSize),
101 baseAddr1(
p.base_addr_1),
102 baseAddr2(
p.base_addr_2),
103 uncacheAddr(
p.uncacheable_base_addr),
104 progressInterval(
p.progress_interval),
105 progressCheck(
p.progress_check),
106 nextProgressMessage(
p.progress_interval),
107 maxLoads(
p.max_loads),
108 atomic(
p.system->isAtomicMode()),
109 suppressFuncErrors(
p.suppress_func_errors), stats(
this)
112 fatal_if(
id >= blockSize,
"Too many testers, only %d allowed\n",
121 schedule(tickEvent,
curTick());
122 schedule(noRequestEvent, clockEdge(progressCheck));
128 if (if_name ==
"port")
138 assert(req->getSize() == 1);
148 pkt->
isError() ?
"error" :
"success");
150 const uint8_t *pkt_data = pkt->
getConstPtr<uint8_t>();
154 panic(
"%s access failed at %#x\n",
155 pkt->
isWrite() ?
"Write" :
"Read", req->getPaddr());
159 if (pkt_data[0] != ref_data) {
160 panic(
"%s: read of %x (blk %x) @ cycle %d "
161 "returns %x, expected %x\n",
name(),
163 pkt_data[0], ref_data);
166 "Completing atomic at address %x (blk %x) value %x\n",
175 }
else if (pkt->
isRead()) {
177 if (pkt_data[0] != ref_data) {
178 panic(
"%s: read of %x (blk %x) @ cycle %d "
179 "returns %x, expected %x\n",
name(),
181 pkt_data[0], ref_data);
189 "%s: completed %d read, %d write, "
190 "%d atomic accesses @%d\n",
224 : statistics::
Group(parent),
225 ADD_STAT(numReads, statistics::units::Count::get(),
226 "number of read accesses completed"),
227 ADD_STAT(numWrites, statistics::units::Count::get(),
228 "number of write accesses completed"),
229 ADD_STAT(numAtomics, statistics::units::Count::get(),
230 "number of atomic accesses completed")
243 unsigned cmd =
rng->random(0, 100);
244 uint8_t
data =
rng->random<uint8_t>();
248 unsigned base =
rng->random(0, 1);
284 "Tester %s has more than 100 outstanding requests\n",
name());
287 uint8_t *pkt_data =
new uint8_t[1];
292 [[maybe_unused]] uint8_t ref_data = 0;
297 ref_data = ref->second;
301 "Initiating %sread at addr %x (blk %x) expecting %x\n",
302 do_functional ?
"functional " :
"", req->getPaddr(),
306 pkt->dataDynamic(pkt_data);
310 "Initiating atomic at addr %x (blk %x) value %x\n",
316 [](uint8_t*
b, uint8_t
a, uint8_t
c){
321 req->setAtomicOpFunctor(std::move(amo_op));
330 "Initiating %swrite at addr %x (blk %x) value %x\n",
331 do_functional ?
"functional " :
"", req->getPaddr(),
335 pkt->dataDynamic(pkt_data);
341 bool keep_ticking =
true;
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
Tick clockEdge(Cycles cycles=Cycles(0)) const
Determine the tick when a cycle begins, by default the current one, but the argument also enables the...
void recvReqRetry()
Called by the peer if sendTimingReq was called on this peer (causing recvTimingReq to be called on th...
bool recvTimingResp(PacketPtr pkt)
Receive a timing response from the peer.
The MemTest class tests a cache coherent memory system by generating false sharing and verifying the ...
EventFunctionWrapper tickEvent
const bool suppressFuncErrors
std::unordered_set< Addr > outstandingAddrs
gem5::MemTest::MemTestStats stats
std::unordered_map< Addr, uint8_t > atomicPendingData
const Cycles progressCheck
const unsigned percentFunctional
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
Addr blockAlign(Addr addr) const
Get the block aligned address.
const unsigned percentAtomic
const unsigned percentReads
void completeRequest(PacketPtr pkt, bool functional=false)
Complete a request by checking the response.
const unsigned progressInterval
std::unordered_map< Addr, uint8_t > referenceData
const unsigned sizeBlocks
EventFunctionWrapper noRequestEvent
EventFunctionWrapper noResponseEvent
RequestorID requestorId
Request id for all generated traffic.
bool sendPkt(PacketPtr pkt)
const unsigned percentUncacheable
virtual std::string name() const
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
RequestPtr req
A pointer to the original request.
const T * getConstPtr() const
void dataDynamic(T *p)
Set the data pointer to a value that should have delete [] called on it.
bool suppressFuncError() const
void setSuppressFuncError()
Tick sendAtomic(PacketPtr pkt)
Send an atomic request packet, where the data is moved and the state is updated in zero time,...
bool sendTimingReq(PacketPtr pkt)
Attempt to send a timing request to the responder port by calling its corresponding receive function.
void sendFunctional(PacketPtr pkt) const
Send a functional request packet, where the data is instantly updated everywhere in the memory system...
@ ATOMIC_RETURN_OP
The request is an atomic that returns data.
@ UNCACHEABLE
The request is to an uncacheable address.
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
std::unique_ptr< AtomicOpFunctor > AtomicOpFunctorPtr
void deschedule(Event &event)
bool scheduled() const
Determine if the current event is scheduled.
void schedule(Event &event, Tick when)
void reschedule(Event &event, Tick when, bool always=false)
#define panic(...)
This implements a cprintf based panic() function.
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
Bitfield< 23, 20 > atomic
Copyright (c) 2024 Arm Limited All rights reserved.
std::shared_ptr< Request > RequestPtr
Tick curTick()
The universal simulation clock.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
void exitSimLoop(const std::string &message, int exit_code, Tick when, Tick repeat, bool serialize)
Schedule an event to exit the simulation loop (returning to Python) at the end of the current cycle (...
static unsigned int TESTER_ALLOCATOR
void ccprintf(cp::Print &print)
Declaration of Statistics objects.
statistics::Scalar numWrites
statistics::Scalar numReads
statistics::Scalar numAtomics
MemTestStats(statistics::Group *parent)
const std::string & name()