32#include "debug/DRAM.hh"
33#include "debug/Drain.hh"
34#include "debug/MemCtrl.hh"
35#include "debug/QOS.hh"
48 retryRdReqPC1(false), retryWrReqPC1(false),
52 respondEventPC1([
this] {processRespondEvent(pc1Int, respQueuePC1,
53 respondEventPC1, retryRdReqPC1); },
name()),
60 assert(
dynamic_cast<DRAMInterface*
>(
p.dram_2) !=
nullptr);
106 panic(
"Can't handle address range for packet %s\n", pkt->
print());
122 panic(
"Can't handle address range for packet %s\n", pkt->
print());
137 panic(
"Can't handle address range for packet %s\n",
147 auto &range = req.
range();
154 panic(
"Can't handle address range for range %s\n", range.to_string());
162 "Write queue limit %d, PC0 size %d, entries needed %d\n",
173 "Write queue limit %d, PC1 size %d, entries needed %d\n",
184 "Read queue limit %d, PC0 size %d, entries needed %d\n",
197 "Read queue limit %d, PC1 size %d, entries needed %d\n",
217 "Should only see read and writes at memory controller\n");
239 unsigned size = pkt->
getSize();
333 auto current_it = it++;
346 auto current_it = it++;
365 Tick cmd_at = cmd_tick;
374 while (
rowBurstTicks.count(burst_tick) >= max_cmds_per_burst) {
385 while (
colBurstTicks.count(burst_tick) >= max_cmds_per_burst) {
400 Tick max_multi_cmd_split)
404 Tick cmd_at = cmd_tick;
414 Tick burst_offset = 0;
416 while (max_multi_cmd_split > (first_cmd_offset + burst_offset)) {
421 Tick first_cmd_tick = burst_tick - std::min(burst_offset, burst_tick);
424 bool first_can_issue =
false;
425 bool second_can_issue =
false;
427 while (!first_can_issue || !second_can_issue) {
428 bool same_burst = (burst_tick == first_cmd_tick);
430 auto second_cmd_count = same_burst ?
433 first_can_issue = first_cmd_count < max_cmds_per_burst;
434 second_can_issue = second_cmd_count < max_cmds_per_burst;
436 if (!second_can_issue) {
437 DPRINTF(
MemCtrl,
"Contention (cmd2) found on command bus at %d\n",
446 bool gap_violated = !same_burst &&
447 ((burst_tick - first_cmd_tick) > max_multi_cmd_split);
449 if (!first_can_issue || (!second_can_issue && gap_violated)) {
450 DPRINTF(
MemCtrl,
"Contention (cmd1) found on command bus at %d\n",
const AddrRange & range() const
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
const std::string & cmdString() const
Return the string name of the cmd field (for debugging and tracing).
void print(std::ostream &o, int verbosity=0, const std::string &prefix="") const
bool cacheResponding() const
bool isTimingMode() const
Is the system in timing mode?
void getBackdoor(MemBackdoorPtr &bd_ptr)
AddrRange getAddrRange() const
Get the address range.
Tick commandOffset() const override
void drainRanks() override
Iterate through dram ranks to exit self-refresh in order to drain.
void startup() override
Iterate through dram ranks and instantiate per rank startup routine.
bool readQueueFullPC1(unsigned int pkt_count) const
void recvMemBackdoorReq(const MemBackdoorReq &req, MemBackdoorPtr &_backdoor) override
virtual void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
AddrRangeList getAddrRanges() override
Tick recvAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &backdoor) override
bool retryRdReqPC1
Remember if we have to retry a request for second pseudo channel.
void recvFunctional(PacketPtr pkt) override
virtual void drainResume() override
Resume execution after a successful drain.
EventFunctionWrapper respondEventPC1
bool recvTimingReq(PacketPtr pkt) override
bool writeQueueFullPC1(unsigned int pkt_count) const
void pruneBurstTick() override
Remove commands that have already issued from rowBurstTicks and colBurstTicks.
virtual void startup() override
startup() is the final initialization call before simulation.
std::unordered_multiset< Tick > colBurstTicks
This is used to ensure that the column command bandwidth does not exceed the allowable media constrai...
bool readQueueFullPC0(unsigned int pkt_count) const
Check if the read queue partition of both pseudo channels has room for more entries.
std::unordered_multiset< Tick > rowBurstTicks
Holds count of row commands issued in burst window starting at defined Tick.
Tick recvAtomic(PacketPtr pkt) override
EventFunctionWrapper nextReqEventPC1
NextReq and Respond events for second pseudo channel.
HBMCtrl(const HBMCtrlParams &p)
Tick verifyMultiCmd(Tick cmd_tick, Tick max_cmds_per_burst, Tick max_multi_cmd_split=0) override
Check for command bus contention for multi-cycle (2 currently) command.
std::deque< MemPacket * > respQueuePC1
Response queue for pkts sent to second pseudo channel The first pseudo channel uses MemCtrl::respQueu...
DRAMInterface * pc0Int
Pointers to interfaces of the two pseudo channels pc0Int is same as MemCtrl::dram (it will be pointin...
Tick verifySingleCmd(Tick cmd_tick, Tick max_cmds_per_burst, bool row_cmd) override
Check for command bus contention for single cycle command.
bool writeQueueFullPC0(unsigned int pkt_count) const
Check if the write queue partition of both pseudo channels has room for more entries.
The memory controller is a single-channel memory controller capturing the most important timing const...
uint32_t writeLowThreshold
bool recvFunctionalLogic(PacketPtr pkt, MemInterface *mem_intr)
bool retryRdReq
Remember if we have to retry a request when available.
virtual void startup() override
startup() is the final initialization call before simulation.
void addToWriteQueue(PacketPtr pkt, unsigned int pkt_count, MemInterface *mem_intr)
Decode the incoming pkt, create a mem_pkt and push to the back of the write queue.
Tick recvAtomicLogic(PacketPtr pkt, MemInterface *mem_intr)
std::deque< MemPacket * > respQueue
Response queue where read packets wait after we're done working with them, but it's not time to send ...
uint32_t writeHighThreshold
std::vector< MemPacketQueue > writeQueue
virtual void processNextReqEvent(MemInterface *mem_intr, MemPacketQueue &resp_queue, EventFunctionWrapper &resp_event, EventFunctionWrapper &next_req_event, bool &retry_wr_req)
Bunch of things requires to setup "events" in gem5 When event "respondEvent" occurs for example,...
bool addToReadQueue(PacketPtr pkt, unsigned int pkt_count, MemInterface *mem_intr)
When a new read comes in, first check if the write q has a pending request to the same address....
virtual void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
uint32_t readBufferSize
The following are basic design parameters of the memory controller, and are initialized based on para...
EventFunctionWrapper nextReqEvent
std::vector< MemPacketQueue > readQueue
The controller's main read and write queues, with support for QoS reordering.
bool isTimingMode
Remember if the memory system is in timing mode.
MemCtrl(const MemCtrlParams &p)
Tick getBurstWindow(Tick cmd_tick)
Calculate burst window aligned tick.
virtual void drainResume() override
Resume execution after a successful drain.
const Tick commandWindow
Length of a command window, used to check command bandwidth.
const uint32_t writeBufferSize
uint32_t readQueueSize
Read/write packets in the read/write queue for this interface qos/mem_ctrl.hh has similar counters,...
void setCtrl(MemCtrl *_ctrl, unsigned int command_window, uint8_t pseudo_channel=0)
Set a pointer to the controller and initialize interface based on controller parameters.
const uint32_t readBufferSize
Buffer sizes for read and write queues in the controller These are passed to the controller on instan...
Tick nextBurstAt
Till when the controller must wait before issuing next RD/WR burst?
uint32_t bytesPerBurst() const
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.
System * system() const
read the system pointer
uint8_t schedule(RequestorID id, uint64_t data)
DRAMInterface declaration.
bool isSubset(const AddrRange &r) const
Determine if this range is a subset of another range, i.e.
bool contains(const Addr &a) const
Determine if the range contains an address.
static constexpr T divCeil(const T &a, const U &b)
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
bool scheduled() const
Determine if the current 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...
MemInterface declaration.
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Tick curTick()
The universal simulation clock.
uint64_t Tick
Tick count type.
statistics::Scalar writeReqs
statistics::Scalar readReqs
statistics::Scalar numWrRetry
statistics::Scalar totGap
statistics::Scalar numRdRetry
statistics::Scalar bytesReadSys
statistics::Scalar bytesWrittenSys
const std::string & name()