2 * Copyright (c) 2012-2014, TU Delft
3 * Copyright (c) 2012-2014, TU Eindhoven
4 * Copyright (c) 2012-2014, TU Kaiserslautern
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the copyright holder nor the names of its
19 * contributors may be used to endorse or promote products derived from
20 * this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
23 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
28 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 * Authors: Karthik Chandrasekar, Matthias Jung, Omar Naji, Sven Goossens
42 #include "CommandAnalysis.h"
43 #include "CmdScheduler.h"
48 CommandAnalysis::CommandAnalysis()
52 CommandAnalysis::CommandAnalysis(const int nbrofBanks
)
54 // Initializing all counters and variables
81 sref_ref_act_cycles
= 0;
82 sref_ref_pre_cycles
= 0;
83 spup_ref_act_cycles
= 0;
84 spup_ref_pre_cycles
= 0;
88 latest_act_cycle
= -1;
89 latest_pre_cycle
= -1;
90 latest_read_cycle
= -1;
91 latest_write_cycle
= -1;
99 bankstate
.resize(nbrofBanks
, 0);
100 last_states
.resize(nbrofBanks
);
107 full_cmd_list
.resize(1, MemCommand::PRE
);
109 activation_cycle
.resize(nbrofBanks
, 0);
112 // function to clear all arrays
113 void CommandAnalysis::clear()
117 full_cmd_list
.clear();
122 // Reads through the trace file, identifies the timestamp, command and bank
123 // If the issued command includes an auto-precharge, adds an explicit
124 // precharge to a cached command list and computes the precharge offset from the
125 // issued command timestamp, when the auto-precharge would kick in
127 void CommandAnalysis::getCommands(const Data::MemorySpecification
& memSpec
,
128 const int nbrofBanks
, std::vector
<MemCommand
>& list
, bool lastupdate
)
130 for (vector
<MemCommand
>::const_iterator i
= list
.begin(); i
!= list
.end(); ++i
) {
131 const MemCommand
& cmd
= *i
;
132 cmd_list
.push_back(cmd
);
134 MemCommand::cmds cmdType
= cmd
.getType();
135 if (cmdType
== MemCommand::ACT
) {
136 activation_cycle
[cmd
.getBank()] = cmd
.getTimeInt64();
137 } else if (cmdType
== MemCommand::RDA
|| cmdType
== MemCommand::WRA
) {
138 // Remove auto-precharge flag from command
139 cmd_list
.back().setType(cmd
.typeWithoutAutoPrechargeFlag());
141 // Add the auto precharge to the list of cached_cmds
142 int64_t preTime
= max(cmd
.getTimeInt64() + cmd
.getPrechargeOffset(memSpec
, cmdType
),
143 activation_cycle
[cmd
.getBank()] + memSpec
.memTimingSpec
.RAS
);
144 cached_cmd
.push_back(MemCommand(MemCommand::PRE
, cmd
.getBank(), static_cast<double>(preTime
)));
148 // Note: the extra pre-cmds at the end of the lists, and the cast to double
149 // of the size vector is probably not desirable.
150 cmd_list
.push_back(MemCommand::PRE
);
151 cached_cmd
.push_back(MemCommand::PRE
);
152 analyse_commands(nbrofBanks
, memSpec
, cmd_list
.size()-1,
153 cached_cmd
.size()-1, lastupdate
);
156 } // CommandAnalysis::getCommands
158 // Checks the auto-precharge cached command list and inserts the explicit
159 // precharges with the appropriate timestamp in the original command list
160 // (by merging) based on their offset from the issuing command. Calls the
161 // evaluate function to analyse this expanded list of commands.
163 void CommandAnalysis::analyse_commands(const int nbrofBanks
,
164 Data::MemorySpecification memSpec
, int64_t nCommands
, int64_t nCached
, bool lastupdate
)
166 full_cmd_list
.resize(1, MemCommand::PRE
);
167 unsigned mCommands
= 0;
168 unsigned mCached
= 0;
169 for (unsigned i
= 0; i
< nCommands
+ nCached
+ 1; i
++) {
170 if (cached_cmd
.size() > 1) {
171 if ((cmd_list
[mCommands
].getTime() > 1) && (init
== 0)) {
172 full_cmd_list
[i
].setType(MemCommand::PREA
);
177 if ((cached_cmd
[mCached
].getTime() > 0) && (cmd_list
.
178 at(mCommands
).getTime() < cached_cmd
[mCached
].
179 getTime()) && ((cmd_list
[mCommands
].getTime() > 0) ||
180 ((cmd_list
[mCommands
].getTime() == 0) && (cmd_list
[mCommands
].
181 getType() != MemCommand::PRE
)))) {
182 full_cmd_list
[i
] = cmd_list
[mCommands
];
184 } else if ((cached_cmd
[mCached
].getTime() > 0) && (cmd_list
[mCommands
].
185 getTime() >= cached_cmd
[mCached
].getTime())) {
186 full_cmd_list
[i
] = cached_cmd
[mCached
];
188 } else if (cached_cmd
[mCached
].getTime() == 0) {
189 if ((cmd_list
[mCommands
].getTime() > 0) || ((cmd_list
[mCommands
].
190 getTime() == 0) && (cmd_list
[mCommands
].
191 getType() != MemCommand::PRE
))) {
192 full_cmd_list
[i
] = cmd_list
[mCommands
];
195 } else if (cmd_list
[mCommands
].getTime() == 0) {
196 full_cmd_list
[i
] = cached_cmd
[mCached
];
201 if ((cmd_list
[mCommands
].getTime() > 1) && (init
== 0)) {
202 full_cmd_list
[i
].setType(MemCommand::PREA
);
207 if ((cmd_list
[mCommands
].getTime() > 0) || ((cmd_list
.
208 at(mCommands
).getTime() == 0) && (cmd_list
[mCommands
].
209 getType() != MemCommand::PRE
))) {
210 full_cmd_list
[i
] = cmd_list
[mCommands
];
215 full_cmd_list
.resize(full_cmd_list
.size() + 1, MemCommand::PRE
);
218 full_cmd_list
.pop_back();
220 full_cmd_list
.pop_back();
223 full_cmd_list
.resize(full_cmd_list
.size() + 1, MemCommand::NOP
);
224 full_cmd_list
[full_cmd_list
.size() - 1].setTime(full_cmd_list
225 [full_cmd_list
.size() - 2].getTime() + timeToCompletion(memSpec
,
226 full_cmd_list
[full_cmd_list
.size() - 2].getType()) - 1);
229 evaluate(memSpec
, full_cmd_list
, nbrofBanks
);
230 } // CommandAnalysis::analyse_commands
232 // To get the time of completion of the issued command
233 // Derived based on JEDEC specifications
235 int CommandAnalysis::timeToCompletion(const MemorySpecification
&
236 memSpec
, MemCommand::cmds type
)
239 const MemTimingSpec
& memTimingSpec
= memSpec
.memTimingSpec
;
240 const MemArchitectureSpec
& memArchSpec
= memSpec
.memArchSpec
;
242 if (type
== MemCommand::RD
) {
243 offset
= static_cast<int>(memTimingSpec
.RL
+
244 memTimingSpec
.DQSCK
+ 1 + (memArchSpec
.burstLength
/
245 memArchSpec
.dataRate
));
246 } else if (type
== MemCommand::WR
) {
247 offset
= static_cast<int>(memTimingSpec
.WL
+
248 (memArchSpec
.burstLength
/ memArchSpec
.dataRate
) +
250 } else if (type
== MemCommand::ACT
) {
251 offset
= static_cast<int>(memTimingSpec
.RCD
);
252 } else if ((type
== MemCommand::PRE
) || (type
== MemCommand::PREA
)) {
253 offset
= static_cast<int>(memTimingSpec
.RP
);
256 } // CommandAnalysis::timeToCompletion
258 // Used to analyse a given list of commands and identify command timings
259 // and memory state transitions
260 void CommandAnalysis::evaluate(const MemorySpecification
& memSpec
,
261 vector
<MemCommand
>& cmd_list
, int nbrofBanks
)
263 // for each command identify timestamp, type and bank
264 for (unsigned cmd_list_counter
= 0; cmd_list_counter
< cmd_list
.size();
265 cmd_list_counter
++) {
267 int type
= cmd_list
[cmd_list_counter
].getType();
269 int bank
= cmd_list
[cmd_list_counter
].getBank();
270 // Command Issue timestamp in clock cycles (cc)
271 int64_t timestamp
= cmd_list
[cmd_list_counter
].getTimeInt64();
273 if (type
== MemCommand::ACT
) {
274 // If command is ACT - update number of acts, bank state of the
275 // target bank, first and latest activation cycle and the memory
276 // state. Update the number of precharged/idle-precharged cycles.
278 if (bankstate
[bank
] == 1) {
279 printWarning("Bank is already active!", type
, timestamp
, bank
);
282 if (mem_state
== 0) {
283 first_act_cycle
= timestamp
;
284 precycles
+= max(zero
, timestamp
- last_pre_cycle
);
285 idle_pre_update(memSpec
, timestamp
, latest_pre_cycle
);
287 latest_act_cycle
= timestamp
;
289 } else if (type
== MemCommand::RD
) {
290 // If command is RD - update number of reads and read cycle. Check
291 // for active idle cycles (if any).
292 if (bankstate
[bank
] == 0) {
293 printWarning("Bank is not active!", type
, timestamp
, bank
);
296 idle_act_update(memSpec
, latest_read_cycle
, latest_write_cycle
,
297 latest_act_cycle
, timestamp
);
298 latest_read_cycle
= timestamp
;
299 } else if (type
== MemCommand::WR
) {
300 // If command is WR - update number of writes and write cycle. Check
301 // for active idle cycles (if any).
302 if (bankstate
[bank
] == 0) {
303 printWarning("Bank is not active!", type
, timestamp
, bank
);
306 idle_act_update(memSpec
, latest_read_cycle
, latest_write_cycle
,
307 latest_act_cycle
, timestamp
);
308 latest_write_cycle
= timestamp
;
309 } else if (type
== MemCommand::REF
) {
310 // If command is REF - update number of refreshes, set bank state of
311 // all banks to ACT, set the last PRE cycles at RFC-RP cycles from
312 // timestamp, set the number of active cycles to RFC-RP and check
313 // for active and precharged cycles and idle active and idle
314 // precharged cycles before refresh. Change memory state to 0.
315 printWarningIfActive("One or more banks are active! REF requires all banks to be precharged.", type
, timestamp
, bank
);
317 idle_pre_update(memSpec
, timestamp
, latest_pre_cycle
);
318 first_act_cycle
= timestamp
;
319 precycles
+= max(zero
, timestamp
- last_pre_cycle
);
320 last_pre_cycle
= timestamp
+ memSpec
.memTimingSpec
.RFC
-
321 memSpec
.memTimingSpec
.RP
;
322 latest_pre_cycle
= last_pre_cycle
;
323 actcycles
+= memSpec
.memTimingSpec
.RFC
- memSpec
.memTimingSpec
.RP
;
325 for (int j
= 0; j
< nbrofBanks
; j
++) {
328 } else if (type
== MemCommand::PRE
) {
329 // If command is explicit PRE - update number of precharges, bank
330 // state of the target bank and last and latest precharge cycle.
331 // Calculate the number of active cycles if the memory was in the
332 // active state before, but there is a state transition to PRE now.
333 // If not, update the number of precharged cycles and idle cycles.
334 // Update memory state if needed.
335 if (bankstate
[bank
] == 1) {
340 if (mem_state
== 1) {
341 actcycles
+= max(zero
, timestamp
- first_act_cycle
);
342 last_pre_cycle
= timestamp
;
343 idle_act_update(memSpec
, latest_read_cycle
, latest_write_cycle
,
344 latest_act_cycle
, timestamp
);
345 } else if (mem_state
== 0) {
346 precycles
+= max(zero
, timestamp
- last_pre_cycle
);
347 idle_pre_update(memSpec
, timestamp
, latest_pre_cycle
);
348 last_pre_cycle
= timestamp
;
350 latest_pre_cycle
= timestamp
;
356 } else if (type
== MemCommand::PREA
) {
357 // If command is explicit PREA (precharge all banks) - update
358 // number of precharges by the number of banks, update the bank
359 // state of all banks to PRE and set the precharge cycle.
360 // Calculate the number of active cycles if the memory was in the
361 // active state before, but there is a state transition to PRE now.
362 // If not, update the number of precharged cycles and idle cycles.
363 if (timestamp
== 0) {
366 numberofpres
+= mem_state
;
370 actcycles
+= max(zero
, timestamp
- first_act_cycle
);
371 idle_act_update(memSpec
, latest_read_cycle
, latest_write_cycle
,
372 latest_act_cycle
, timestamp
);
373 } else if (mem_state
== 0) {
374 precycles
+= max(zero
, timestamp
- last_pre_cycle
);
375 idle_pre_update(memSpec
, timestamp
, latest_pre_cycle
);
378 latest_pre_cycle
= timestamp
;
379 last_pre_cycle
= timestamp
;
383 for (int j
= 0; j
< nbrofBanks
; j
++) {
386 } else if (type
== MemCommand::PDN_F_ACT
) {
387 // If command is fast-exit active power-down - update number of
388 // power-downs, set the power-down cycle and the memory mode to
389 // fast-exit active power-down. Save states of all the banks from
390 // the cycle before entering active power-down, to be returned to
391 // after powering-up. Update active and active idle cycles.
392 printWarningIfNotActive("All banks are precharged! Incorrect use of Active Power-Down.", type
, timestamp
, bank
);
394 for (int j
= 0; j
< nbrofBanks
; j
++) {
395 last_states
[j
] = bankstate
[j
];
397 pdn_cycle
= timestamp
;
398 actcycles
+= max(zero
, timestamp
- first_act_cycle
);
399 idle_act_update(memSpec
, latest_read_cycle
, latest_write_cycle
,
400 latest_act_cycle
, timestamp
);
401 mem_state
= CommandAnalysis::MS_PDN_F_ACT
;
402 } else if (type
== MemCommand::PDN_S_ACT
) {
403 // If command is slow-exit active power-down - update number of
404 // power-downs, set the power-down cycle and the memory mode to
405 // slow-exit active power-down. Save states of all the banks from
406 // the cycle before entering active power-down, to be returned to
407 // after powering-up. Update active and active idle cycles.
408 printWarningIfNotActive("All banks are precharged! Incorrect use of Active Power-Down.", type
, timestamp
, bank
);
410 for (int j
= 0; j
< nbrofBanks
; j
++) {
411 last_states
[j
] = bankstate
[j
];
413 pdn_cycle
= timestamp
;
414 actcycles
+= max(zero
, timestamp
- first_act_cycle
);
415 idle_act_update(memSpec
, latest_read_cycle
, latest_write_cycle
,
416 latest_act_cycle
, timestamp
);
417 mem_state
= CommandAnalysis::MS_PDN_S_ACT
;
418 } else if (type
== MemCommand::PDN_F_PRE
) {
419 // If command is fast-exit precharged power-down - update number of
420 // power-downs, set the power-down cycle and the memory mode to
421 // fast-exit precahrged power-down. Update precharged and precharged
423 printWarningIfActive("One or more banks are active! Incorrect use of Precharged Power-Down.", type
, timestamp
, bank
);
425 pdn_cycle
= timestamp
;
426 precycles
+= max(zero
, timestamp
- last_pre_cycle
);
427 idle_pre_update(memSpec
, timestamp
, latest_pre_cycle
);
428 mem_state
= CommandAnalysis::MS_PDN_F_PRE
;
429 } else if (type
== MemCommand::PDN_S_PRE
) {
430 // If command is slow-exit precharged power-down - update number of
431 // power-downs, set the power-down cycle and the memory mode to
432 // slow-exit precahrged power-down. Update precharged and precharged
434 printWarningIfActive("One or more banks are active! Incorrect use of Precharged Power-Down.", type
, timestamp
, bank
);
436 pdn_cycle
= timestamp
;
437 precycles
+= max(zero
, timestamp
- last_pre_cycle
);
438 idle_pre_update(memSpec
, timestamp
, latest_pre_cycle
);
439 mem_state
= CommandAnalysis::MS_PDN_S_PRE
;
440 } else if (type
== MemCommand::PUP_ACT
) {
441 // If command is power-up in the active mode - check the power-down
442 // exit-mode employed (fast or slow), update the number of power-down
443 // and power-up cycles and the latest and first act cycle. Also, reset
444 // all the individual bank states to the respective saved states
445 // before entering power-down.
446 if (mem_state
== CommandAnalysis::MS_PDN_F_ACT
) {
447 f_act_pdcycles
+= max(zero
, timestamp
- pdn_cycle
);
448 pup_act_cycles
+= memSpec
.memTimingSpec
.XP
;
449 latest_act_cycle
= max(timestamp
, timestamp
+
450 memSpec
.memTimingSpec
.XP
- memSpec
.memTimingSpec
.RCD
);
451 } else if (mem_state
== CommandAnalysis::MS_PDN_S_ACT
) {
452 s_act_pdcycles
+= max(zero
, timestamp
- pdn_cycle
);
453 if (memSpec
.memArchSpec
.dll
== false) {
454 pup_act_cycles
+= memSpec
.memTimingSpec
.XP
;
455 latest_act_cycle
= max(timestamp
, timestamp
+
456 memSpec
.memTimingSpec
.XP
- memSpec
.memTimingSpec
.RCD
);
458 pup_act_cycles
+= memSpec
.memTimingSpec
.XPDLL
-
459 memSpec
.memTimingSpec
.RCD
;
460 latest_act_cycle
= max(timestamp
, timestamp
+
461 memSpec
.memTimingSpec
.XPDLL
-
462 (2 * memSpec
.memTimingSpec
.RCD
));
464 } else if ((mem_state
!= CommandAnalysis::MS_PDN_S_ACT
) || (mem_state
!=
465 CommandAnalysis::MS_PDN_F_ACT
)) {
466 cerr
<< "Incorrect use of Active Power-Up!" << endl
;
469 for (int j
= 0; j
< nbrofBanks
; j
++) {
470 bankstate
[j
] = last_states
[j
];
471 mem_state
+= last_states
[j
];
473 first_act_cycle
= timestamp
;
474 } else if (type
== MemCommand::PUP_PRE
) {
475 // If command is power-up in the precharged mode - check the power-down
476 // exit-mode employed (fast or slow), update the number of power-down
477 // and power-up cycles and the latest and last pre cycle.
478 if (mem_state
== CommandAnalysis::MS_PDN_F_PRE
) {
479 f_pre_pdcycles
+= max(zero
, timestamp
- pdn_cycle
);
480 pup_pre_cycles
+= memSpec
.memTimingSpec
.XP
;
481 latest_pre_cycle
= max(timestamp
, timestamp
+
482 memSpec
.memTimingSpec
.XP
- memSpec
.memTimingSpec
.RP
);
483 } else if (mem_state
== CommandAnalysis::MS_PDN_S_PRE
) {
484 s_pre_pdcycles
+= max(zero
, timestamp
- pdn_cycle
);
485 if (memSpec
.memArchSpec
.dll
== false) {
486 pup_pre_cycles
+= memSpec
.memTimingSpec
.XP
;
487 latest_pre_cycle
= max(timestamp
, timestamp
+
488 memSpec
.memTimingSpec
.XP
- memSpec
.memTimingSpec
.RP
);
490 pup_pre_cycles
+= memSpec
.memTimingSpec
.XPDLL
-
491 memSpec
.memTimingSpec
.RCD
;
492 latest_pre_cycle
= max(timestamp
, timestamp
+
493 memSpec
.memTimingSpec
.XPDLL
- memSpec
.memTimingSpec
.RCD
-
494 memSpec
.memTimingSpec
.RP
);
496 } else if ((mem_state
!= CommandAnalysis::MS_PDN_S_PRE
) || (mem_state
!=
497 CommandAnalysis::MS_PDN_F_PRE
)) {
498 cerr
<< "Incorrect use of Precharged Power-Up!" << endl
;
501 last_pre_cycle
= timestamp
;
502 } else if (type
== MemCommand::SREN
) {
503 // If command is self-refresh - update number of self-refreshes,
504 // set memory state to SREF, update precharge and idle precharge
505 // cycles and set the self-refresh cycle.
506 printWarningIfActive("One or more banks are active! SREF requires all banks to be precharged.", type
, timestamp
, bank
);
508 sref_cycle
= timestamp
;
509 precycles
+= max(zero
, timestamp
- last_pre_cycle
);
510 idle_pre_update(memSpec
, timestamp
, latest_pre_cycle
);
511 mem_state
= CommandAnalysis::MS_SREF
;
512 } else if (type
== MemCommand::SREX
) {
513 // If command is self-refresh exit - update the number of self-refresh
514 // clock cycles, number of active and precharged auto-refresh clock
515 // cycles during self-refresh and self-refresh exit based on the number
516 // of cycles in the self-refresh mode and auto-refresh duration (RFC).
517 // Set the last and latest precharge cycle accordingly and set the
518 // memory state to 0.
519 if (mem_state
!= CommandAnalysis::MS_SREF
) {
520 cerr
<< "Incorrect use of Self-Refresh Power-Up!" << endl
;
522 if (max(zero
, timestamp
- sref_cycle
) >= memSpec
.memTimingSpec
.RFC
) {
523 sref_cycles
+= max(zero
, timestamp
- sref_cycle
524 - memSpec
.memTimingSpec
.RFC
);
525 sref_ref_act_cycles
+= memSpec
.memTimingSpec
.RFC
-
526 memSpec
.memTimingSpec
.RP
;
527 sref_ref_pre_cycles
+= memSpec
.memTimingSpec
.RP
;
528 last_pre_cycle
= timestamp
;
529 if (memSpec
.memArchSpec
.dll
== false) {
530 spup_cycles
+= memSpec
.memTimingSpec
.XS
;
531 latest_pre_cycle
= max(timestamp
, timestamp
+
532 memSpec
.memTimingSpec
.XS
- memSpec
.memTimingSpec
.RP
);
534 spup_cycles
+= memSpec
.memTimingSpec
.XSDLL
-
535 memSpec
.memTimingSpec
.RCD
;
536 latest_pre_cycle
= max(timestamp
, timestamp
+
537 memSpec
.memTimingSpec
.XSDLL
- memSpec
.memTimingSpec
.RCD
538 - memSpec
.memTimingSpec
.RP
);
541 int64_t sref_diff
= memSpec
.memTimingSpec
.RFC
- memSpec
.memTimingSpec
.RP
;
542 int64_t sref_pre
= max(zero
, timestamp
- sref_cycle
- sref_diff
);
543 int64_t spup_pre
= memSpec
.memTimingSpec
.RP
- sref_pre
;
544 int64_t sref_act
= max(zero
, timestamp
- sref_cycle
);
545 int64_t spup_act
= memSpec
.memTimingSpec
.RFC
- sref_act
;
547 if (max(zero
, timestamp
- sref_cycle
) >= sref_diff
) {
548 sref_ref_act_cycles
+= sref_diff
;
549 sref_ref_pre_cycles
+= sref_pre
;
550 spup_ref_pre_cycles
+= spup_pre
;
551 last_pre_cycle
= timestamp
+ spup_pre
;
552 if (memSpec
.memArchSpec
.dll
== false) {
553 spup_cycles
+= memSpec
.memTimingSpec
.XS
- spup_pre
;
554 latest_pre_cycle
= max(timestamp
, timestamp
+
555 memSpec
.memTimingSpec
.XS
- spup_pre
-
556 memSpec
.memTimingSpec
.RP
);
558 spup_cycles
+= memSpec
.memTimingSpec
.XSDLL
-
559 memSpec
.memTimingSpec
.RCD
- spup_pre
;
560 latest_pre_cycle
= max(timestamp
, timestamp
+
561 memSpec
.memTimingSpec
.XSDLL
- memSpec
.memTimingSpec
.RCD
-
562 spup_pre
- memSpec
.memTimingSpec
.RP
);
565 sref_ref_act_cycles
+= sref_act
;
566 spup_ref_act_cycles
+= spup_act
;
567 spup_ref_pre_cycles
+= memSpec
.memTimingSpec
.RP
;
568 last_pre_cycle
= timestamp
+ spup_act
+ memSpec
.memTimingSpec
.RP
;
569 if (memSpec
.memArchSpec
.dll
== false) {
570 spup_cycles
+= memSpec
.memTimingSpec
.XS
- spup_act
-
571 memSpec
.memTimingSpec
.RP
;
572 latest_pre_cycle
= max(timestamp
, timestamp
+
573 memSpec
.memTimingSpec
.XS
- spup_act
-
574 (2 * memSpec
.memTimingSpec
.RP
));
576 spup_cycles
+= memSpec
.memTimingSpec
.XSDLL
-
577 memSpec
.memTimingSpec
.RCD
- spup_act
-
578 memSpec
.memTimingSpec
.RP
;
579 latest_pre_cycle
= max(timestamp
, timestamp
+
580 memSpec
.memTimingSpec
.XSDLL
- memSpec
.memTimingSpec
.RCD
-
581 spup_act
- (2 * memSpec
.memTimingSpec
.RP
));
586 } else if ((type
== MemCommand::END
) || (type
== MemCommand::NOP
)) {
587 // May be optionally used at the end of memory trace for better accuracy
588 // Update all counters based on completion of operations.
589 if ((mem_state
> 0) && (mem_state
< 9)) {
590 actcycles
+= max(zero
, timestamp
- first_act_cycle
);
591 idle_act_update(memSpec
, latest_read_cycle
, latest_write_cycle
,
592 latest_act_cycle
, timestamp
);
593 } else if (mem_state
== 0) {
594 precycles
+= max(zero
, timestamp
- last_pre_cycle
);
595 idle_pre_update(memSpec
, timestamp
, latest_pre_cycle
);
596 } else if (mem_state
== CommandAnalysis::MS_PDN_F_ACT
) {
597 f_act_pdcycles
+= max(zero
, timestamp
- pdn_cycle
);
598 } else if (mem_state
== CommandAnalysis::MS_PDN_S_ACT
) {
599 s_act_pdcycles
+= max(zero
, timestamp
- pdn_cycle
);
600 } else if (mem_state
== CommandAnalysis::MS_PDN_F_PRE
) {
601 f_pre_pdcycles
+= max(zero
, timestamp
- pdn_cycle
);
602 } else if (mem_state
== CommandAnalysis::MS_PDN_S_PRE
) {
603 s_pre_pdcycles
+= max(zero
, timestamp
- pdn_cycle
);
604 } else if (mem_state
== CommandAnalysis::MS_SREF
) {
605 sref_cycles
+= max(zero
, timestamp
- sref_cycle
);
609 } // CommandAnalysis::evaluate
611 // To update idle period information whenever active cycles may be idle
612 void CommandAnalysis::idle_act_update(const MemorySpecification
& memSpec
,
613 int64_t latest_read_cycle
, int64_t latest_write_cycle
,
614 int64_t latest_act_cycle
, int64_t timestamp
)
616 if (latest_read_cycle
>= 0) {
617 end_read_op
= latest_read_cycle
+ timeToCompletion(memSpec
,
621 if (latest_write_cycle
>= 0) {
622 end_write_op
= latest_write_cycle
+ timeToCompletion(memSpec
,
626 if (latest_act_cycle
>= 0) {
627 end_act_op
= latest_act_cycle
+ timeToCompletion(memSpec
,
628 MemCommand::ACT
) - 1;
631 idlecycles_act
+= max(zero
, timestamp
- max(max(end_read_op
, end_write_op
),
633 } // CommandAnalysis::idle_act_update
635 // To update idle period information whenever precharged cycles may be idle
636 void CommandAnalysis::idle_pre_update(const MemorySpecification
& memSpec
,
637 int64_t timestamp
, int64_t latest_pre_cycle
)
639 if (latest_pre_cycle
> 0) {
640 idlecycles_pre
+= max(zero
, timestamp
- latest_pre_cycle
-
641 memSpec
.memTimingSpec
.RP
);
642 } else if (latest_pre_cycle
== 0) {
643 idlecycles_pre
+= max(zero
, timestamp
- latest_pre_cycle
);
647 void CommandAnalysis::printWarningIfActive(const string
& warning
, int type
, int64_t timestamp
, int bank
)
649 if (mem_state
!= 0) {
650 printWarning(warning
, type
, timestamp
, bank
);
654 void CommandAnalysis::printWarningIfNotActive(const string
& warning
, int type
, int64_t timestamp
, int bank
)
656 if (mem_state
== 0) {
657 printWarning(warning
, type
, timestamp
, bank
);
661 void CommandAnalysis::printWarning(const string
& warning
, int type
, int64_t timestamp
, int bank
)
663 cerr
<< "WARNING: " << warning
<< endl
;
664 cerr
<< "Command: " << type
<< ", Timestamp: " << timestamp
<<
665 ", Bank: " << bank
<< endl
;