46#include "debug/MemTest.hh"
75 if (!
port.sendTimingReq(pkt)) {
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",
226 "number of read accesses completed"),
228 "number of write accesses completed"),
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(),
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(),
341 bool keep_ticking =
true;
344 port.sendFunctional(pkt);
ClockedObject(const ClockedObjectParams &p)
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.
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()
Ports are used to interface objects to each other.
@ ATOMIC_RETURN_OP
The request is an atomic that returns data.
@ UNCACHEABLE
The request is to an uncacheable address.
gem5::Flags< FlagsType > Flags
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
std::unique_ptr< AtomicOpFunctor > AtomicOpFunctorPtr
void deschedule(Event &event)
void schedule(Event &event, Tick when)
void reschedule(Event &event, Tick when, bool always=false)
void set(Type mask)
Set all flag's bits matching the given mask.
#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)
The "old style" exitSimLoop functions.
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()