42#include "debug/Drain.hh"
43#include "debug/QOS.hh"
45#include "params/QoSMemSinkInterface.hh"
57 :
MemCtrl(
p), requestLatency(
p.request_latency),
58 responseLatency(
p.response_latency),
59 memoryPacketSize(
p.memory_packet_size),
60 readBufferSize(
p.read_buffer_size),
61 writeBufferSize(
p.write_buffer_size), port(
name() +
".port", *this),
62 interface(
p.interface),
63 retryRdReq(false), retryWrReq(false), nextRequest(0), nextReqEvent(*this),
105 "%s Should not see packets where cache is responding\n",
136 bool req_accepted =
true;
139 "%s. Should only see "
140 "read and writes at memory controller\n",
144 "%s. Should not see packets where cache is responding\n",
148 "%s: REQUESTOR %s request %s addr %lld size %d\n",
155 assert(required_entries);
164 "%s Read queue full, not accepting\n", __func__);
168 req_accepted =
false;
172 readQueue.at(pkt_priority).push_back(pkt);
178 "%s Write queue full, not accepting\n", __func__);
182 req_accepted =
false;
194 pkt->
req->requestorId(),
203 "%s scheduling next request at "
204 "time %d (next is %d)\n", __func__,
230 "%s DUMPING %s queues status\n", __func__,
235 std::string plist =
"";
237 plist += (std::to_string(
e->req->requestorId())) +
" ";
240 "%s priority Queue [%i] contains %i elements, "
241 "packets are: [%s]\n", __func__,
i,
250 for (
auto queue = (*queue_ptr).rbegin();
251 queue != (*queue_ptr).rend(); ++queue) {
256 "%s checking %s queue [%d] priority [%d packets]\n",
258 curr_prio, queue->size());
260 if (!queue->empty()) {
267 "%s scheduling packet address %d for requestor %s from "
268 "priority queue %d\n", __func__, pkt->
getAddr(),
284 "%s scheduled packet address %d for requestor %s size is %d, "
285 "corresponds to %d memory packets\n", __func__, pkt->
getAddr(),
287 pkt->
getSize(), removed_entries);
291 "%s response not required\n", __func__);
299 pkt->
req->requestorId(),
307 "%s response scheduled at time %d\n",
326 "%s scheduling next request event at tick %d\n",
336 "%s queues have requests, waiting to drain\n",
345 : statistics::
Group(parent),
346 ADD_STAT(numReadRetries, statistics::units::Count::get(),
347 "Number of read retries"),
348 ADD_STAT(numWriteRetries, statistics::units::Count::get(),
349 "Number of write retries")
356 mem(
m), queue(
mem, *this, true)
363 ranges.push_back(
mem.interface->getAddrRange());
370 return mem.recvAtomic(pkt);
378 if (!queue.trySatisfyFunctional(pkt)) {
382 mem.recvFunctional(pkt);
391 return mem.recvTimingReq(pkt);
virtual std::string name() const
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
void pushLabel(const std::string &lbl)
Push label for PrintReq (safe to call unconditionally).
const std::string & cmdString() const
Return the string name of the cmd field (for debugging and tracing).
bool needsResponse() const
uint8_t qosValue() const
QoS Value getter Returns 0 if QoS value was never set (constructor default).
RequestPtr req
A pointer to the original request.
void popLabel()
Pop label for PrintReq (safe to call unconditionally).
bool cacheResponding() const
Ports are used to interface objects to each other.
bool isConnected() const
Is this port currently connected to a peer?
A queued port is a port that has an infinite queue for outgoing packets and thus decouples the module...
void schedTimingResp(PacketPtr pkt, Tick when)
Schedule the sending of a timing response.
void sendRangeChange() const
Called by the owner to send a range change.
void sendRetryReq()
Send a retry to the request port that previously attempted a sendTimingReq to this response port and ...
std::string getRequestorName(RequestorID requestor_id)
Get the name of an object for a given request id.
An abstract memory represents a contiguous block of physical memory, with an associated address range...
void access(PacketPtr pkt)
Perform an untimed memory access and update all the state (e.g.
void functionalAccess(PacketPtr pkt)
Perform an untimed memory read or write without changing anything but the memory itself.
The qos::MemCtrl is a base class for Memory objects which support QoS - it provides access to a set o...
void logResponse(BusState dir, RequestorID id, uint8_t _qos, Addr addr, uint64_t entries, double delay)
Called upon receiving a response, updates statistics and updates queues status.
std::vector< uint64_t > writeQueueSizes
Write request packets queue length in #packets, per QoS priority.
uint8_t qosSchedule(std::initializer_list< Queues * > queues_ptr, uint64_t queue_entry_size, const PacketPtr pkt)
Assign priority to a packet by executing the configured QoS policy.
uint64_t totalWriteQueueSize
Total write request packets queue length in #packets.
void recordTurnaroundStats(BusState busState, BusState busStateNext)
Record statistics on turnarounds based on busStateNext and busState values.
void setCurrentBusState()
Set current bus direction (READ or WRITE) from next selected one.
std::vector< uint64_t > readQueueSizes
Read request packets queue length in #packets, per QoS priority.
const std::unique_ptr< QueuePolicy > queuePolicy
QoS Queue Policy: selects packet among same-priority queue.
BusState selectNextBusState()
Returns next bus direction (READ or WRITE) based on configured policy.
uint8_t numPriorities() const
Gets the total number of priority levels in the QoS memory controller.
BusState busState
Bus state used to control the read/write switching and drive the scheduling of the next request.
System * _system
Pointer to the System object.
uint64_t totalReadQueueSize
Total read request packets queue length in #packets.
BusState busStateNext
bus state for next request event triggered
uint8_t schedule(RequestorID id, uint64_t data)
void logRequest(BusState dir, RequestorID id, uint8_t _qos, Addr addr, uint64_t entries)
Called upon receiving a request or updates statistics and updates queues status.
void recvFunctional(PacketPtr pkt)
Receive a Packet in Functional mode.
MemoryPort(const std::string &, MemSinkCtrl &)
Constructor.
AddrRangeList getAddrRanges() const
Gets the configured address ranges for this port.
Tick recvAtomic(PacketPtr pkt)
Receive a Packet in Atomic mode.
bool recvTimingReq(PacketPtr pkt)
Receive a Packet in Timing mode.
MemoryPort port
Memory response port.
Tick recvAtomic(PacketPtr pkt)
Receive a Packet in Atomic mode.
const Tick responseLatency
Memory response latency (ticks)
Port & getPort(const std::string &if_name, PortID=InvalidPortID) override
Getter method to access this memory's response port.
MemberEventWrapper<&MemSinkCtrl::processNextReqEvent > nextReqEvent
Event wrapper to schedule next request handler function.
const uint64_t writeBufferSize
Write request packets queue buffer size in #packets.
DrainState drain() override
Checks and return the Drain state of this SimObject.
bool readQueueFull(const uint64_t packets) const
Check if the read queue has room for more entries.
bool recvTimingReq(PacketPtr pkt)
Receive a Packet in Timing mode.
const uint64_t readBufferSize
Read request packets queue buffer size in #packets.
bool retryWrReq
Write request pending.
std::vector< PacketQueue > readQueue
QoS-aware (per priority) incoming read requests packets queue.
bool retryRdReq
Read request pending.
void processNextReqEvent()
Processes the next Request event according to configured request latency.
bool writeQueueFull(const uint64_t packets) const
Check if the write queue has room for more entries.
const Tick requestLatency
Memory between requests latency (ticks)
const uint64_t memoryPacketSize
Memory packet size in bytes.
void init() override
Initializes this object.
MemSinkCtrl(const QoSMemSinkCtrlParams &)
QoS Memory Sink Constructor.
void recvFunctional(PacketPtr pkt)
Receive a Packet in Functional mode.
Tick nextRequest
Next request service time.
std::vector< PacketQueue > writeQueue
QoS-aware (per priority) incoming read requests packets queue.
MemSinkInterface *const interface
Create pointer to interface of actual media.
MemSinkInterface(const QoSMemSinkInterfaceParams &_p)
void setMemCtrl(MemSinkCtrl *_ctrl)
Setting a pointer to the interface.
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
static constexpr T divCeil(const T &a, const U &b)
DrainState
Object drain/handover states.
@ Draining
Draining buffers pending serialization/handover.
@ Drained
Buffers drained, ready for serialization/handover.
bool scheduled() const
Determine if the current event is scheduled.
#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.
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Tick curTick()
The universal simulation clock.
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
uint64_t Tick
Tick count type.
statistics::Scalar numReadRetries
Count the number of read retries.
MemSinkCtrlStats(statistics::Group *parent)
statistics::Scalar numWriteRetries
Count the number of write retries.
const std::string & name()