24.22.4.2.2. TimingSimpleCPU analysis #1
Backtrace:
EventManager::schedule DRAMCtrl::Rank::startup DRAMCtrl::startup
Snippets:
void DRAMCtrl::startup() { // remember the memory system mode of operation isTimingMode = system()->isTimingMode(); if (isTimingMode) { // timestamp offset should be in clock cycles for DRAMPower timeStampOffset = divCeil(curTick(), tCK); // update the start tick for the precharge accounting to the // current tick for (auto r : ranks) { r->startup(curTick() + tREFI - tRP); } // shift the bus busy time sufficiently far ahead that we never // have to worry about negative values when computing the time for // the next request, this will add an insignificant bubble at the // start of simulation nextBurstAt = curTick() + tRP + tRCD; } }
which then calls:
void DRAMCtrl::Rank::startup(Tick ref_tick) { assert(ref_tick > curTick()); pwrStateTick = curTick(); // kick off the refresh, and give ourselves enough time to // precharge schedule(refreshEvent, ref_tick); }
DRAMCtrl::startup
is itself a SimObject
method exposed to Python and called from simulate
in src/python/m5/simulate.py
:
def simulate(*args, **kwargs): global need_startup if need_startup: root = objects.Root.getInstance() for obj in root.descendants(): obj.startup()
where simulate
happens after m5.instantiate
, and both are called directly from the toplevel scripts, e.g. for se.py in configs/common/Simulation.py
:
def run(options, root, testsys, cpu_class): ... exit_event = m5.simulate()
By looking up some variable definitions in the source, we now we see some memory parameters clearly:
-
ranks:
std::vector<DRAMCtrl::Rank*>
with 2 elements. TODO why do we have 2? What does it represent? Likely linked toconfig.ini
atsystem.mem_ctrls.ranks_per_channel=2
: https://en.wikipedia.org/wiki/Memory_rank -
tCK=1250
,tREFI=7800000
,tRP=13750
,tRCD=13750
: all defined in a single code location with a comment:/** * Basic memory timing parameters initialized based on parameter * values. */
Their values can be seen under
config.ini
and they are documented insrc/mem/DRAMCtrl.py
e.g.:# the base clock period of the DRAM tCK = Param.Latency("Clock period") # minimum time between a precharge and subsequent activate tRP = Param.Latency("Row precharge time") # the amount of time in nanoseconds from issuing an activate command # to the data being available in the row buffer for a read/write tRCD = Param.Latency("RAS to CAS delay") # refresh command interval, how often a "ref" command needs # to be sent. It is 7.8 us for a 64ms refresh requirement tREFI = Param.Latency("Refresh command interval")
So we realize that we are going into deep DRAM modelling, more detail that a mere mortal should ever need to know.
curTick() + tREFI - tRP = 0 + 7800000 - 13750 = 7786250
which is when that refreshEvent
was scheduled. Our simulation ends way before that point however, so we will never know what it did thank God.