44#include "debug/DRAM.hh"
45#include "debug/Drain.hh"
46#include "debug/MemCtrl.hh"
47#include "debug/NVM.hh"
48#include "debug/QOS.hh"
69 "HeteroMemCtrl's dram interface must be of type DRAMInterface.\n");
71 "HeteroMemCtrl's nvm interface must be of type NVMInterface.\n");
84 if (
p.write_low_thresh_perc >=
p.write_high_thresh_perc)
85 fatal(
"Write buffer low threshold %d must be smaller than the "
86 "high threshold %d\n",
p.write_low_thresh_perc,
87 p.write_high_thresh_perc);
100 panic(
"Can't handle address range for packet %s\n", pkt->
print());
117 "Should only see read and writes at memory controller\n");
132 panic(
"Can't handle address range for packet %s\n",
140 unsigned size = pkt->
getSize();
202 "processRespondEvent(): Some req has reached its readyTime\n");
204 if (queue.front()->isDram()) {
211MemPacketQueue::iterator
217 MemPacketQueue::iterator ret = queue.end();
219 if (!queue.empty()) {
220 if (queue.size() == 1) {
231 for (
auto i = queue.begin();
i != queue.end(); ++
i) {
240 std::tie(ret, col_allowed_at)
243 panic(
"No scheduling policy chosen\n");
254 auto selected_pkt_it = queue.end();
255 auto nvm_pkt_it = queue.end();
259 std::tie(selected_pkt_it, col_allowed_at) =
262 std::tie(nvm_pkt_it, nvm_col_allowed_at) =
268 if (col_allowed_at > nvm_col_allowed_at) {
269 selected_pkt_it = nvm_pkt_it;
270 col_allowed_at = nvm_col_allowed_at;
273 return std::make_pair(selected_pkt_it, col_allowed_at);
313 bool dram_busy, nvm_busy =
true;
315 dram_busy = mem_intr->
isBusy(
false,
false);
319 nvm_busy =
nvm->
isBusy(read_queue_empty, all_writes_nvm);
323 if (dram_busy && nvm_busy) {
400 panic(
"Can't handle address range for packet %s\n", pkt->
print());
412 return (dram_drained && nvm_drained);
423 DPRINTF(Drain,
"Memory controller not drained, write: %d, read: %d,"
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?
AddrRange getAddrRange() const
Get the address range.
Interface to DRAM devices with media specific parameters, statistics, and functions.
virtual void processRespondEvent(MemInterface *mem_intr, MemPacketQueue &queue, EventFunctionWrapper &resp_event, bool &retry_rd_req) override
void drainResume() override
Resume execution after a successful drain.
virtual bool pktSizeCheck(MemPacket *mem_pkt, MemInterface *mem_intr) const override
Check if mem pkt's size is sane.
HeteroMemCtrl(const HeteroMemCtrlParams &p)
Tick doBurstAccess(MemPacket *mem_pkt, MemInterface *mem_int) override
Actually do the burst based on media specific access function.
virtual bool memBusy(MemInterface *mem_intr) override
Checks if the memory interface is already busy.
Tick recvAtomic(PacketPtr pkt) override
virtual Addr burstAlign(Addr addr, MemInterface *mem_intr) const override
Burst-align an address.
virtual std::pair< MemPacketQueue::iterator, Tick > chooseNextFRFCFS(MemPacketQueue &queue, Tick extra_col_delay, MemInterface *mem_intr) override
For FR-FCFS policy reorder the read/write queue depending on row buffer hits and earliest bursts avai...
DrainState drain() override
Draining is the process of clearing out the states of SimObjects.These are the SimObjects that are pa...
bool recvTimingReq(PacketPtr pkt) override
AddrRangeList getAddrRanges() override
MemPacketQueue::iterator chooseNext(MemPacketQueue &queue, Tick extra_col_delay, MemInterface *mem_int) override
The memory schduler/arbiter - picks which request needs to go next, based on the specified policy suc...
Tick minReadToWriteDataGap() override
Calculate the minimum delay used when scheduling a read-to-write transision.
bool allIntfDrained() const override
Ensure that all interfaced have drained commands.
virtual void nonDetermReads(MemInterface *mem_intr) override
Will access nvm memory interface and select non-deterministic reads to issue.
Tick minWriteToReadDataGap() override
Calculate the minimum delay used when scheduling a write-to-read transision.
virtual bool nvmWriteBlock(MemInterface *mem_intr) override
Will check if all writes are for nvm interface and nvm's write resp queue is full.
NVMInterface * nvm
Create pointer to interface of the actual nvm media when connected.
void recvFunctional(PacketPtr pkt) override
The memory controller is a single-channel memory controller capturing the most important timing const...
uint32_t writeLowThreshold
enums::MemSched memSchedPolicy
Memory controller configuration initialized based on parameter values.
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 std::pair< MemPacketQueue::iterator, Tick > chooseNextFRFCFS(MemPacketQueue &queue, Tick extra_col_delay, MemInterface *mem_intr)
For FR-FCFS policy reorder the read/write queue depending on row buffer hits and earliest bursts avai...
bool readQueueFull(unsigned int pkt_count) const
Check if the read queue has room for more entries.
virtual Tick doBurstAccess(MemPacket *mem_pkt, MemInterface *mem_intr)
Actually do the burst based on media specific access function.
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....
bool writeQueueFull(unsigned int pkt_count) const
Check if the write queue has room for more entries.
uint32_t readBufferSize
The following are basic design parameters of the memory controller, and are initialized based on para...
EventFunctionWrapper nextReqEvent
virtual bool packetReady(MemPacket *pkt, MemInterface *mem_intr)
Determine if there is a packet that can issue.
virtual bool nvmWriteBlock(MemInterface *mem_intr)
Will check if all writes are for nvm interface and nvm's write resp queue is full.
virtual void processRespondEvent(MemInterface *mem_intr, MemPacketQueue &queue, EventFunctionWrapper &resp_event, bool &retry_rd_req)
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.
const Tick commandWindow
Length of a command window, used to check command bandwidth.
virtual void nonDetermReads(MemInterface *mem_intr)
Will access memory interface and select non-deterministic reads to issue.
General interface to memory device Includes functions and parameters shared across media types.
const uint32_t writeBufferSize
virtual void suspend()
This function is DRAM specific.
virtual void addRankToRankDelay(Tick cmd_at)=0
Add rank to rank delay to bus timing to all banks in all ranks when access to an alternate interface ...
virtual bool isBusy(bool read_queue_empty, bool all_writes_nvm)=0
This function checks if ranks are busy.
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?
Tick minWriteToReadDataGap() const
uint32_t numWritesQueued
NVM specific variable, but declaring it here allows treating different interfaces in a more genral wa...
Tick minReadToWriteDataGap() const
virtual bool allRanksDrained() const =0
Check drain state of interface.
virtual void drainRanks()
This function is DRAM specific.
uint32_t bytesPerBurst() const
A memory packet stores packets along with the timestamp of when the packet entered the queue,...
unsigned int size
The size of this dram packet in bytes It is always equal or smaller than the burst size.
bool isDram() const
Return true if its a DRAM access.
Interface to NVM devices with media specific parameters, statistics, and functions.
void addRankToRankDelay(Tick cmd_at) override
Add rank to rank delay to bus timing to all NVM banks in alli ranks when access to an alternate inter...
bool isBusy(bool read_queue_empty, bool all_writes_nvm) override
This function checks if ranks are busy.
bool allRanksDrained() const override
Check drain state of NVM interface.
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.
uint64_t totalReadQueueSize
Total read request packets queue length in #packets.
System * system() const
read the system pointer
uint8_t schedule(RequestorID id, uint64_t data)
DRAMInterface declaration.
bool contains(const Addr &a) const
Determine if the range contains an address.
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(...)
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 fatal(...)
This implements a cprintf based fatal() function.
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
virtual void startup()
startup() is the final initialization call before simulation.
HeteroMemCtrl declaration.
MemInterface declaration.
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.
uint64_t Tick
Tick count type.
NVMInterface declaration.
statistics::Scalar writeReqs
statistics::Scalar readReqs
statistics::Scalar numWrRetry
statistics::Scalar totGap
statistics::Scalar numRdRetry
statistics::Scalar bytesReadSys
statistics::Scalar bytesWrittenSys