52 cacheLineSize(params.
system->cacheLineSize()),
55 instRequestorID(params.
system->getRequestorId(this,
"inst")),
56 dataRequestorID(params.
system->getRequestorId(this,
"data")),
57 instTraceFile(params.instTraceFile),
58 dataTraceFile(params.dataTraceFile),
59 icacheGen(*this,
".iside", icachePort, instRequestorID, instTraceFile),
60 dcacheGen(*this,
".dside", dcachePort, dataRequestorID, dataTraceFile,
63 dcacheNextEvent([
this]{ schedDcacheNext(); },
name()),
64 oneTraceComplete(
false),
66 execCompleteEvent(
nullptr),
67 enableEarlyExit(params.enableEarlyExit),
68 progressMsgInterval(params.progressMsgInterval),
69 progressMsgThreshold(params.progressMsgInterval), traceStats(
this)
76 fatal_if(params.sizeROB > UINT16_MAX,
77 "ROB size set to %d exceeds the max. value of %d.",
78 params.sizeROB, UINT16_MAX);
79 fatal_if(params.sizeStoreBuffer > UINT16_MAX,
80 "ROB size set to %d exceeds the max. value of %d.",
81 params.sizeROB, UINT16_MAX);
82 fatal_if(params.sizeLoadBuffer > UINT16_MAX,
83 "Load buffer size set to %d exceeds the max. value of %d.",
84 params.sizeLoadBuffer, UINT16_MAX);
101 DPRINTF(TraceCPUInst,
"Instruction fetch request trace file is \"%s\".\n",
103 DPRINTF(TraceCPUData,
"Data memory request trace file is \"%s\".\n",
115 traceOffset = std::min(first_icache_tick, first_dcache_tick);
116 inform(
"%s: Time offset (tick) found as min of both traces is %lli.",
144 DPRINTF(TraceCPUInst,
"IcacheGen event.\n");
151 "Scheduling next icacheGen event at %d.\n",
170 DPRINTF(TraceCPUData,
"DcacheGen event.\n");
202 statistics::
Group(trace),
203 ADD_STAT(numSchedDcacheEvent, statistics::units::Count::get(),
204 "Number of events scheduled to trigger data request generator"),
205 ADD_STAT(numSchedIcacheEvent, statistics::units::Count::get(),
206 "Number of events scheduled to trigger instruction request "
208 ADD_STAT(numOps, statistics::units::Count::get(),
209 "Number of micro-ops simulated by the Trace CPU"),
210 ADD_STAT(cpi, statistics::units::Rate<
211 statistics::units::Cycle, statistics::units::Count>::get(),
212 "Cycles per micro-op used as a proxy for CPI",
213 trace->traceStats.numCycles / numOps)
220 const std::string&
_name) :
222 ADD_STAT(maxDependents, statistics::units::Count::get(),
223 "Max number of dependents observed on a node"),
224 ADD_STAT(maxReadyListSize, statistics::units::Count::get(),
225 "Max size of the ready list observed"),
226 ADD_STAT(numSendAttempted, statistics::units::Count::get(),
227 "Number of first attempts to send a request"),
228 ADD_STAT(numSendSucceeded, statistics::units::Count::get(),
229 "Number of successful first attempts"),
230 ADD_STAT(numSendFailed, statistics::units::Count::get(),
231 "Number of failed first attempts"),
232 ADD_STAT(numRetrySucceeded, statistics::units::Count::get(),
233 "Number of successful retries"),
234 ADD_STAT(numSplitReqs, statistics::units::Count::get(),
235 "Number of split requests"),
236 ADD_STAT(numSOLoads, statistics::units::Count::get(),
237 "Number of strictly ordered loads"),
238 ADD_STAT(numSOStores, statistics::units::Count::get(),
239 "Number of strictly ordered stores"),
241 "Last tick simulated from the elastic data trace")
248 DPRINTF(TraceCPUData,
"Initializing data memory request generator "
249 "DcacheGen: elastic issue with retry.\n");
252 "Trace has %d elements. It must have at least %d elements.",
254 DPRINTF(TraceCPUData,
"After 1st read, depGraph size:%d.\n",
258 "Trace has %d elements. It must have at least %d elements.",
260 DPRINTF(TraceCPUData,
"After 2st read, depGraph size:%d.\n",
264 if (debug::TraceCPUData) {
269 "Execute tick of the first dependency free node %lli is %d.\n",
270 free_itr->seqNum, free_itr->execTick);
273 return (free_itr->execTick);
280 free_node.execTick -=
offset;
294 DPRINTF(TraceCPUData,
"Reading next window from file.\n");
302 DPRINTF(TraceCPUData,
"Start read: Size of depGraph is %d.\n",
305 uint32_t num_read = 0;
315 DPRINTF(TraceCPUData,
"\tTrace complete!\n");
329 if (new_node->
robDep.empty() && new_node->
regDep.empty()) {
337 DPRINTF(TraceCPUData,
"End read: Size of depGraph is %d.\n",
346 auto dep_it = dep_list.begin();
347 while (dep_it != dep_list.end()) {
349 auto parent_itr =
depGraph.find(*dep_it);
354 parent_itr->second->dependents.push_back(new_node);
355 auto num_depts = parent_itr->second->dependents.size();
363 dep_it = dep_list.erase(dep_it);
371 DPRINTF(TraceCPUData,
"Execute start occupancy:\n");
372 DPRINTFR(TraceCPUData,
"\tdepGraph = %d, readyList = %d, "
390 "Removing from depFreeQueue: seq. num %lli.\n",
405 graph_itr =
depGraph.find(free_itr->seqNum);
406 assert(graph_itr !=
depGraph.end());
414 panic(
"Retry packet's seqence number does not match "
415 "the first node in the readyList.\n");
445 "Node seq. num %lli sent. Waking up dependents..\n",
448 auto child_itr = (node_ptr->
dependents).begin();
449 while (child_itr != (node_ptr->
dependents).end()) {
452 if (!(*child_itr)->isStore() &&
453 (*child_itr)->removeRobDep(node_ptr->
seqNum)) {
456 if ((*child_itr)->robDep.empty() &&
457 (*child_itr)->regDep.empty()) {
465 child_itr = node_ptr->
dependents.erase(child_itr);
476 DPRINTF(TraceCPUData,
"Node seq. num %lli done. Waking"
477 " up dependents..\n", node_ptr->
seqNum);
482 if (child->removeDepOnInst(node_ptr->
seqNum)) {
516 if (debug::TraceCPUData) {
518 DPRINTF(TraceCPUData,
"Execute end occupancy:\n");
519 DPRINTFR(TraceCPUData,
"\tdepGraph = %d, readyList = %d, "
526 DPRINTF(TraceCPUData,
"Not scheduling an event as expecting a retry"
527 "event from the cache for seq. num %lli.\n",
544 DPRINTF(TraceCPUData,
"Attempting to schedule @%lli.\n",
549 DPRINTF(TraceCPUData,
"Attempting to schedule @%lli.\n",
558 DPRINTF(TraceCPUData,
"\tExecution Complete!\n");
567 DPRINTF(TraceCPUData,
"Executing memory request %lli (phys addr %d, "
568 "virt addr %d, pc %#x, size %d, flags %d).\n",
577 DPRINTF(TraceCPUData,
"Skipping strictly ordered request %lli.\n",
590 if (!(blk_offset + node_ptr->
size <= blk_size)) {
591 node_ptr->
size = blk_size - blk_offset;
596 auto req = std::make_shared<Request>(
598 req->setReqInstSeqNum(node_ptr->
seqNum);
603 req->setPC(node_ptr->
pc);
610 req->setReqInstSeqNum(node_ptr->
seqNum);
614 uint8_t* pkt_data =
new uint8_t[req->getSize()];
619 memset(pkt_data, 0xA, req->getSize());
631 DPRINTF(TraceCPUData,
"Send failed. Saving packet for retry.\n");
644 assert(node_ptr->
robDep.empty() && node_ptr->
regDep.empty());
648 DPRINTFR(TraceCPUData,
"\t\tseq. num %lli(%s) with rob num %lli is now"
656 DPRINTFR(TraceCPUData,
"\t\tResources available for seq. num %lli. "
657 "Adding to readyList, occupying resources.\n",
669 DPRINTFR(TraceCPUData,
"\t\tResources unavailable for seq. num "
670 "%lli. Adding to depFreeQueue.\n", node_ptr->
seqNum);
673 DPRINTFR(TraceCPUData,
"\t\tResources unavailable for seq. num "
674 "%lli. Still pending issue.\n", node_ptr->
seqNum);
694 auto graph_itr =
depGraph.find(pkt->
req->getReqInstSeqNum());
695 assert(graph_itr !=
depGraph.end());
701 DPRINTF(TraceCPUData,
"Load seq. num %lli response received. Waking up"
702 " dependents..\n", node_ptr->
seqNum);
705 if (child->removeDepOnInst(node_ptr->
seqNum)) {
720 if (debug::TraceCPUData) {
741 DPRINTF(TraceCPUData,
"Attempting to schedule @%lli.\n",
752 ready_node.
seqNum = seq_num;
772 if (
retryPkt->
req->getReqInstSeqNum() == itr->seqNum)
779 while (!found && itr !=
readyList.end()) {
782 if (exec_tick < itr->execTick) {
786 }
else if (exec_tick == itr->execTick) {
789 if (seq_num < itr->seqNum) {
812 DPRINTF(TraceCPUData,
"readyList is empty.\n");
815 DPRINTF(TraceCPUData,
"Printing readyList:\n");
817 auto graph_itr =
depGraph.find(itr->seqNum);
818 [[maybe_unused]]
GraphNode* node_ptr = graph_itr->second;
819 DPRINTFR(TraceCPUData,
"\t%lld(%s), %lld\n", itr->seqNum,
826 uint16_t max_rob, uint16_t max_stores, uint16_t max_loads) :
828 sizeStoreBuffer(max_stores),
829 sizeLoadBuffer(max_loads),
830 oldestInFlightRobNum(UINT64_MAX),
842 oldestInFlightRobNum = inFlightNodes.begin()->second;
847 }
else if (new_node->
isStore()) {
857 assert(!inFlightNodes.empty());
859 "\tClearing done seq. num %d from inFlightNodes..\n",
862 assert(inFlightNodes.find(done_node->
seqNum) != inFlightNodes.end());
863 inFlightNodes.erase(done_node->
seqNum);
865 if (inFlightNodes.empty()) {
868 oldestInFlightRobNum = UINT64_MAX;
872 oldestInFlightRobNum = inFlightNodes.begin()->second;
876 "\tCleared. inFlightNodes.size() = %d, "
877 "oldestInFlightRobNum = %d\n", inFlightNodes.size(),
878 oldestInFlightRobNum);
884 if (done_node->
isLoad()) {
885 assert(numInFlightLoads != 0);
893 releaseStoreBuffer();
900 assert(numInFlightStores != 0);
908 uint16_t num_in_flight_nodes;
909 if (inFlightNodes.empty()) {
910 num_in_flight_nodes = 0;
911 DPRINTFR(TraceCPUData,
"\t\tChecking resources to issue seq. num %lli:"
912 " #in-flight nodes = 0", new_node->
seqNum);
913 }
else if (new_node->
robNum > oldestInFlightRobNum) {
917 num_in_flight_nodes = new_node->
robNum - oldestInFlightRobNum;
918 DPRINTFR(TraceCPUData,
"\t\tChecking resources to issue seq. num %lli:"
919 " #in-flight nodes = %d - %d = %d", new_node->
seqNum,
920 new_node->
robNum, oldestInFlightRobNum, num_in_flight_nodes);
927 num_in_flight_nodes = 0;
928 DPRINTFR(TraceCPUData,
"\t\tChecking resources to issue seq. num %lli:"
929 " new oldestInFlightRobNum = %d, #in-flight nodes ignored",
932 DPRINTFR(TraceCPUData,
", LQ = %d/%d, SQ = %d/%d.\n",
933 numInFlightLoads, sizeLoadBuffer,
934 numInFlightStores, sizeStoreBuffer);
936 if (num_in_flight_nodes >= sizeROB) {
939 if (new_node->
isLoad() && numInFlightLoads >= sizeLoadBuffer) {
942 if (new_node->
isStore() && numInFlightStores >= sizeStoreBuffer) {
952 return (numInFlightStores != 0 || numInFlightLoads != 0);
958 DPRINTFR(TraceCPUData,
"oldestInFlightRobNum = %d, "
959 "LQ = %d/%d, SQ = %d/%d.\n",
960 oldestInFlightRobNum,
961 numInFlightLoads, sizeLoadBuffer,
962 numInFlightStores, sizeStoreBuffer);
968 ADD_STAT(numSendAttempted, statistics::units::Count::get(),
969 "Number of first attempts to send a request"),
970 ADD_STAT(numSendSucceeded, statistics::units::Count::get(),
971 "Number of successful first attempts"),
972 ADD_STAT(numSendFailed, statistics::units::Count::get(),
973 "Number of failed first attempts"),
974 ADD_STAT(numRetrySucceeded, statistics::units::Count::get(),
975 "Number of successful retries"),
977 "Last tick simulated from the fixed inst trace")
985 DPRINTF(TraceCPUInst,
"Initializing instruction fetch request generator"
986 " IcacheGen: fixed issue with retry.\n");
992 panic(
"Read of first message in the trace failed.\n");
1002 DPRINTF(TraceCPUInst,
"Trying to send retry packet.\n");
1006 DPRINTF(TraceCPUInst,
"Retry packet sending failed.\n");
1011 DPRINTF(TraceCPUInst,
"Trying to send packet for currElement.\n");
1020 DPRINTF(TraceCPUInst,
"currElement sending failed.\n");
1031 DPRINTF(TraceCPUInst,
"Packet sent successfully, trying to read next "
1071 DPRINTF(TraceCPUInst,
"inst fetch: %c addr %d pc %#x size %d tick %d\n",
1096 uint8_t* pkt_data =
new uint8_t[req->getSize()];
1100 memset(pkt_data, 0xA, req->getSize());
1118 DPRINTF(TraceCPUInst,
"Icache retry received. Scheduling next IcacheGen"
1119 " event @%lli.\n",
curTick());
1128 DPRINTF(TraceCPUData,
"Dcache retry received. Scheduling next DcacheGen"
1129 " event @%lli.\n",
curTick());
1137 DPRINTF(TraceCPUData,
"Scheduling next DcacheGen event at %lli.\n",
1142 DPRINTF(TraceCPUData,
"Re-scheduling next dcache event from %lli"
1155 if (if_name ==
"dcache_port")
1157 else if (if_name ==
"icache_port")
1182 DPRINTF(TraceCPUData,
"Received timing response from Dcache.\n");
1206 const std::string& filename,
const double time_multiplier) :
1208 timeMultiplier(time_multiplier),
1212 ProtoMessage::InstDepRecordHeader header_msg;
1214 panic(
"Failed to read packet header from %s\n", filename);
1217 panic(
"Trace %s was recorded with a different tick frequency %d\n",
1218 header_msg.tick_freq());
1236 ProtoMessage::InstDepRecord pkt_msg;
1239 element->
seqNum = pkt_msg.seq_num();
1240 element->
type = pkt_msg.type();
1242 element->
compDelay = pkt_msg.comp_delay() * timeMultiplier;
1246 for (
int i = 0;
i < (pkt_msg.rob_dep()).size();
i++) {
1247 element->
robDep.push_back(pkt_msg.rob_dep(
i));
1252 for (
int i = 0;
i < (pkt_msg.reg_dep()).size();
i++) {
1256 bool duplicate =
false;
1257 for (
auto &dep: element->
robDep) {
1258 duplicate |= (pkt_msg.reg_dep(
i) == dep);
1261 element->
regDep.push_back(pkt_msg.reg_dep(
i));
1265 if (pkt_msg.has_p_addr())
1266 element->
physAddr = pkt_msg.p_addr();
1270 if (pkt_msg.has_v_addr())
1271 element->
virtAddr = pkt_msg.v_addr();
1275 if (pkt_msg.has_size())
1276 element->
size = pkt_msg.size();
1280 if (pkt_msg.has_flags())
1281 element->
flags = pkt_msg.flags();
1285 if (pkt_msg.has_pc())
1286 element->
pc = pkt_msg.pc();
1292 if (pkt_msg.has_weight()) {
1293 microOpCount += pkt_msg.weight();
1295 element->
robNum = microOpCount;
1306 for (
auto it = regDep.begin(); it != regDep.end(); it++) {
1307 if (*it == reg_dep) {
1311 "\tFor %lli: Marking register dependency %lli done.\n",
1324 for (
auto it = robDep.begin(); it != robDep.end(); it++) {
1325 if (*it == rob_dep) {
1329 "\tFor %lli: Marking ROB dependency %lli done.\n",
1341 if (!removeRobDep(done_seq_num)) {
1345 [[maybe_unused]]
bool regdep_found = removeRegDep(done_seq_num);
1346 assert(regdep_found);
1349 return robDep.empty() && regDep.empty();
1356 DPRINTFR(TraceCPUData,
"%lli", seqNum);
1357 DPRINTFR(TraceCPUData,
",%s", typeToStr());
1358 if (isLoad() || isStore()) {
1360 DPRINTFR(TraceCPUData,
",%i", size);
1363 DPRINTFR(TraceCPUData,
",%lli", compDelay);
1365 for (
auto &dep: robDep) {
1366 DPRINTFR(TraceCPUData,
",%lli", dep);
1369 for (
auto &dep: regDep) {
1370 DPRINTFR(TraceCPUData,
",%lli", dep);
1372 auto child_itr = dependents.begin();
1373 DPRINTFR(TraceCPUData,
"dependents:");
1374 while (child_itr != dependents.end()) {
1375 DPRINTFR(TraceCPUData,
":%lli", (*child_itr)->seqNum);
1386 return Record::RecordType_Name(
type);
1393 ProtoMessage::PacketHeader header_msg;
1395 panic(
"Failed to read packet header from %s\n", filename);
1398 panic(
"Trace %s was recorded with a different tick frequency %d\n",
1399 header_msg.tick_freq());
1413 ProtoMessage::Packet pkt_msg;
1415 element->
cmd = pkt_msg.
cmd();
1416 element->
addr = pkt_msg.addr();
1418 element->
tick = pkt_msg.tick();
1419 element->
flags = pkt_msg.has_flags() ? pkt_msg.flags() : 0;
1420 element->
pc = pkt_msg.has_pc() ? pkt_msg.pc() : 0;
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...
Cycles is a wrapper class for representing cycle counts, i.e.
virtual std::string name() const
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
static PacketPtr createWrite(const RequestPtr &req)
static PacketPtr createRead(const RequestPtr &req)
Constructor-like methods that return Packets based on Request objects.
RequestPtr req
A pointer to the original request.
void dataDynamic(T *p)
Set the data pointer to a value that should have delete [] called on it.
Ports are used to interface objects to each other.
bool sendTimingReq(PacketPtr pkt)
Attempt to send a timing request to the responder port by calling its corresponding receive function.
bool recvTimingResp(PacketPtr pkt)
Receive the timing reponse and call dcacheRecvTimingResp() method of the dcacheGen to handle completi...
void recvReqRetry()
Handle a retry signalled by the cache if data access failed in the first attempt.
The struct GraphNode stores an instruction in the trace file.
bool isLoad() const
Is the node a load.
RecordType type
Type of the node corresponding to the instruction modeled by it.
bool isStrictlyOrdered() const
Return true if node has a request which is strictly ordered.
bool removeDepOnInst(NodeSeqNum done_seq_num)
Check for all dependencies on completed inst.
std::vector< GraphNode * > dependents
A vector of nodes dependent (outgoing) on this node.
bool removeRobDep(NodeSeqNum rob_dep)
Remove completed instruction from order dependency array.
Request::Flags flags
Request flags if any.
RegDepList regDep
List of register dependencies (incoming) if any.
uint32_t size
Size of request if any.
NodeRobNum robNum
ROB occupancy number.
std::string typeToStr() const
Return string specifying the type of the node.
void writeElementAsTrace() const
Write out element in trace-compatible format using debug flag TraceCPUData.
RobDepList robDep
List of order dependencies.
Addr physAddr
The address for the request if any.
Addr virtAddr
The virtual address for the request if any.
bool isStore() const
Is the node a store.
uint64_t compDelay
Computational delay.
NodeSeqNum seqNum
Instruction sequence number.
bool removeRegDep(NodeSeqNum reg_dep)
Remove completed instruction from register dependency array.
void occupy(const GraphNode *new_node)
Occupy appropriate structures for an issued node.
void release(const GraphNode *done_node)
Release appropriate structures for a completed node.
bool awaitingResponse() const
Check if there are any outstanding requests, i.e.
void printOccupancy()
Print resource occupancy for debugging.
HardwareResource(uint16_t max_rob, uint16_t max_stores, uint16_t max_loads)
Constructor that initializes the sizes of the structures.
void releaseStoreBuffer()
Release store buffer entry for a completed store.
bool isAvailable(const GraphNode *new_node) const
Check if structures required to issue a node are free.
const uint32_t windowSize
Window size within which to check for dependencies.
bool readNextWindow()
Reads a line of the trace file.
PacketPtr executeMemReq(GraphNode *node_ptr)
Creates a new request for a load or store assigning the request parameters.
void printReadyList()
Print readyList for debugging using debug flag TraceCPUData.
bool isExecComplete() const
Returns the execComplete variable which is set when the last node is executed.
TraceCPU & owner
Reference of the TraceCPU.
const RequestorID requestorId
RequestorID used for the requests being sent.
Tick init()
Called from TraceCPU init().
uint64_t NodeSeqNum
Node sequence number type.
void adjustInitTraceOffset(Tick &offset)
Adjust traceOffset based on what TraceCPU init() determines on comparing the offsets in the fetch req...
bool checkAndIssue(const GraphNode *node_ptr, bool first=true)
Attempts to issue a node once the node's source dependencies are complete.
std::list< ReadyNode > readyList
List of nodes that are ready to execute.
PacketPtr retryPkt
PacketPtr used to store the packet to retry.
bool traceComplete
Set to true when end of trace is reached.
void exit()
Exit the ElasticDataGen.
bool nextRead
Set to true when the next window of instructions need to be read.
std::queue< const GraphNode * > depFreeQueue
Queue of dependency-free nodes that are pending issue because resources are not available.
gem5::TraceCPU::ElasticDataGen::ElasticDataGenStatGroup elasticStats
std::unordered_map< NodeSeqNum, GraphNode * > depGraph
Store the depGraph of GraphNodes.
void addDepsOnParent(GraphNode *new_node, T &dep_list)
Iterate over the dependencies of a new node and add the new node to the list of dependents of the par...
bool execComplete
Set true when execution of trace is complete.
RequestPort & port
Reference of the port to be used to issue memory requests.
HardwareResource hwResource
Hardware resources required to contain in-flight nodes and to throttle issuing of new nodes when reso...
void addToSortedReadyList(NodeSeqNum seq_num, Tick exec_tick)
Add a ready node to the readyList.
InputStream trace
Input stream used for reading the input trace file.
void execute()
This is the main execute function which consumes nodes from the sorted readyList.
void completeMemAccess(PacketPtr pkt)
When a load writeback is received, that is when the load completes, release the dependents on it.
TraceCPU & owner
Reference of the TraceCPU.
int64_t delta
Stores the difference in the send ticks of the current and last packets.
Tick init()
Called from TraceCPU init().
const RequestorID requestorId
RequestorID used for the requests being sent.
gem5::TraceCPU::FixedRetryGen::FixedRetryGenStatGroup fixedStats
TraceElement currElement
Store an element read from the trace to send as the next packet.
bool nextExecute()
Reads a line of the trace file.
bool traceComplete
Set to true when end of trace is reached.
PacketPtr retryPkt
PacketPtr used to store the packet to retry.
bool isTraceComplete()
Returns the traceComplete variable which is set when end of the input trace file is reached.
void exit()
Exit the FixedRetryGen.
RequestPort & port
Reference of the port to be used to issue memory requests.
InputStream trace
Input stream used for reading the input trace file.
bool send(Addr addr, unsigned size, const MemCmd &cmd, Request::FlagsType flags, Addr pc)
Creates a new request assigning the request parameters passed by the arguments.
bool tryNext()
This tries to send current or retry packet and returns true if successfull.
void recvReqRetry()
Handle a retry signalled by the cache if instruction read failed in the first attempt.
bool recvTimingResp(PacketPtr pkt)
Receive the timing reponse and simply delete the packet since instruction fetch requests are issued a...
The trace cpu replays traces generated using the elastic trace probe attached to the O3 CPU model.
const uint64_t progressMsgInterval
Interval of committed instructions specified by the user at which a progress info message is printed.
Port & getDataPort()
Used to get a reference to the dcache port.
const bool enableEarlyExit
Exit when any one Trace CPU completes its execution.
bool oneTraceComplete
Set to true when one of the generators finishes replaying its trace.
void dcacheRetryRecvd()
When data cache port receives a retry, schedule event dcacheNextEvent.
Port & getInstPort()
Used to get a reference to the icache port.
Tick traceOffset
This stores the time offset in the trace, which is taken away from the ready times of requests.
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
gem5::TraceCPU::TraceStats traceStats
ElasticDataGen dcacheGen
Instance of ElasticDataGen to replay data read and write requests.
std::string instTraceFile
File names for input instruction and data traces.
FixedRetryGen icacheGen
Instance of FixedRetryGen to replay instruction read requests.
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port on this CPU.
TraceCPU(const TraceCPUParams ¶ms)
void updateNumOps(uint64_t rob_num)
std::string dataTraceFile
uint64_t progressMsgThreshold
const Addr cacheLineSize
Cache the cache line size that we get from the system.
void dcacheRecvTimingResp(PacketPtr pkt)
When data cache port receives a response, this calls the dcache generator method handle to complete t...
void icacheRetryRecvd()
When instruction cache port receives a retry, schedule event icacheNextEvent.
EventFunctionWrapper dcacheNextEvent
Event for the control flow method schedDcacheNext()
static int numTraceCPUs
Number of Trace CPUs in the system used as a shared variable and passed to the CountedExitEvent event...
EventFunctionWrapper icacheNextEvent
Event for the control flow method schedIcacheNext()
void schedDcacheNextEvent(Tick when)
Schedule event dcacheNextEvent at the given tick.
CountedExitEvent * execCompleteEvent
A CountedExitEvent which when serviced decrements the counter.
void checkAndSchedExitEvent()
This is called when either generator finishes executing from the trace.
void schedDcacheNext()
This is the control flow that uses the functionality of the dcacheGen to replay the trace.
void schedIcacheNext()
This is the control flow that uses the functionality of the icacheGen to replay the trace.
Derived & precision(int _precision)
Set the precision and marks this stat to print at the end of simulation.
Counter value() const
Return the current value of this stat as its base type.
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
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)
Tick when() const
Get the time that the event is scheduled.
#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.
virtual void init()
init() is called after all C++ SimObjects have been created and all ports are connected.
Tick Frequency
The simulated frequency of curTick(). (In ticks per second)
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
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.
uint64_t Tick
Tick count type.
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 (...
int ContextID
Globally unique thread context ID.
statistics::Scalar numSplitReqs
statistics::Scalar numSendFailed
statistics::Scalar maxDependents
Stats for data memory accesses replayed.
statistics::Scalar numRetrySucceeded
statistics::Scalar numSendSucceeded
statistics::Scalar dataLastTick
Tick when ElasticDataGen completes execution.
ElasticDataGenStatGroup(statistics::Group *parent, const std::string &_name)
name is the extension to the name for these stats
statistics::Scalar numSOLoads
statistics::Scalar numSendAttempted
statistics::Scalar numSOStores
statistics::Scalar maxReadyListSize
Struct to store a ready-to-execute node and its execution tick.
Tick execTick
The tick at which the ready node must be executed.
NodeSeqNum seqNum
The sequence number of the ready node.
statistics::Scalar numSendFailed
statistics::Scalar numSendSucceeded
statistics::Scalar numSendAttempted
Stats for instruction accesses replayed.
FixedRetryGenStatGroup(statistics::Group *parent, const std::string &_name)
name is the extension to the name for these stats
statistics::Scalar numRetrySucceeded
statistics::Scalar instLastTick
Last simulated tick by the FixedRetryGen.
This struct stores a line in the trace file.
void clear()
Make this element invalid.
MemCmd cmd
Specifies if the request is to be a read or a write.
Addr addr
The address for the request.
Addr blocksize
The size of the access for the request.
Request::FlagsType flags
Potential request flags to use.
Tick tick
The time at which the request should be sent.
bool isValid() const
Check validity of this element.
statistics::Scalar numSchedDcacheEvent
statistics::Scalar numSchedIcacheEvent
statistics::Formula cpi
Stat for the CPI.
statistics::Scalar numCycles
Number of CPU cycles simulated.
TraceStats(TraceCPU *trace)
statistics::Scalar numOps
Stat for number of simulated micro-ops.
const std::string & name()