43#include "debug/RubyQueue.hh"
45#include "mem/ruby/protocol/MemoryMsg.hh"
58 m_clusterID(
p.cluster_id),
59 m_id(
p.
system->getRequestorId(this)), m_is_blocking(false),
60 m_number_of_TBEs(
p.number_of_TBEs),
61 m_transitions_per_cycle(
p.transitions_per_cycle),
62 m_buffer_size(
p.buffer_size), m_recycle_latency(
p.recycle_latency),
63 m_mandatory_queue_latency(
p.mandatory_queue_latency),
64 m_waiting_mem_retry(false),
65 m_mem_ctrl_waiting_retry(false),
67 addrRanges(
p.addr_ranges.begin(),
p.addr_ranges.end()),
68 mRetryRespEvent{*this, false},
83 for (uint32_t
i = 0;
i < size;
i++) {
97 for (
auto abs_cntrl :
params().downstream_destinations) {
98 MachineID mid = abs_cntrl->getMachineID();
100 for (
const auto &addr_range : ranges) {
103 (
i->second.intersects(addr_range) !=
i->second.end())) {
104 fatal(
"%s: %s mapped to multiple machines of the same type\n",
105 name(), addr_range.to_string());
115 for (
auto abs_cntrl :
params().upstream_destinations) {
125 for (uint32_t
i = 0;
i < size;
i++) {
164 bool has_other_msgs =
false;
166 for (
unsigned int port = 0; port < msgVec->size(); ++port) {
167 if ((*msgVec)[port] == buf) {
169 (*msgVec)[port] = NULL;
170 }
else if ((*msgVec)[port] != NULL) {
171 has_other_msgs =
true;
174 if (!has_other_msgs) {
236 for (MsgVecType::iterator vec_iter = buf_iter->second->begin();
237 vec_iter != buf_iter->second->end();
242 if (*vec_iter != NULL &&
243 (wokeUpMsgBufs.count(*vec_iter) == 0)) {
244 (*vec_iter)->reanalyzeAllMessages(
clockEdge());
245 wokeUpMsgBufs.insert(*vec_iter);
248 wokeUpMsgVecs.push_back(buf_iter->second);
252 wb_iter != wokeUpMsgVecs.end();
270 const MemoryMsg *mem_msg = (
const MemoryMsg*)mem_queue->peek();
272 if (mem_msg->m_Len > 0) {
273 req_size = mem_msg->m_Len;
277 = std::make_shared<Request>(mem_msg->m_addr, req_size, 0,
m_id);
279 if (mem_msg->getType() == MemoryRequestType_MEMORY_WB) {
284 }
else if (mem_msg->getType() == MemoryRequestType_MEMORY_READ) {
286 uint8_t *newData =
new uint8_t[req_size];
289 panic(
"Unknown memory request type (%s) for addr %p",
290 MemoryRequestType_to_string(mem_msg->getType()),
366 int num_functional_writes = 0;
370 return num_functional_writes + 1;
380 if (!memRspQueue->areNSlotsAvailable(1,
curTick())) {
385 std::shared_ptr<MemoryMsg> msg = std::make_shared<MemoryMsg>(
clockEdge());
386 (*msg).m_addr = pkt->
getAddr();
390 (*msg).m_OriginalRequestorMachId =
s->
id;
394 (*msg).m_Type = MemoryRequestType_MEMORY_READ;
395 (*msg).m_MessageSize = MessageSizeType_Response_Data;
398 (*msg).m_DataBlk.setData(pkt->
getPtr<uint8_t>(), 0,
401 (*msg).m_Type = MemoryRequestType_MEMORY_WB;
402 (*msg).m_MessageSize = MessageSizeType_Writeback_Control;
404 panic(
"Incorrect packet type received from memory controller!");
430 if (mtype == MachineType_NUM) {
433 const auto mapping =
i.second.contains(
addr);
434 if (mapping !=
i.second.end())
435 return mapping->second;
441 const auto mapping =
i->second.contains(
addr);
442 if (mapping !=
i->second.end())
443 return mapping->second;
446 fatal(
"%s: couldn't find mapping for address %x mtype=%s\n",
483 controller->m_waiting_mem_retry =
false;
484 controller->serviceMemoryQueue();
496 : statistics::
Group(parent),
498 "cycles for which number of transistions == max transitions"),
499 ADD_STAT(delayHistogram,
"delay_histogram")
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
ClockedObjectParams Params
Parameters of ClockedObject.
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 cyclesToTicks(Cycles c) const
Cycles ticksToCycles(Tick t) const
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)
SenderState * senderState
This packet's sender state.
void pushSenderState(SenderState *sender_state)
Push a new sender state to the packet and make the current sender state the predecessor of the new on...
T * getPtr()
get a pointer to the data ptr.
void setData(const uint8_t *p)
Copy data into the packet from the provided pointer.
static PacketPtr createRead(const RequestPtr &req)
Constructor-like methods that return Packets based on Request objects.
void dataDynamic(T *p)
Set the data pointer to a value that should have delete [] called on it.
void allocate()
Allocate memory for the packet.
Ports are used to interface objects to each other.
A RequestPort is a specialisation of a Port, which implements the default protocol for the three diff...
virtual void sendRetryResp()
Send a retry to the response port that previously attempted a sendTimingResp to this request port and...
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...
MemoryPort(const std::string &_name, AbstractController *_controller, PortID id=InvalidPortID)
bool recvTimingResp(PacketPtr pkt)
Receive a timing response from the peer.
void recvReqRetry()
Called by the peer if sendTimingReq was called on this peer (causing recvTimingReq to be called on th...
AbstractController * controller
bool m_mem_ctrl_waiting_retry
std::vector< MessageBuffer * > MsgVecType
bool recvTimingResp(PacketPtr pkt)
void profileMsgDelay(uint32_t virtualNetwork, Cycles delay)
Profiles the delay associated with messages.
NetDest upstreamDestinations
void dequeueMemRespQueue()
void wakeUpBuffer(MessageBuffer *buf, Addr addr)
void functionalMemoryRead(PacketPtr)
int functionalMemoryWrite(PacketPtr)
virtual void regStats()
Callback to set stat parameters.
Tick recvAtomic(PacketPtr pkt)
std::unordered_map< MachineType, AddrRangeMap< MachineID, 3 > > downstreamAddrMap
virtual MessageBuffer * getMemReqQueue() const =0
std::set< MessageBuffer * > MsgBufType
unsigned int m_cur_in_port
void wakeUpBuffers(Addr addr)
MachineID mapAddressToDownstreamMachine(Addr addr, MachineType mtype=MachineType_NUM) const
Maps an address to the correct dowstream MachineID (i.e.
virtual void collateStats()
Function for collating statistics from all the controllers of this particular type.
virtual MessageBuffer * getMemRespQueue() const =0
AbstractController(const Params &p)
NetDest downstreamDestinations
void init()
init() is called after all C++ SimObjects have been created and all ports are connected.
void memRespQueueDequeued()
MemberEventWrapper<&AbstractController::sendRetryRespToMem > mRetryRespEvent
bool isBlocked(Addr) const
virtual void resetStats()=0
Callback to reset stats.
void blockOnQueue(Addr, MessageBuffer *)
MachineID mapAddressToMachine(Addr addr, MachineType mtype) const
Map an address to the correct MachineID.
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
A function used to return the port associated with this bus object.
gem5::ruby::AbstractController::ControllerStats stats
std::map< Addr, MessageBuffer * > m_block_map
WaitingBufType m_waiting_buffers
void sendRetryRespToMem()
bool serviceMemoryQueue()
void stallBuffer(MessageBuffer *buf, Addr addr)
void scheduleEvent(Cycles timeDelta)
void setConsumer(Consumer *consumer)
bool functionalRead(Packet *pkt)
void reanalyzeMessages(Addr addr, Tick current_time)
void add(MachineID newElement)
static uint32_t getNumberOfVirtualNetworks()
NodeID addressToNodeID(Addr addr, MachineType mtype)
Map an address to the correct NodeID.
static bool getWarmupEnabled()
static uint32_t getBlockSizeBytes()
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
void sample(const U &v, int n=1)
Add a value to the distribtion n times.
void reset()
Reset stat value to default.
Histogram & init(size_type size)
Set the parameters of this histogram.
#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)
#define panic(...)
This implements a cprintf based panic() function.
#define gem5_assert(cond,...)
The assert macro will function like a normal assert, but will use panic instead of straight abort().
#define fatal(...)
This implements a cprintf based fatal() function.
const Params & params() const
static SimObject * find(const char *name)
Find the SimObject with the given name and return a pointer to it.
virtual void regStats()
Callback to set stat parameters.
virtual void resetStats()
Callback to reset stats.
Addr getOffset(Addr addr)
void registerDumpCallback(const std::function< void()> &callback)
Register a callback that should be called whenever statistics are about to be dumped.
const FlagsType nozero
Don't print if this is zero.
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria 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.
uint64_t Tick
Tick count type.
RubyTester::SenderState SenderState
std::string csprintf(const char *format, const Args &...args)
statistics::Scalar fullyBusyCycles
Counter for the number of cycles when the transitions carried out were equal to the maximum allowed.
ControllerStats(statistics::Group *parent)
statistics::Histogram delayHistogram
Histogram for profiling delay for the messages this controller cares for.
std::vector< statistics::Histogram * > delayVCHistogram
MachineType getType() const
const std::string & name()