35 #include "debug/MemoryAccess.hh"
36 #include "debug/ProtocolTrace.hh"
37 #include "debug/RubySequencer.hh"
38 #include "debug/RubyStats.hh"
40 #include "mem/protocol/PrefetchBit.hh"
41 #include "mem/protocol/RubyAccessMode.hh"
50 RubySequencerParams::create()
56 :
RubyPort(p), m_IncompleteTimes(MachineType_NUM), deadlockCheckEvent(this)
91 int total_outstanding = 0;
95 for (; read != read_end; ++read) {
100 panic(
"Possible Deadlock detected. Aborting!\n"
101 "version: %d request.paddr: 0x%x m_readRequestTable: %d "
102 "current time: %u issue_time: %d difference: %d\n",
m_version,
110 for (; write != write_end; ++write) {
115 panic(
"Possible Deadlock detected. Aborting!\n"
116 "version: %d request.paddr: 0x%x m_writeRequestTable: %d "
117 "current time: %u issue_time: %d difference: %d\n",
m_version,
139 for (
int i = 0;
i < RubyRequestType_NUM;
i++) {
143 for (
int j = 0;
j < MachineType_NUM;
j++) {
149 for (
int i = 0;
i < MachineType_NUM;
i++) {
180 (request_type != RubyRequestType_Locked_RMW_Write)) {
184 return RequestStatus_Aliased;
189 RequestTable::value_type default_entry(line_addr,
192 if ((request_type == RubyRequestType_ST) ||
193 (request_type == RubyRequestType_RMW_Read) ||
194 (request_type == RubyRequestType_RMW_Write) ||
195 (request_type == RubyRequestType_Load_Linked) ||
196 (request_type == RubyRequestType_Store_Conditional) ||
197 (request_type == RubyRequestType_Locked_RMW_Read) ||
198 (request_type == RubyRequestType_Locked_RMW_Write) ||
199 (request_type == RubyRequestType_FLUSH)) {
205 return RequestStatus_Aliased;
211 RequestTable::iterator
i = r.first;
217 return RequestStatus_Aliased;
224 return RequestStatus_Aliased;
231 RequestTable::iterator
i = r.first;
237 return RequestStatus_Aliased;
245 return RequestStatus_Ready;
278 if (request->
m_type == RubyRequestType_Store_Conditional) {
297 }
else if (request->
m_type == RubyRequestType_Load_Linked) {
314 const MachineType respondingMach,
315 bool isExternalHit,
Cycles issuedTime,
316 Cycles initialRequestTime,
317 Cycles forwardRequestTime,
327 if (respondingMach != MachineType_NUM) {
331 if ((issuedTime <= initialRequestTime) &&
332 (initialRequestTime <= forwardRequestTime) &&
333 (forwardRequestTime <= firstResponseTime) &&
334 (firstResponseTime <= completionTime)) {
337 initialRequestTime - issuedTime);
339 forwardRequestTime - initialRequestTime);
341 firstResponseTime - forwardRequestTime);
343 completionTime - firstResponseTime);
352 if (respondingMach != MachineType_NUM) {
361 const bool externalHit,
const MachineType mach,
362 const Cycles initialRequestTime,
363 const Cycles forwardRequestTime,
364 const Cycles firstResponseTime)
376 assert((request->m_type == RubyRequestType_ST) ||
377 (request->m_type == RubyRequestType_ATOMIC) ||
378 (request->m_type == RubyRequestType_RMW_Read) ||
379 (request->m_type == RubyRequestType_RMW_Write) ||
380 (request->m_type == RubyRequestType_Load_Linked) ||
381 (request->m_type == RubyRequestType_Store_Conditional) ||
382 (request->m_type == RubyRequestType_Locked_RMW_Read) ||
383 (request->m_type == RubyRequestType_Locked_RMW_Write) ||
384 (request->m_type == RubyRequestType_FLUSH));
399 if (request->m_type == RubyRequestType_Locked_RMW_Read) {
406 }
else if (request->m_type == RubyRequestType_Locked_RMW_Write) {
410 hitCallback(request, data, success, mach, externalHit,
411 initialRequestTime, forwardRequestTime, firstResponseTime);
416 bool externalHit,
const MachineType mach,
417 Cycles initialRequestTime,
418 Cycles forwardRequestTime,
431 assert((request->m_type == RubyRequestType_LD) ||
432 (request->m_type == RubyRequestType_IFETCH));
434 hitCallback(request, data,
true, mach, externalHit,
435 initialRequestTime, forwardRequestTime, firstResponseTime);
441 const MachineType mach,
const bool externalHit,
442 const Cycles initialRequestTime,
443 const Cycles forwardRequestTime,
444 const Cycles firstResponseTime)
446 warn_once(
"Replacement policy updates recently became the responsibility "
447 "of SLICC state machines. Make sure to setMRU() near callbacks "
460 initialRequestTime, forwardRequestTime,
463 DPRINTFR(ProtocolTrace,
"%15s %3s %10s%20s %6s>%-6s %#x %d cycles\n",
465 llscSuccess ?
"Done" :
"SC_Failed",
"",
"",
473 if ((type == RubyRequestType_LD) ||
474 (type == RubyRequestType_IFETCH) ||
475 (type == RubyRequestType_RMW_Read) ||
476 (type == RubyRequestType_Locked_RMW_Read) ||
477 (type == RubyRequestType_Load_Linked)) {
478 memcpy(pkt->
getPtr<uint8_t>(),
481 DPRINTF(RubySequencer,
"read data %s\n", data);
484 memcpy(&overwrite_val[0], pkt->
getConstPtr<uint8_t>(),
486 memcpy(pkt->
getPtr<uint8_t>(),
489 data.
setData(&overwrite_val[0],
491 DPRINTF(RubySequencer,
"swap data %s\n", data);
492 }
else if (type != RubyRequestType_Store_Conditional || llscSuccess) {
497 DPRINTF(RubySequencer,
"set data %s\n", data);
505 DPRINTF(RubySequencer,
"hitCallback %s 0x%x using RubyTester\n",
509 assert(testerSenderState);
510 testerSenderState->subBlock.mergeFrom(data);
540 return RequestStatus_BufferFull;
543 RubyRequestType primary_type = RubyRequestType_NULL;
544 RubyRequestType secondary_type = RubyRequestType_NULL;
556 DPRINTF(RubySequencer,
"Issuing SC\n");
557 primary_type = RubyRequestType_Store_Conditional;
559 DPRINTF(RubySequencer,
"Issuing LL\n");
561 primary_type = RubyRequestType_Load_Linked;
563 secondary_type = RubyRequestType_ATOMIC;
572 DPRINTF(RubySequencer,
"Issuing Locked RMW Write\n");
573 primary_type = RubyRequestType_Locked_RMW_Write;
575 DPRINTF(RubySequencer,
"Issuing Locked RMW Read\n");
577 primary_type = RubyRequestType_Locked_RMW_Read;
579 secondary_type = RubyRequestType_ST;
590 primary_type = secondary_type = RubyRequestType_ST;
591 }
else if (pkt->
isRead()) {
593 primary_type = secondary_type = RubyRequestType_IFETCH;
595 bool storeCheck =
false;
603 primary_type = RubyRequestType_RMW_Read;
604 secondary_type = RubyRequestType_ST;
606 primary_type = secondary_type = RubyRequestType_LD;
610 primary_type = secondary_type = RubyRequestType_FLUSH;
612 panic(
"Unsupported ruby packet type\n");
617 if (status != RequestStatus_Ready)
623 return RequestStatus_Issued;
643 std::shared_ptr<RubyRequest> msg =
646 nullptr : pkt->
getPtr<uint8_t>(),
648 RubyAccessMode_Supervisor, pkt,
649 PrefetchBit_No, proc_id, core_id);
651 DPRINTFR(ProtocolTrace,
"%15s %3s %10s%20s %6s>%-6s %#x %s\n",
654 RubyRequestType_to_string(secondary_type));
663 if (secondary_type == RubyRequestType_IFETCH)
675 template <
class KEY,
class VALUE>
677 operator<<(ostream &out, const std::unordered_map<KEY, VALUE> &map)
679 auto i = map.begin();
680 auto end = map.end();
683 for (;
i != end; ++
i)
684 out <<
" " <<
i->first <<
"=" <<
i->second;
706 #ifdef CHECK_COHERENCE
713 DPRINTF(RubyStats,
"Recorded statistic: %s\n",
714 SequencerRequestType_to_string(requestType));
730 .
name(
name() +
".store_waiting_on_load")
731 .
desc(
"Number of times a store aliased with a pending load")
734 .
name(
name() +
".store_waiting_on_store")
735 .
desc(
"Number of times a store aliased with a pending store")
738 .
name(
name() +
".load_waiting_on_load")
739 .
desc(
"Number of times a load aliased with a pending load")
742 .
name(
name() +
".load_waiting_on_store")
743 .
desc(
"Number of times a load aliased with a pending store")
754 for (
int i = 0;
i < RubyRequestType_NUM;
i++) {
765 for (
int i = 0;
i < MachineType_NUM;
i++) {
785 for (
int i = 0;
i < RubyRequestType_NUM;
i++) {
789 for (
int j = 0;
j < MachineType_NUM;
j++) {
void enqueueNextFetchRequest()
Function for fetching warming up the memory and the caches.
Stats::Scalar m_store_waiting_on_load
Counters for recording aliasing information.
int m_max_outstanding_requests
void resetStats()
Reset statistics associated with this object.
void hitCallback(SequencerRequest *request, DataBlock &data, bool llscSuccess, const MachineType mach, const bool externalHit, const Cycles initialRequestTime, const Cycles forwardRequestTime, const Cycles firstResponseTime)
Cycles is a wrapper class for representing cycle counts, i.e.
SequencerWakeupEvent deadlockCheckEvent
void print(std::ostream &out) const
std::vector< Stats::Histogram * > m_missTypeLatencyHist
ContextID contextId() const
Accessor function for context ID.
Tick cyclesToTicks(Cycles c) const
void setExtraData(uint64_t extraData)
Accessor function for store conditional return value.
CacheRecorder * m_cache_recorder
AbstractController * m_controller
bool scheduled() const
Determine if the current event is scheduled.
std::vector< Stats::Histogram * > m_FirstResponseToCompletionDelayHist
RequestStatus insertRequest(PacketPtr pkt, RubyRequestType request_type)
void recordRequestType(SequencerRequestType requestType)
Histogram & init(size_type size)
Set the parameters of this histogram.
Addr getPC() const
Accessor function for pc.
Stats::Histogram m_missLatencyHist
Histogram for holding latency profile of all requests that miss in the controller connected to this s...
Stats::Histogram m_latencyHist
Histogram for holding latency profile of all requests.
CacheMemory * m_dataCache_ptr
void recordMissLatency(const Cycles t, const RubyRequestType type, const MachineType respondingMach, bool isExternalHit, Cycles issuedTime, Cycles initialRequestTime, Cycles forwardRequestTime, Cycles firstResponseTime, Cycles completionTime)
Cycles m_inst_cache_hit_latency
std::vector< Stats::Histogram * > m_typeLatencyHist
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
T * getPtr()
get a pointer to the data ptr.
RequestTable m_readRequestTable
RubySystem * m_ruby_system
Stats::Histogram m_outstandReqHist
Histogram for number of outstanding requests per cycle.
std::vector< Stats::Histogram * > m_ForwardToFirstResponseDelayHist
CacheMemory * m_instCache_ptr
bool hasContextId() const
bool isBlocked(Addr) const
Cycles curCycle() const
Determine the current cycle, corresponding to a tick aligned to a clock edge.
std::vector< Stats::Histogram * > m_InitialToForwardDelayHist
static bool getWarmupEnabled()
RequestTable m_writeRequestTable
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...
Tick curTick()
The current simulated tick.
void enqueueNextFlushRequest()
Function for flushing the memory contents of the caches to the main memory.
void ruby_eviction_callback(Addr address)
void invalidateSC(Addr address)
void evictionCallback(Addr address)
std::vector< Stats::Histogram * > m_hitTypeLatencyHist
std::vector< Stats::Histogram * > m_IssueToInitialDelayHist
Histograms for recording the breakdown of miss latency.
bool handleLlsc(Addr address, SequencerRequest *request)
const RequestPtr req
A pointer to the original request.
Addr getOffset(Addr addr)
bool isLocked(int context) const
static bool getCooldownEnabled()
std::vector< Stats::Histogram * > m_missMachLatencyHist
Histograms for profiling the latencies for requests that required external messages.
void ruby_hit_callback(PacketPtr pkt)
void setLocked(int context)
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
void issueRequest(PacketPtr pkt, RubyRequestType type)
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Addr makeLineAddress(Addr addr)
std::string printAddress(Addr addr)
void reset()
Reset stat value to default.
void blockOnQueue(Addr, MessageBuffer *)
Flags getFlags()
Accessor for flags.
MessageBuffer * m_mandatory_q_ptr
std::vector< std::vector< Stats::Histogram * > > m_missTypeMachLatencyHist
Derived & name(const std::string &name)
Set the name and marks this stat to print at the end of simulation.
std::vector< Stats::Counter > m_IncompleteTimes
void regStats()
Register statistics for this object.
const uint8_t * getData(int offset, int len) const
virtual const std::string name() const
Declaration of the Packet class.
Cycles m_data_cache_hit_latency
const std::string & cmdString() const
Return the string name of the cmd field (for debugging and tracing).
bool m_runningGarnetStandalone
const ContextID InvalidContextID
void schedule(Event &event, Tick when)
Stats::Scalar m_store_waiting_on_store
DrainState drainState() const
Return the current drain state of an object.
void setData(const uint8_t *data, int offset, int len)
Stats::Scalar m_load_waiting_on_load
std::vector< Stats::Histogram * > m_hitMachLatencyHist
Histograms for profiling the latencies for requests that did not required external messages...
T * findNextSenderState() const
Go through the sender state stack and return the first instance that is of type T (as determined by a...
Derived & desc(const std::string &_desc)
Set the description and marks this stat to print at the end of simulation.
const T * getConstPtr() const
Cycles m_deadlock_threshold
void readCallback(Addr address, DataBlock &data, const bool externalHit=false, const MachineType mach=MachineType_NUM, const Cycles initialRequestTime=Cycles(0), const Cycles forwardRequestTime=Cycles(0), const Cycles firstResponseTime=Cycles(0))
RequestStatus makeRequest(PacketPtr pkt)
const FlagsType nozero
Don't print if this is zero.
AbstractCacheEntry * lookup(Addr address)
void writeCallback(Addr address, DataBlock &data, const bool externalHit=false, const MachineType mach=MachineType_NUM, const Cycles initialRequestTime=Cycles(0), const Cycles forwardRequestTime=Cycles(0), const Cycles firstResponseTime=Cycles(0))
void enqueue(MsgPtr message, Tick curTime, Tick delta)
void regStats() override
Register statistics for this object.
Stats::Histogram m_hitLatencyHist
Histogram for holding latency profile of all requests that hit in the controller connected to this se...
int ContextID
Globally unique thread context ID.
void sample(const U &v, int n=1)
Add a value to the distribtion n times.
void checkCoherence(Addr address)
Stats::Scalar m_load_waiting_on_store
Arch getArch() const
Get the architecture.
std::vector< std::vector< Stats::Histogram * > > m_hitTypeMachLatencyHist
Sequencer(const Params *)