gem5 v24.0.0.0
Loading...
Searching...
No Matches
hbm_ctrl.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2022 The Regents of the University of California
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include "mem/hbm_ctrl.hh"
30
31#include "base/trace.hh"
32#include "debug/DRAM.hh"
33#include "debug/Drain.hh"
34#include "debug/MemCtrl.hh"
35#include "debug/QOS.hh"
36#include "mem/dram_interface.hh"
37#include "mem/mem_interface.hh"
38#include "sim/system.hh"
39
40namespace gem5
41{
42
43namespace memory
44{
45
46HBMCtrl::HBMCtrl(const HBMCtrlParams &p) :
47 MemCtrl(p),
48 retryRdReqPC1(false), retryWrReqPC1(false),
49 nextReqEventPC1([this] {processNextReqEvent(pc1Int, respQueuePC1,
51 name()),
52 respondEventPC1([this] {processRespondEvent(pc1Int, respQueuePC1,
53 respondEventPC1, retryRdReqPC1); }, name()),
54 pc1Int(p.dram_2)
55{
56 DPRINTF(MemCtrl, "Setting up HBM controller\n");
57
58 pc0Int = dynamic_cast<DRAMInterface*>(dram);
59
60 assert(dynamic_cast<DRAMInterface*>(p.dram_2) != nullptr);
61
64
65 fatal_if(!pc0Int, "Memory controller must have pc0 interface");
66 fatal_if(!pc1Int, "Memory controller must have pc1 interface");
67
68 pc0Int->setCtrl(this, commandWindow, 0);
69 pc1Int->setCtrl(this, commandWindow, 1);
70
71 writeHighThreshold = (writeBufferSize/2 * p.write_high_thresh_perc)/100.0;
72 writeLowThreshold = (writeBufferSize/2 * p.write_low_thresh_perc)/100.0;
73}
74
75void
80
81void
83{
85
87 if (isTimingMode) {
88 // shift the bus busy time sufficiently far ahead that we never
89 // have to worry about negative values when computing the time for
90 // the next request, this will add an insignificant bubble at the
91 // start of simulation
93 }
94}
95
96Tick
98{
99 Tick latency = 0;
100
101 if (pc0Int->getAddrRange().contains(pkt->getAddr())) {
102 latency = recvAtomicLogic(pkt, pc0Int);
103 } else if (pc1Int->getAddrRange().contains(pkt->getAddr())) {
104 latency = recvAtomicLogic(pkt, pc1Int);
105 } else {
106 panic("Can't handle address range for packet %s\n", pkt->print());
107 }
108
109 return latency;
110}
111
112void
114{
115 bool found = recvFunctionalLogic(pkt, pc0Int);
116
117 if (!found) {
118 found = recvFunctionalLogic(pkt, pc1Int);
119 }
120
121 if (!found) {
122 panic("Can't handle address range for packet %s\n", pkt->print());
123 }
124}
125
126Tick
128{
129 Tick latency = recvAtomic(pkt);
130
131 if (pc0Int && pc0Int->getAddrRange().contains(pkt->getAddr())) {
132 pc0Int->getBackdoor(backdoor);
133 } else if (pc1Int && pc1Int->getAddrRange().contains(pkt->getAddr())) {
134 pc1Int->getBackdoor(backdoor);
135 }
136 else {
137 panic("Can't handle address range for packet %s\n",
138 pkt->print());
139 }
140 return latency;
141}
142
143void
145 MemBackdoorPtr &backdoor)
146{
147 auto &range = req.range();
148 if (pc0Int && pc0Int->getAddrRange().isSubset(range)) {
149 pc0Int->getBackdoor(backdoor);
150 } else if (pc1Int && pc1Int->getAddrRange().isSubset(range)) {
151 pc1Int->getBackdoor(backdoor);
152 }
153 else {
154 panic("Can't handle address range for range %s\n", range.to_string());
155 }
156}
157
158bool
159HBMCtrl::writeQueueFullPC0(unsigned int neededEntries) const
160{
162 "Write queue limit %d, PC0 size %d, entries needed %d\n",
163 writeBufferSize/2, pc0Int->writeQueueSize, neededEntries);
164
165 unsigned int wrsize_new = (pc0Int->writeQueueSize + neededEntries);
166 return wrsize_new > (writeBufferSize/2);
167}
168
169bool
170HBMCtrl::writeQueueFullPC1(unsigned int neededEntries) const
171{
173 "Write queue limit %d, PC1 size %d, entries needed %d\n",
174 writeBufferSize/2, pc1Int->writeQueueSize, neededEntries);
175
176 unsigned int wrsize_new = (pc1Int->writeQueueSize + neededEntries);
177 return wrsize_new > (writeBufferSize/2);
178}
179
180bool
181HBMCtrl::readQueueFullPC0(unsigned int neededEntries) const
182{
184 "Read queue limit %d, PC0 size %d, entries needed %d\n",
186 neededEntries);
187
188 unsigned int rdsize_new = pc0Int->readQueueSize + respQueue.size()
189 + neededEntries;
190 return rdsize_new > (readBufferSize/2);
191}
192
193bool
194HBMCtrl::readQueueFullPC1(unsigned int neededEntries) const
195{
197 "Read queue limit %d, PC1 size %d, entries needed %d\n",
199 neededEntries);
200
201 unsigned int rdsize_new = pc1Int->readQueueSize + respQueuePC1.size()
202 + neededEntries;
203 return rdsize_new > (readBufferSize/2);
204}
205
206bool
208{
209 // This is where we enter from the outside world
210 DPRINTF(MemCtrl, "recvTimingReq: request %s addr %#x size %d\n",
211 pkt->cmdString(), pkt->getAddr(), pkt->getSize());
212
213 panic_if(pkt->cacheResponding(), "Should not see packets where cache "
214 "is responding");
215
216 panic_if(!(pkt->isRead() || pkt->isWrite()),
217 "Should only see read and writes at memory controller\n");
218
219 // Calc avg gap between requests
220 if (prevArrival != 0) {
222 }
224
225 // What type of media does this packet access?
226 bool is_pc0;
227
228 // TODO: make the interleaving bit across pseudo channels a parameter
229 if (bits(pkt->getAddr(), 6) == 0) {
230 is_pc0 = true;
231 } else {
232 is_pc0 = false;
233 }
234
235 // Find out how many memory packets a pkt translates to
236 // If the burst size is equal or larger than the pkt size, then a pkt
237 // translates to only one memory packet. Otherwise, a pkt translates to
238 // multiple memory packets
239 unsigned size = pkt->getSize();
240 uint32_t burst_size = pc0Int->bytesPerBurst();
241 unsigned offset = pkt->getAddr() & (burst_size - 1);
242 unsigned int pkt_count = divCeil(offset + size, burst_size);
243
244 // run the QoS scheduler and assign a QoS priority value to the packet
245 qosSchedule({&readQueue, &writeQueue}, burst_size, pkt);
246
247 // check local buffers and do not accept if full
248 if (pkt->isWrite()) {
249 if (is_pc0) {
250 if (writeQueueFullPC0(pkt_count)) {
251 DPRINTF(MemCtrl, "Write queue full, not accepting\n");
252 // remember that we have to retry this port
253 retryWrReq = true;
255 return false;
256 } else {
257 addToWriteQueue(pkt, pkt_count, pc0Int);
258 if (!nextReqEvent.scheduled()) {
259 DPRINTF(MemCtrl, "Request scheduled immediately\n");
261 }
263 stats.bytesWrittenSys += size;
264 }
265 } else {
266 if (writeQueueFullPC1(pkt_count)) {
267 DPRINTF(MemCtrl, "Write queue full, not accepting\n");
268 // remember that we have to retry this port
269 retryWrReqPC1 = true;
271 return false;
272 } else {
273 addToWriteQueue(pkt, pkt_count, pc1Int);
274 if (!nextReqEventPC1.scheduled()) {
275 DPRINTF(MemCtrl, "Request scheduled immediately\n");
277 }
279 stats.bytesWrittenSys += size;
280 }
281 }
282 } else {
283
284 assert(pkt->isRead());
285 assert(size != 0);
286
287 if (is_pc0) {
288 if (readQueueFullPC0(pkt_count)) {
289 DPRINTF(MemCtrl, "Read queue full, not accepting\n");
290 // remember that we have to retry this port
291 retryRdReq = true;
293 return false;
294 } else {
295 if (!addToReadQueue(pkt, pkt_count, pc0Int)) {
296 if (!nextReqEvent.scheduled()) {
297 DPRINTF(MemCtrl, "Request scheduled immediately\n");
299 }
300 }
301
302 stats.readReqs++;
303 stats.bytesReadSys += size;
304 }
305 } else {
306 if (readQueueFullPC1(pkt_count)) {
307 DPRINTF(MemCtrl, "Read queue full, not accepting\n");
308 // remember that we have to retry this port
309 retryRdReqPC1 = true;
311 return false;
312 } else {
313 if (!addToReadQueue(pkt, pkt_count, pc1Int)) {
314 if (!nextReqEventPC1.scheduled()) {
315 DPRINTF(MemCtrl, "Request scheduled immediately\n");
317 }
318 }
319 stats.readReqs++;
320 stats.bytesReadSys += size;
321 }
322 }
323 }
324
325 return true;
326}
327
328void
330{
331 auto it = rowBurstTicks.begin();
332 while (it != rowBurstTicks.end()) {
333 auto current_it = it++;
334 if (getBurstWindow(curTick()) > *current_it) {
335 DPRINTF(MemCtrl, "Removing burstTick for %d\n", *current_it);
336 rowBurstTicks.erase(current_it);
337 }
338 }
339}
340
341void
343{
344 auto it = colBurstTicks.begin();
345 while (it != colBurstTicks.end()) {
346 auto current_it = it++;
347 if (getBurstWindow(curTick()) > *current_it) {
348 DPRINTF(MemCtrl, "Removing burstTick for %d\n", *current_it);
349 colBurstTicks.erase(current_it);
350 }
351 }
352}
353
354void
360
361Tick
362HBMCtrl::verifySingleCmd(Tick cmd_tick, Tick max_cmds_per_burst, bool row_cmd)
363{
364 // start with assumption that there is no contention on command bus
365 Tick cmd_at = cmd_tick;
366
367 // get tick aligned to burst window
368 Tick burst_tick = getBurstWindow(cmd_tick);
369
370 // verify that we have command bandwidth to issue the command
371 // if not, iterate over next window(s) until slot found
372
373 if (row_cmd) {
374 while (rowBurstTicks.count(burst_tick) >= max_cmds_per_burst) {
375 DPRINTF(MemCtrl, "Contention found on row command bus at %d\n",
376 burst_tick);
377 burst_tick += commandWindow;
378 cmd_at = burst_tick;
379 }
380 DPRINTF(MemCtrl, "Now can send a row cmd_at %d\n",
381 cmd_at);
382 rowBurstTicks.insert(burst_tick);
383
384 } else {
385 while (colBurstTicks.count(burst_tick) >= max_cmds_per_burst) {
386 DPRINTF(MemCtrl, "Contention found on col command bus at %d\n",
387 burst_tick);
388 burst_tick += commandWindow;
389 cmd_at = burst_tick;
390 }
391 DPRINTF(MemCtrl, "Now can send a col cmd_at %d\n",
392 cmd_at);
393 colBurstTicks.insert(burst_tick);
394 }
395 return cmd_at;
396}
397
398Tick
399HBMCtrl::verifyMultiCmd(Tick cmd_tick, Tick max_cmds_per_burst,
400 Tick max_multi_cmd_split)
401{
402
403 // start with assumption that there is no contention on command bus
404 Tick cmd_at = cmd_tick;
405
406 // get tick aligned to burst window
407 Tick burst_tick = getBurstWindow(cmd_tick);
408
409 // Command timing requirements are from 2nd command
410 // Start with assumption that 2nd command will issue at cmd_at and
411 // find prior slot for 1st command to issue
412 // Given a maximum latency of max_multi_cmd_split between the commands,
413 // find the burst at the maximum latency prior to cmd_at
414 Tick burst_offset = 0;
415 Tick first_cmd_offset = cmd_tick % commandWindow;
416 while (max_multi_cmd_split > (first_cmd_offset + burst_offset)) {
417 burst_offset += commandWindow;
418 }
419 // get the earliest burst aligned address for first command
420 // ensure that the time does not go negative
421 Tick first_cmd_tick = burst_tick - std::min(burst_offset, burst_tick);
422
423 // Can required commands issue?
424 bool first_can_issue = false;
425 bool second_can_issue = false;
426 // verify that we have command bandwidth to issue the command(s)
427 while (!first_can_issue || !second_can_issue) {
428 bool same_burst = (burst_tick == first_cmd_tick);
429 auto first_cmd_count = rowBurstTicks.count(first_cmd_tick);
430 auto second_cmd_count = same_burst ?
431 first_cmd_count + 1 : rowBurstTicks.count(burst_tick);
432
433 first_can_issue = first_cmd_count < max_cmds_per_burst;
434 second_can_issue = second_cmd_count < max_cmds_per_burst;
435
436 if (!second_can_issue) {
437 DPRINTF(MemCtrl, "Contention (cmd2) found on command bus at %d\n",
438 burst_tick);
439 burst_tick += commandWindow;
440 cmd_at = burst_tick;
441 }
442
443 // Verify max_multi_cmd_split isn't violated when command 2 is shifted
444 // If commands initially were issued in same burst, they are
445 // now in consecutive bursts and can still issue B2B
446 bool gap_violated = !same_burst &&
447 ((burst_tick - first_cmd_tick) > max_multi_cmd_split);
448
449 if (!first_can_issue || (!second_can_issue && gap_violated)) {
450 DPRINTF(MemCtrl, "Contention (cmd1) found on command bus at %d\n",
451 first_cmd_tick);
452 first_cmd_tick += commandWindow;
453 }
454 }
455
456 // Add command to burstTicks
457 rowBurstTicks.insert(burst_tick);
458 rowBurstTicks.insert(first_cmd_tick);
459
460 return cmd_at;
461}
462
463void
465{
466
468
469 if (!isTimingMode && system()->isTimingMode()) {
470 // if we switched to timing mode, kick things into action,
471 // and behave as if we restored from a checkpoint
472 startup();
473 pc1Int->startup();
474 } else if (isTimingMode && !system()->isTimingMode()) {
475 // if we switch from timing mode, stop the refresh events to
476 // not cause issues with KVM
477 if (pc1Int) {
479 }
480 }
481
482 // update the mode
484}
485
488{
489 AddrRangeList ranges;
490 ranges.push_back(pc0Int->getAddrRange());
491 ranges.push_back(pc1Int->getAddrRange());
492 return ranges;
493}
494
495} // namespace memory
496} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:210
const AddrRange & range() const
Definition backdoor.hh:140
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition packet.hh:295
bool isRead() const
Definition packet.hh:593
Addr getAddr() const
Definition packet.hh:807
const std::string & cmdString() const
Return the string name of the cmd field (for debugging and tracing).
Definition packet.hh:588
void print(std::ostream &o, int verbosity=0, const std::string &prefix="") const
Definition packet.cc:368
bool isWrite() const
Definition packet.hh:594
unsigned getSize() const
Definition packet.hh:817
bool cacheResponding() const
Definition packet.hh:659
bool isTimingMode() const
Is the system in timing mode?
Definition system.hh:270
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
Definition hbm_ctrl.cc:194
DRAMInterface * pc1Int
Definition hbm_ctrl.hh:195
void recvMemBackdoorReq(const MemBackdoorReq &req, MemBackdoorPtr &_backdoor) override
Definition hbm_ctrl.cc:144
virtual void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition hbm_ctrl.cc:76
AddrRangeList getAddrRanges() override
Definition hbm_ctrl.cc:487
Tick recvAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &backdoor) override
Definition hbm_ctrl.cc:127
bool retryRdReqPC1
Remember if we have to retry a request for second pseudo channel.
Definition hbm_ctrl.hh:79
void recvFunctional(PacketPtr pkt) override
Definition hbm_ctrl.cc:113
virtual void drainResume() override
Resume execution after a successful drain.
Definition hbm_ctrl.cc:464
EventFunctionWrapper respondEventPC1
Definition hbm_ctrl.hh:135
bool recvTimingReq(PacketPtr pkt) override
Definition hbm_ctrl.cc:207
bool writeQueueFullPC1(unsigned int pkt_count) const
Definition hbm_ctrl.cc:170
void pruneBurstTick() override
Remove commands that have already issued from rowBurstTicks and colBurstTicks.
Definition hbm_ctrl.cc:355
virtual void startup() override
startup() is the final initialization call before simulation.
Definition hbm_ctrl.cc:82
std::unordered_multiset< Tick > colBurstTicks
This is used to ensure that the column command bandwidth does not exceed the allowable media constrai...
Definition hbm_ctrl.hh:187
bool readQueueFullPC0(unsigned int pkt_count) const
Check if the read queue partition of both pseudo channels has room for more entries.
Definition hbm_ctrl.cc:181
std::unordered_multiset< Tick > rowBurstTicks
Holds count of row commands issued in burst window starting at defined Tick.
Definition hbm_ctrl.hh:180
Tick recvAtomic(PacketPtr pkt) override
Definition hbm_ctrl.cc:97
EventFunctionWrapper nextReqEventPC1
NextReq and Respond events for second pseudo channel.
Definition hbm_ctrl.hh:134
HBMCtrl(const HBMCtrlParams &p)
Definition hbm_ctrl.cc:46
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.
Definition hbm_ctrl.cc:399
std::deque< MemPacket * > respQueuePC1
Response queue for pkts sent to second pseudo channel The first pseudo channel uses MemCtrl::respQueu...
Definition hbm_ctrl.hh:173
DRAMInterface * pc0Int
Pointers to interfaces of the two pseudo channels pc0Int is same as MemCtrl::dram (it will be pointin...
Definition hbm_ctrl.hh:194
Tick verifySingleCmd(Tick cmd_tick, Tick max_cmds_per_burst, bool row_cmd) override
Check for command bus contention for single cycle command.
Definition hbm_ctrl.cc:362
bool writeQueueFullPC0(unsigned int pkt_count) const
Check if the write queue partition of both pseudo channels has room for more entries.
Definition hbm_ctrl.cc:159
The memory controller is a single-channel memory controller capturing the most important timing const...
Definition mem_ctrl.hh:247
uint32_t writeLowThreshold
Definition mem_ctrl.hh:517
bool recvFunctionalLogic(PacketPtr pkt, MemInterface *mem_intr)
Definition mem_ctrl.cc:1395
bool retryRdReq
Remember if we have to retry a request when available.
Definition mem_ctrl.hh:293
virtual void startup() override
startup() is the final initialization call before simulation.
Definition mem_ctrl.cc:110
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.
Definition mem_ctrl.cc:304
Tick recvAtomicLogic(PacketPtr pkt, MemInterface *mem_intr)
Definition mem_ctrl.cc:136
std::deque< MemPacket * > respQueue
Response queue where read packets wait after we're done working with them, but it's not time to send ...
Definition mem_ctrl.hh:492
uint32_t writeHighThreshold
Definition mem_ctrl.hh:516
std::vector< MemPacketQueue > writeQueue
Definition mem_ctrl.hh:473
MemInterface * dram
Definition mem_ctrl.hh:504
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,...
Definition mem_ctrl.cc:881
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....
Definition mem_ctrl.cc:189
virtual void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition mem_ctrl.cc:100
uint32_t readBufferSize
The following are basic design parameters of the memory controller, and are initialized based on para...
Definition mem_ctrl.hh:514
EventFunctionWrapper nextReqEvent
Definition mem_ctrl.hh:307
std::vector< MemPacketQueue > readQueue
The controller's main read and write queues, with support for QoS reordering.
Definition mem_ctrl.hh:472
bool isTimingMode
Remember if the memory system is in timing mode.
Definition mem_ctrl.hh:288
MemCtrl(const MemCtrlParams &p)
Definition mem_ctrl.cc:60
Tick getBurstWindow(Tick cmd_tick)
Calculate burst window aligned tick.
Definition mem_ctrl.cc:675
virtual void drainResume() override
Resume execution after a successful drain.
Definition mem_ctrl.cc:1452
const Tick commandWindow
Length of a command window, used to check command bandwidth.
Definition mem_ctrl.hh:545
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.
Definition mem_ctrl.hh:495
System * system() const
read the system pointer
Definition mem_ctrl.hh:370
uint8_t schedule(RequestorID id, uint64_t data)
Definition mem_ctrl.cc:217
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)
Definition intmath.hh:110
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition bitfield.hh:79
bool scheduled() const
Determine if the current event is scheduled.
Definition eventq.hh:458
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition logging.hh:236
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition logging.hh:214
HBMCtrl declaration.
MemInterface declaration.
Bitfield< 23, 0 > offset
Definition types.hh:144
Bitfield< 0 > p
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
Tick curTick()
The universal simulation clock.
Definition cur_tick.hh:46
uint64_t Tick
Tick count type.
Definition types.hh:58
statistics::Scalar writeReqs
Definition mem_ctrl.hh:572
statistics::Scalar readReqs
Definition mem_ctrl.hh:571
statistics::Scalar numWrRetry
Definition mem_ctrl.hh:583
statistics::Scalar numRdRetry
Definition mem_ctrl.hh:582
statistics::Scalar bytesReadSys
Definition mem_ctrl.hh:592
statistics::Scalar bytesWrittenSys
Definition mem_ctrl.hh:593
Definition mem.h:38
const std::string & name()
Definition trace.cc:48

Generated on Tue Jun 18 2024 16:24:05 for gem5 by doxygen 1.11.0