Use ReadResp instead of LoadLockedResp for LoadLockedReq responses.
[gem5.git] / src / mem / dram.cc
1 /*
2 * Copyright (c) 2004 The Regents of The University of Michigan
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 * Authors: Ali Saidi
29 * Ron Dreslinski
30 */
31
32 /*
33 Copyright (c) 2000 Computer Engineering and Communication Networks Lab (TIK)
34 Swiss Federal Institute of Technology (ETH) Zurich, Switzerland
35
36 All rights reserved.
37 Permission is hereby granted, without written agreement and without
38 license or royalty fees, to use, copy, modify, and distribute this
39 software and its documentation for any purpose, provided that the above
40 copyright notice and the following two paragraphs appear in all copies
41 of this software.
42
43 IN NO EVENT SHALL THE TIK OR THE ETH ZURICH BE LIABLE TO ANY PARTY
44 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
45 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
46 THE TIK OR THE ETH ZURICH HAVE BEEN ADVISED OF THE POSSIBILITY OF
47 SUCH DAMAGE.
48
49 THE TIK AND THE ETH ZURICH SPECIFICALLY DISCLAIM ANY WARRANTIES,
50 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
51 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
52 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND TIK AND THE ETH ZURICH
53 HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
54 ENHANCEMENTS, OR MODIFICATIONS.
55 */
56
57 /* authors: Andreas Romer 4/99 - 7/99
58 Matthias Gries 4/99 - 2/01
59
60
61 References: http://www.tik.ee.ethz.ch/
62 ======================================
63 -> Publications http://www.tik.ee.ethz.ch/db/tik/publications/form_search_publications.php3
64
65
66 Matthias Gries: A Survey of Synchronous RAM Architectures.
67 TIK Report Nr. 71, Computer Engineering and Networks Lab (TIK),
68 Swiss Federal Institute of Technology (ETH) Zurich, April, 1999
69
70 -> DRAM survey
71
72
73 Matthias Gries, Andreas Romer: Performance Evaluation of Recent
74 DRAM Architectures for Embedded Systems.
75 TIK Report Nr. 82, Computer Engineering and Networks Lab (TIK),
76 Swiss Federal Institute of Technology (ETH) Zurich, November, 1999.
77
78 -> description of the DRAM and controller models for SimpleScalar in the appendix
79 (note that the current software version additionally supports overlapping in
80 closed-page mode with slightly modified timing)
81
82
83 Matthias Gries: The Impact of Recent DRAM Architectures on Embedded Systems Performance.
84 Euromicro2000, Symposium on Digital Systems Design, IEEE Computer, Maastricht, Netherlands,
85 Vol. 1, pages 282-289, September, 2000.
86
87 -> performance study with SimpleScalar
88
89
90 Matthias Gries: Modeling a Memory Subsystem with Petri Nets: a Case Study.
91 A. Yakovlev, L. Gomes, and L. Lavagno (Eds), Hardware Design and Petri Nets,
92 Kluwer Academic, pages 291-310, March, 2000.
93
94 -> SDRAM + controller performance model as a high-level Petri net
95 */
96
97 /**
98 * @file
99 * Definition of a DRAM like main memory.
100 */
101
102 #include <cstdlib>
103 #include <string>
104
105 #include "mem/dram.hh"
106
107 extern int maxThreadsPerCPU;
108
109 /* SDRAM system: PC100/PC133 2-2-2 DIMM timing according to
110 PC SDRAM Specification, Rev. 1.7, Intel Corp, Nov. 1999.
111
112 64 bit DIMM consists of four 16x organized 256 Mbit SDRAMs, 128 MByte of main memory in total.*/
113 /* the settings above must be changed if another memory is used */
114 /* DRDRAM system: 16 bit channel, four chips (single RIMM), 128 MByte of main memory in total.
115 Timing: Rambus Inc, Direct RDRAM, preliminary information, 256/288Mbit: 40-800 timing */
116
117
118 #define DR_STACK_BASE 0x8000000 /* total size of memory: 128 Mbyte */
119 #define DR_BANK_SIZE 0x100000 /* size of a bank : 1 Mbyte */
120 #define DR_ROW_SIZE 0x800 /* size of a row : 2 Kbyte */
121 #define DR_NUM_BANKS (DR_STACK_BASE/DR_BANK_SIZE) /* number of banks : 128 */
122 #define DR_NUM_ROWS (DR_BANK_SIZE/DR_ROW_SIZE) /* number of rows per bank: 512 */
123 #define DR_DATA_BASE 0x4000000 /* Size of textsegment : 64 Mbyte */
124 #define DR_NUM_BYTE_MEM 16 /* data packet capacity: 16 byte */
125 #define DR_NUM_DEVS 4 /* number of devices along channel */
126 #define DR_BANK_SAMP 16 /* 16 banks are together in one group in each device: bank 15 and 16 have no shared SAMPs */
127 #define DR_T_PACKET 4 /* number of cycles (in 400 MHz) the memory needs to deliver a data packet */
128 #define DR_T_RCD 7 /* RAS to CAS delay */
129 #define DR_T_CAC 8 /* read access delay: number of cylces from read to data (trailing to leading edge of packet!) */
130 #define DR_T_CWD 6 /* Write delay: number of cylces from write to write data (trailing to leading edge of packet!) */
131 #define DR_T_RP 8 /* row precharge delay */
132 #define DR_T_RTR 8 /* retire delay*/
133 #define DR_T_RDP 4 /* min delay from read to precharge in cycles */
134 #define DR_T_PP 8 /* precharge to precharge time to any bank in the same device */
135 #define DR_T_RAS 20 /* minimal row active time */
136 /*the settings above need to be changed if the memory is altered*/
137 #define DR_DYNAMIC_SIZE (DR_STACK_BASE - DR_DATA_BASE) /* size of the heap and stack at most: 64 Mbyte */
138 // #define DR_NUM_BANKS (DR_STACK_BASE/DR_BANK_SIZE) /* number of banks : 128 */
139 // #define DR_NUM_ROWS (DR_BANK_SIZE/DR_ROW_SIZE) /* number of rows per bank: 512 */
140 #define DR_T_OWR (DR_T_CWD + DR_T_PACKET - DR_T_RTR) /* overlap after write retire */
141 #define DR_T_HELP (DR_T_CAC+DR_T_PACKET-DR_T_RDP+DR_T_PACKET) /* used for read after read with precharge */
142 /*delays until data is ready/written to the memory for the DRDRAM*/
143 #define DR_T_READ_READ_SROW (DR_T_CAC + DR_T_PACKET) /* RAR, row hit, current bank */
144 #define DR_T_READ_WRITE_SROW (DR_T_CAC + DR_T_PACKET) /* RAW, row hit, current bank */
145 #define DR_T_WRITE_READ_SROW (DR_T_CWD + DR_T_PACKET) /* WAR, row hit, current bank */
146 #define DR_T_WRITE_WRITE_SROW (DR_T_CWD + DR_T_PACKET) /* WAW, row hit, current bank */
147 #define DR_T_READ_READ_SBANK (DR_T_RP+DR_T_RCD+DR_T_CAC+DR_T_PACKET) /* RAR, row miss, current bank */
148 #define DR_T_READ_WRITE_SBANK (DR_T_RP+DR_T_RCD+DR_T_CAC+DR_T_PACKET) /* RAW, row miss, current bank */
149 #define DR_T_WRITE_READ_SBANK (DR_T_RP+DR_T_RCD+DR_T_CWD+DR_T_PACKET) /* WAR, row miss, current bank */
150 #define DR_T_WRITE_WRITE_SBANK (DR_T_RP+DR_T_RCD+DR_T_CWD+DR_T_PACKET) /* WAR, row miss, current bank */
151 #define DR_T_READ_READ_OBANK (DR_T_PP+DR_T_RP+DR_T_RCD+DR_T_CAC+DR_T_PACKET) /* RAR, row miss, another bank */
152 #define DR_T_READ_WRITE_OBANK (DR_T_PP+DR_T_RP+DR_T_RCD+DR_T_CAC+DR_T_PACKET) /* RAW, row miss, another bank */
153 #define DR_T_WRITE_READ_OBANK (DR_T_PP+DR_T_RP+DR_T_RCD+DR_T_CWD+DR_T_PACKET) /* WAR, row miss, another bank */
154 #define DR_T_WRITE_WRITE_OBANK (DR_T_PP+DR_T_RP+DR_T_RCD+DR_T_CWD+DR_T_PACKET) /* WAR, row miss, another bank */
155 /* best-case latencies (due to overlap / row hits in another bank) */
156 #define DR_BEST_T_READ_READ_SROW 0 /* RAR, row hit, current bank */
157 #define DR_BEST_T_READ_WRITE_SROW (DR_T_CAC+DR_T_PACKET-DR_T_OWR) /* RAW, row hit, current bank */
158 #define DR_BEST_T_WRITE_READ_SROW 0 /* WAR, row hit, current bank */
159 #define DR_BEST_T_WRITE_WRITE_SROW (DR_T_CWD+DR_T_PACKET-DR_T_OWR) /* WAR, row hit, current bank */
160 #define DR_BEST_T_READ_READ_SBANK (DR_T_RCD + DR_T_CAC) /* RAR, row miss, current bank */
161 #define DR_BEST_T_READ_WRITE_SBANK (DR_T_RP-DR_T_OWR+DR_T_RCD+DR_T_CAC+DR_T_PACKET) /* RAW, row miss, current bank */
162 #define DR_BEST_T_WRITE_READ_SBANK (DR_T_RCD+DR_T_CWD) /* WAR, row miss, current bank */
163 #define DR_BEST_T_WRITE_WRITE_SBANK (DR_T_RP-DR_T_OWR+DR_T_RCD+DR_T_CWD+DR_T_PACKET) /* WAW, row miss, current bank */
164 #define DR_BEST_T_READ_READ_OBANK 0 /* RAR, row miss/hit, another bank */
165 #define DR_BEST_T_READ_WRITE_OBANK (DR_T_PACKET+DR_T_CAC-DR_T_OWR) /* RAW, row miss/hit, another bank */
166 #define DR_BEST_T_WRITE_READ_OBANK 0 /* WAR, row miss/hit, another bank */
167 #define DR_BEST_T_WRITE_WRITE_OBANK 0 /* WAW, row miss/hit, another bank */
168 #define DR_BEST_T_READ_WRITE_ODEV (DR_T_CAC-DR_T_CWD) /* RAW, row miss/hit, another device */
169
170
171 #define MIN(a,b) ((a<b) ? a : b)
172 #define SD_ROW_SIZE 0x1000 /* size of a row : 4 Kbyte */
173
174
175
176 DRAMMemory::DRAMMemory(const Params *p)
177 : PhysicalMemory(p), cpu_ratio(p->cpu_ratio), bus_width(p->bus_width),
178 mem_type(p->mem_type), mem_actpolicy(p->mem_actpolicy),
179 memctrladdr_type(p->memctrladdr_type), act_lat(p->act_lat),
180 cas_lat(p->cas_lat), war_lat(p->war_lat),
181 pre_lat(p->pre_lat), dpl_lat(p->dpl_lat),
182 trc_lat(p->trc_lat), num_banks(p->num_banks),
183 num_cpus(p->num_cpus), last_dev(DR_NUM_DEVS+1),
184 lastCmdIsRead(true), precharge(0), same_row_read_access(0), srr_after_read(0),
185 srr_after_write(0), same_row_write_access(0), srw_after_read(0),
186 srw_after_write(0), same_bank_read_access(0), sbr_after_read(0),
187 sbr_after_write(0), same_bank_write_access(0), sbw_after_read(0),
188 sbw_after_write(0), other_bank_read_access_hit(0), obr_after_read_hit(0),
189 obr_after_write_hit(0), other_bank_write_access_hit(0),
190 obw_after_read_hit(0), obw_after_write_hit(0), obr_after_read_miss(0),
191 obr_after_write_miss(0),
192 obw_after_read_miss(0), obw_after_write_miss(0), total_access(0),
193 adjacent_access(0), adjacent_read(0), adjacent_write(0),
194 command_overlapping(0), best_case(0), in_between_case(0), worst_case(0),
195 full_overlapping(0), partial_overlapping(0), mem_access_details(false),
196 memctrlpipe_enable(false), time_last_access(0)
197 {
198 warn("This DRAM module has not been tested with the new memory system at all!");
199 bank_size = (p->range.size() + 1) / num_banks;
200 num_rows = bank_size / SD_ROW_SIZE; /* 0x1000 size of row 4Kbtye */
201 active_row = new int[num_banks];
202 last_bank = num_banks+1;
203 last_row = num_rows;
204 busy_until = new Tick[num_banks];
205 std::memset(busy_until,0,sizeof(Tick)*num_banks); /* initiliaze */
206
207 }
208
209 void
210 DRAMMemory::regStats()
211 {
212 using namespace Stats;
213
214 accesses
215 .init(maxThreadsPerCPU)
216 .name(name() + ".accesses")
217 .desc("total number of accesses")
218 .flags(total)
219 ;
220
221 bytesRequested
222 .init(maxThreadsPerCPU)
223 .name(name() + ".bytes_requested")
224 .desc("total number of bytes requested")
225 .flags(total)
226 ;
227
228 bytesSent
229 .init(maxThreadsPerCPU)
230 .name(name() + ".bytes_sent")
231 .desc("total number of bytes sent")
232 .flags(total)
233 ;
234
235 compressedAccesses
236 .init(maxThreadsPerCPU)
237 .name(name() + ".compressed_responses")
238 .desc("total number of accesses that are compressed")
239 .flags(total)
240 ;
241
242 // stats for power modelling
243 cycles_nCKE
244 .init(1)
245 .name(name() + ".cycles_nCKE")
246 .desc("cycles when CKE is low")
247 .flags(total)
248 ;
249
250 cycles_all_precharge_CKE
251 .init(1)
252 .name(name() + ".cycles_all_precharge_CKE")
253 .desc("cycles when all banks precharged")
254 .flags(total)
255 ;
256
257 cycles_all_precharge_nCKE
258 .init(1)
259 .name(name() + ".cycles_all_precharge_nCKE")
260 .desc("cycles when all banks precharged and CKE is low")
261 .flags(total)
262 ;
263
264 cycles_bank_active_nCKE
265 .init(1)
266 .name(name() + ".cycles_bank_active_nCKE")
267 .desc("cycles when banks active and CKE low")
268 .flags(total)
269 ;
270
271 // we derive this from other stats later
272 // so DR TODO for now this counter is unused
273 cycles_avg_ACT
274 .init(1)
275 .name(name() + ".cycles_avg_ACT")
276 .desc("avg cycles between ACT commands")
277 .flags(total)
278 ;
279
280 cycles_read_out
281 .init(1)
282 .name(name() + ".cycles_read_out")
283 .desc("cycles outputting read data")
284 .flags(total)
285 ;
286
287 cycles_write_in
288 .init(1)
289 .name(name() + ".cycles_write_in")
290 .desc("cycles inputting write data")
291 .flags(total)
292 ;
293
294 cycles_between_misses
295 .init(1)
296 .name(name() + ".cycles_between_misses")
297 .desc("cycles between open page misses")
298 .flags(total)
299 ;
300
301 other_bank_read_access_miss
302 .init(1)
303 .name(name() + ".other_bank_read_access_miss")
304 .desc("read miss count")
305 .flags(total)
306 ;
307
308 other_bank_write_access_miss
309 .init(1)
310 .name(name() + ".other_bank_write_access_miss")
311 .desc("write miss count")
312 .flags(total)
313 ;
314
315 // DR TODO for now, only output stats which are involved in power equations
316 total_latency
317 .name(name() + ".total_latency")
318 .desc("total DRAM latency")
319 ;
320
321 total_arb_latency
322 .name(name() + ".total_arb_latency")
323 .desc("total arbitration latency")
324 ;
325
326 avg_latency
327 .name(name() + ".avg_latency")
328 .desc("average DRAM latency")
329 ;
330
331 avg_arb_latency
332 .name(name() + ".avg_arb_latency")
333 .desc("average arbitration DRAM latency")
334 ;
335
336 bank_access_profile
337 .init(num_banks,num_cpus)
338 .name(name() + "[cpu][bank]")
339 .desc("DRAM bank access profile")
340 ;
341
342 total_icache_req
343 .name(name() + ".total_icache_req")
344 .desc("total number of requests from icache")
345 ;
346
347 avg_latency = total_latency / accesses;
348 avg_arb_latency = total_arb_latency / accesses;
349 }
350
351
352
353
354 // DR DEBUG: assume we have a 500 MHz CPU and 100 MHz RAM
355 // static float cpu_ratio = 5; // ratio between CPU speed and memory bus speed
356 // DR TODO: get this parameter from the simulation
357
358 static char *mem_access_output=NULL;
359 /* latency of access [CPU cycles]*/
360 Tick
361 DRAMMemory::calculateLatency(PacketPtr pkt)
362 {
363
364 bool cmdIsRead = pkt->isRead();
365
366 int lat=0, temp=0, current_bank=0;
367 int current_row=0, current_device=0;
368
369 int was_miss = 0; // determines if there was an active row miss this access
370
371 //md_addr_t physic_address; /* linear memory address to be accessed */
372 Addr physic_address; /* linear memory address to be accessed */
373
374 int num_blocks=0;
375 int corrected_overlap, /* overlap of consecutive accesses [CPU cycles] */
376 overlap=0; /* overlap of consecutive accesses [mem bus cycles] */
377 int adjacent=0; /* 1 indicates that current bank is adjacent to the last accessed one*/
378
379 int chunks = (pkt->getSize() + (bus_width - 1)) / bus_width; // burst length
380 assert(chunks >0);
381 physic_address = pkt->getAddr();
382
383 ///////////////////////////////////////////////////////////////////////////
384 // DR added more stats for power modelling
385 // NOTE:
386 // for DRAM closed-page, automatic precharge after read or write,
387 // i.e. whenever idle
388
389
390 // count number of cycles where dram is not busy, use for CKE low signal
391 // calculate as percentage of all clock cycles
392 // if busy, do not add to idle count. Else add cycles since last access
393 /* #define SD_NUM_BANKS (SD_STACK_BASE/SD_BANK_SIZE) */ /* number of banks */
394 /* #define SD_NUM_ROWS (SD_BANK_SIZE/SD_ROW_SIZE) */ /* number of rows per bank */
395 /*delays until data is ready/written to the memory for the SDRAM*/
396 int SD_T_READ_READ_SROW = cas_lat; /* RAR, row hit, current bank */
397 int SD_T_READ_WRITE_SROW = cas_lat; /* RAW, row hit, current bank */
398 int SD_T_WRITE_READ_SROW = war_lat-1; /* WAR, row hit, current bank */
399 int SD_T_WRITE_WRITE_SROW = 0; /* WAW, row hit, current bank */
400 int SD_T_READ_READ_SBANK = (pre_lat+act_lat+cas_lat); /* RAR, row miss, current bank */
401 int SD_T_READ_WRITE_SBANK = (pre_lat+act_lat+cas_lat+(dpl_lat-1)); /* RAW, row miss, current bank */
402 int SD_T_WRITE_READ_SBANK = (pre_lat+act_lat); /* WAR, row miss, current bank */
403 int SD_T_WRITE_WRITE_SBANK = (pre_lat+act_lat+(dpl_lat-1)); /* WAW, row miss, current bank */
404 int SD_T_READ_READ_OBANK = (pre_lat+act_lat+cas_lat); /* RAR, row miss, another bank */
405 int SD_T_READ_WRITE_OBANK = (pre_lat+act_lat+cas_lat); /* RAW, row miss, another bank */
406 int SD_T_WRITE_READ_OBANK = (pre_lat+act_lat); /* WAR, row miss, another bank */
407 int SD_T_WRITE_WRITE_OBANK = (pre_lat+act_lat); /* WAW, row miss, another bank */
408 /* best-case latencies (due to overlap / row hits in another bank) */
409 int SD_BEST_T_READ_READ_SROW = 0; /* RAR, row hit, current bank */
410 int SD_BEST_T_READ_READ_SBANK = (act_lat+cas_lat); /* RAR, row miss, current bank */
411 int SD_BEST_T_WRITE_READ_SBANK = (act_lat); /* WAR, row miss, current bank */
412 int SD_BEST_T_READ_READ_OBANK = 0; /* RAR, row miss/hit, another bank */
413 int SD_BEST_T_READ_WRITE_OBANK = cas_lat; /* RAW, row miss/hit, another bank */
414 int SD_BEST_T_WRITE_READ_OBANK = (war_lat -1); /* WAR, row miss/hit, another bank */
415 int SD_BEST_T_WRITE_WRITE_OBANK = 0; /* WAW, row miss/hit, another bank */
416
417 Tick time_since_last_access = curTick-time_last_access;
418 Tick time_last_miss = 0; // used for keeping track of times between activations (page misses)
419 //int was_idle = (curTick > busy_until);
420 bool srow_flag = false;
421 int timing_correction = 0;
422
423 int was_idle = (curTick > busy_until[current_bank]);
424 cycles_nCKE[0] += was_idle ? MIN(curTick-busy_until[current_bank], time_since_last_access) : 0;
425
426 // bank is precharged
427 //active_row[current_bank] == DR_NUM_ROWS
428 int all_precharged = 1;
429 int bank_max = num_banks;
430 int row_max = num_rows;
431
432 if( (mem_type == "SDRAM") && (mem_actpolicy == "closed") ) {
433 // SDRAM does not use the active_row array in closed_page mode
434 // TODO: handle closed page operation
435
436 } else { // DRDRAM uses the active_row array
437 for( int i = 0; i < bank_max; i++ ) {
438 if( (active_row[current_bank] != row_max)) all_precharged = 0;
439 }
440 }
441
442 if(all_precharged) {
443 if(was_idle) {
444 cycles_all_precharge_nCKE[0] += MIN(curTick-busy_until[current_bank], time_since_last_access);
445 cycles_all_precharge_CKE[0] += MIN(0, busy_until[current_bank]-time_last_access);
446 }
447 else {
448 cycles_all_precharge_CKE[0] += time_since_last_access;
449 }
450 } else { // some bank is active
451 if(was_idle) {
452 cycles_bank_active_nCKE[0] += MIN(curTick-busy_until[current_bank], time_since_last_access);
453 }
454 else {
455 }
456 }
457
458 if( cmdIsRead ) {
459 cycles_read_out[0] += chunks;
460 } else {
461 cycles_write_in[0] += chunks;
462 }
463
464
465 time_last_access = curTick;
466 ////////////////////////////////////////////////////////////////////////////
467
468 if ((mem_type == "SDRAM") && (mem_actpolicy == "open"))
469 {
470 /* Split transaction on m5 makes it challenging to */
471 /* model the DRAM. A single cycle latency is assumed */
472 /* for dequeueing an address bus request. In response to */
473 /* that, the current DRAM implementation assumes that a */
474 /* seperate DRAM command generator / controller exists per */
475 /* bank and the dequeued addresses are queued to these */
476 /* controllers. We can view this as an ideal scenario for */
477 /* a shared DRAM command generator / controller with */
478 /* support for overlapping DRAM commands. */
479 /* Compare DRAM PRE,ACT,CAS etc. latencies, DRAM clock */
480 /* frequency and the number of banks to determine whether */
481 /* the ideal scenario with a shared DRAM command generator */
482 /* is equivalent to having multiple DRAM command generators */
483 /* per bank */
484 if ((memctrladdr_type != "interleaved"))/* i.e. mc_type is linear */
485 {
486 current_bank=physic_address/bank_size;
487 temp=physic_address-current_bank*bank_size;/*address in bank*/
488 current_row=temp/SD_ROW_SIZE;
489 }
490 else/* mc_type interleaved */
491 /* This memory controller maps the addresses differently
492 * depending on the row_size, every row is mapped to another
493 * bank. Thus, the text segment uses half of every bank, the heap
494 * the next quarter of each bank, and the stack the rest.
495 */
496
497 {
498 num_blocks = physic_address/SD_ROW_SIZE; /* row number */
499 current_bank=num_blocks%num_banks;
500 current_row=num_blocks/num_banks;
501 }
502
503 if (mem_access_details == true)
504 {
505 // DR TODO
506 //fprintf(mem_accessfd," %09u %4d %3d\n",physic_address,current_row,current_bank);
507 }
508 else
509 {
510 if (mem_access_output!=0)
511 {
512 //fprintf(mem_accessfd,"\n");
513 }
514 }
515 total_access++;
516
517 if (memctrlpipe_enable == true)
518 {
519 overlap=(int)(busy_until[current_bank] - curTick);
520 }
521 else overlap = 0;
522
523 if (cpu_ratio < 1.0)
524 {
525 corrected_overlap = overlap*((int)(1/cpu_ratio)); /* floor */
526 }
527 else
528 {
529 corrected_overlap = (int) (overlap/cpu_ratio);
530 }
531
532 /*fprintf(stderr,"%10.0f %10.0f %4d %4d ",(double)busy_until, (double)curTick, overlap, corrected_overlap); debugging*/
533
534 if (cmdIsRead == lastCmdIsRead)/*same command*/
535 {
536 if (current_bank == last_bank)/*same bank*/
537 {
538 if (current_row == last_row)/*same row*/
539 {
540 /* Page Hit */
541 if (cmdIsRead)
542 {
543 if (corrected_overlap > 0)/*overlapping*/
544 {
545 /*best case*/
546 if (corrected_overlap >= cas_lat)
547 {
548 lat=SD_BEST_T_READ_READ_SROW;
549 srow_flag = true;
550 best_case++;
551 full_overlapping++;
552 }
553 else/*in between case*/
554 {
555 lat = cas_lat-corrected_overlap;
556 srow_flag = true;
557 in_between_case++;
558 partial_overlapping++;
559 }
560 }
561 else
562 {
563 /*worst case*/
564 lat = SD_T_READ_READ_SROW;
565 srow_flag = true;
566 worst_case++;
567 }
568 same_row_read_access++;
569 srr_after_read++;
570 }
571 else/*write*/
572 {/*no option case*/
573 lat = SD_T_WRITE_WRITE_SROW;
574 srow_flag = true;
575 same_row_write_access++;
576 srw_after_write++;
577 worst_case++;
578 }
579 }
580 else /*other row in same bank*/
581 {
582 /* Page miss */
583 if (cmdIsRead)
584 {
585 if (corrected_overlap > 0)/*overlapping*/
586 {
587 if (corrected_overlap >= pre_lat)/*best case*/
588 {
589 lat = SD_BEST_T_READ_READ_SBANK;
590 best_case++;
591 full_overlapping++;
592 }
593 else/*in between case*/
594 {
595 lat = SD_T_READ_READ_SBANK-corrected_overlap;
596 in_between_case++;
597 partial_overlapping++;
598 }
599 }
600 else/*worst case*/
601 {
602 lat = SD_T_READ_READ_SBANK;
603 worst_case++;
604 }
605 same_bank_read_access++;
606 sbr_after_read++;
607 }
608 else/*write*/
609 {/*no option case*/
610 lat = SD_T_WRITE_WRITE_SBANK;
611 same_bank_write_access++;
612 sbw_after_write++;
613 worst_case++;
614 }
615 }
616 }
617 else /*other bank*/
618 {
619 if (cmdIsRead)
620 {
621 /* Page empty */
622 if (current_row == active_row[current_bank])/*row is still active*/
623 {
624 if (corrected_overlap > 0 )/*overlapping*/
625 {
626 if(corrected_overlap >= pre_lat)/*best case*/
627 {
628 lat = SD_BEST_T_READ_READ_OBANK;
629 best_case++;
630 full_overlapping++;
631 }
632 else/*in between case*/
633 {
634 lat = SD_T_READ_READ_OBANK - corrected_overlap;
635 in_between_case++;
636 partial_overlapping++;
637 }
638 }
639 else/*in between case*/
640 {
641 lat = SD_T_READ_READ_OBANK;
642 in_between_case++;
643 }
644 other_bank_read_access_hit++;
645 obr_after_read_hit++;
646 }
647 else/*row is not active*/
648 {
649 if (corrected_overlap > 0 )/*overlapping*/
650 {
651 if(corrected_overlap >= SD_T_READ_READ_OBANK )/*best case*/
652 {
653 lat = SD_BEST_T_READ_READ_OBANK;
654 best_case++;
655 full_overlapping++;
656 }
657 else/*in between case*/
658 {
659 lat = SD_T_READ_READ_OBANK-corrected_overlap;
660 in_between_case++;
661 partial_overlapping++;
662 }
663 }
664 else/*worst case*/
665 {
666 lat = SD_T_READ_READ_OBANK;
667 worst_case++;
668 }
669
670 // DR keep track of time between misses
671 was_miss = 1;
672
673 other_bank_read_access_miss[0]++;
674 obr_after_read_miss++;
675 }
676 }
677 else/*write*/
678 {
679 if (current_row == active_row[current_bank])/*row is still active*/
680 { /*best_case*/
681 lat = SD_BEST_T_WRITE_WRITE_OBANK;
682 best_case++;
683 other_bank_write_access_hit++;
684 obw_after_write_hit++;
685 }
686 else/*row is not active*/
687 {
688 if (corrected_overlap > 0 )/*overlapping*/
689 {
690 if(corrected_overlap >=SD_T_WRITE_WRITE_OBANK)/*best case*/
691 {
692 lat = SD_BEST_T_WRITE_WRITE_OBANK;
693 best_case++;
694 full_overlapping++;
695 }
696 else/*in between case*/
697 {
698 lat = SD_T_WRITE_WRITE_OBANK-corrected_overlap;
699 in_between_case++;
700 partial_overlapping++;
701 }
702 }
703 else/*worst case*/
704 {
705 lat = SD_T_WRITE_WRITE_OBANK;
706 worst_case++;
707 }
708
709 // DR keep track of time between misses
710 was_miss = 1;
711
712 other_bank_write_access_miss[0]++;
713 obw_after_write_miss++;
714
715 }
716 }
717 }
718 }
719 else /*lastCmdIsRead != cmdIsRead*/
720 {
721 if (current_bank == last_bank)/*same bank*/
722 {
723 if (current_row == last_row)/*same row*/
724 {
725 /* Page Hit */
726 if (cmdIsRead)
727 {/*worst case*/
728 lat = SD_T_READ_WRITE_SROW;
729 srow_flag = true;
730 same_row_read_access++;
731 srr_after_write++;
732 worst_case++;
733 }
734 else/*write*/
735 {/*worst case*/
736 lat = SD_T_WRITE_READ_SROW;
737 srow_flag = true;
738 same_row_write_access++;
739 srw_after_read++;
740 worst_case++;
741 }
742 }
743 else /*other row in same bank*/
744 {
745 /* Page Miss */
746 if (cmdIsRead)
747 {/*worst case*/
748 lat = SD_T_READ_WRITE_SBANK;
749 same_bank_read_access++;
750 sbr_after_write++;
751 worst_case++;
752 }
753 else/*write*/
754 {
755 if (corrected_overlap > 0 )/*overlapping*/
756 {
757 if (corrected_overlap >= pre_lat)/*best case*/
758 {
759 lat = SD_BEST_T_WRITE_READ_SBANK;
760 best_case++;
761 full_overlapping++;
762 }
763 else/*in between case*/
764 {
765 lat = SD_T_WRITE_READ_SBANK-corrected_overlap;
766 in_between_case++;
767 partial_overlapping++;
768 }
769 }
770 else/*worst case*/
771 {
772 lat = SD_T_WRITE_READ_OBANK;
773 worst_case++;
774 }
775 same_bank_write_access++;
776 sbw_after_read++;
777 }
778 }
779 }
780 else /*other bank*/
781 {
782 /* Page empty */
783 if (cmdIsRead)
784 {
785 if (current_row == active_row[current_bank])/*row is still active*/
786 { /*best case*/
787 lat = SD_BEST_T_READ_WRITE_OBANK;
788 best_case++;
789 other_bank_read_access_hit++;
790 obr_after_write_hit++;
791 }
792 else/*row is not active*/
793 {
794 if (corrected_overlap > 0 )/*overlapping*/
795 {
796 if(corrected_overlap >= (pre_lat+act_lat))/*best case*/
797 {
798 lat = SD_BEST_T_READ_WRITE_OBANK;
799 best_case++;
800 full_overlapping++;
801 }
802 else/*in between case*/
803 {
804 lat = SD_T_READ_WRITE_OBANK-corrected_overlap;
805 in_between_case++;
806 partial_overlapping++;
807 }
808 }
809 else/*worst case*/
810 {
811 lat = SD_T_READ_WRITE_OBANK;
812 worst_case++;
813 }
814 // DR keep track of time between misses
815 was_miss = 1;
816
817 other_bank_read_access_miss[0]++;
818 obr_after_write_miss++;
819 }
820 }
821 else/*write*/
822 {
823 if (current_row == active_row[current_bank])/*row is still active*/
824 { /*best case*/
825 lat = SD_BEST_T_WRITE_READ_OBANK;
826 best_case++;
827 other_bank_write_access_hit++;
828 obw_after_read_hit++;
829 }
830 else/*row is not active*/
831 {
832 if (corrected_overlap > 0 )/*overlapping*/
833 {
834 if (corrected_overlap >= (SD_T_WRITE_READ_OBANK-SD_BEST_T_WRITE_READ_OBANK))/*best case*/
835 {/*best case*/
836 lat = SD_BEST_T_WRITE_READ_OBANK;
837 best_case++;
838 full_overlapping++;
839 }
840 else/*in between case*/
841 {
842 lat = SD_T_WRITE_READ_OBANK-corrected_overlap;
843 in_between_case++;
844 partial_overlapping++;
845 }
846 }
847 else/*worst case*/
848 {
849 lat = SD_T_WRITE_READ_OBANK;
850 worst_case++;
851 }
852
853 // DR keep track of time between misses
854 was_miss = 1;
855
856 other_bank_write_access_miss[0]++;
857 obw_after_read_miss++;
858 }
859 }
860 }
861 }
862 /*fprintf(stderr,"%4d %4d ",lat,active_row[current_bank]);debugging*/
863
864 lat += chunks; /* burst length added*/
865 if(srow_flag == false)
866 timing_correction = cpu_ratio*(trc_lat - pre_lat - act_lat - cas_lat - 1);
867
868
869 /*fprintf(stderr,"%4d ",lat);debugging*/
870
871 active_row[current_bank]=current_row; /* open-page (hit) register */
872 lastCmdIsRead = cmdIsRead;
873 last_bank = current_bank;
874 last_row = current_row;
875
876 if (cpu_ratio < 1.0)
877 {
878 lat = (lat+((int)(1/cpu_ratio)-1))/(int)(1/cpu_ratio);
879 }
880 else
881 {
882 temp = (int)(lat*cpu_ratio);
883 lat = (lat*cpu_ratio == temp)?temp:(temp+1); /*round up*/
884 }
885
886 /*fprintf(stderr,"%4d \n",lat);debugging*/
887
888 if (overlap <= 0) /*memory interface is not busy*/
889 {
890 if (memctrlpipe_enable == true)
891 {
892 busy_until[current_bank]=curTick+lat+
893 timing_correction;
894 }
895 else
896 {
897 if (busy_until[current_bank] >= curTick)
898 {
899 busy_until[current_bank]+=(lat+
900 timing_correction);
901 total_arb_latency += (busy_until[current_bank]
902 - curTick - lat
903 - timing_correction);
904 lat=busy_until[current_bank] - curTick;
905 }
906 else busy_until[current_bank]=curTick+lat+
907 timing_correction;
908 }
909 }
910 else/*the memory request will be satisfied temp cycles after curTick*/
911 {
912 busy_until[current_bank] +=(lat+
913 timing_correction);
914 command_overlapping++;
915 lat+=overlap;
916 total_arb_latency += overlap;
917 }
918
919 // DR for power stats
920 if( was_miss ) {
921 cycles_between_misses[0] += (busy_until[current_bank] - time_last_miss);
922 time_last_miss = busy_until[current_bank];
923 }
924 // cout <<"cpu id = " << _cpu_num << "current_bank = " << current_bank << endl;
925 // if((_cpu_num < num_cpus) && (_cpu_num >= 0))
926 // bank_access_profile[_cpu_num][current_bank]++;
927
928 return lat;
929 }
930
931
932 /***********************************************************/
933 /******************** DRDRAM ***********************/
934 /***********************************************************/
935
936 else if ((mem_type == "DRDRAM") && (mem_actpolicy == "open"))/*DRDRAM*/ /*a closed bank has an activ_row number of DR_NUM_ROWS: highest +1*/
937 {
938 if ((memctrladdr_type != "interleaved"))/* i.e. mc_type is linear */
939 {
940 current_bank=physic_address/DR_BANK_SIZE;
941 temp=physic_address-current_bank*DR_BANK_SIZE;/*address in bank*/
942 current_row=temp/DR_ROW_SIZE;
943 current_device=current_bank/(DR_NUM_BANKS/DR_NUM_DEVS);
944 }
945
946 else/*mc_type interleaved*/
947 /* This memory controller maps the addresses differently
948 * depending on the row-size, every row is mapped to another
949 * bank. So the text segment uses half of every bank. The heap
950 * the next quarter of each bank and the stack the rest.
951 */
952
953 {
954 num_blocks = physic_address/DR_ROW_SIZE; /* row number */
955 current_bank=(num_blocks%DR_NUM_BANKS)*2; /*every 'second' bank will be used*/
956 /*banks above DR_NUM_BANKS are the uneven banks*/
957 current_bank = ((current_bank < DR_NUM_BANKS) ? current_bank:(current_bank - DR_NUM_BANKS+1));
958 current_row=num_blocks/DR_NUM_BANKS;
959 current_device=current_bank/(DR_NUM_BANKS/DR_NUM_DEVS);
960 }
961 if (abs(current_bank-last_bank)==1)/*access to an adjacent bank*/
962 {
963 if (!((current_bank%DR_BANK_SAMP == (DR_BANK_SAMP-1))&&(last_bank%DR_BANK_SAMP == 0))/*not 15/16 (current/last)*/
964 &&(!((last_bank%DR_BANK_SAMP == (DR_BANK_SAMP-1))&&(current_bank%DR_BANK_SAMP == 0))))/*not 16/15(current/last)*/
965 {
966 adjacent_access++;
967 adjacent=1;/*an adjacent bank is accessed*/
968 if (cmdIsRead)
969 adjacent_read++;
970 else
971 adjacent_write++;
972 }
973 }
974 precharge=0;/*at this moment no bank needs to be precharged*/
975 if (active_row[current_bank] == DR_NUM_ROWS)/*bank is precharged*/
976 {
977 if (prechargeBanksAround(current_bank)> 0)/*a bank next to the current is activated*/
978 {
979 if ((adjacent==1)&&(precharge==1))
980 {
981 /*since adjacent banks share SAMPs, this access would be the same as (in terms of latency)
982 *an access to another row in the same bank if only one adjacent bank was active*/
983 last_bank = current_bank;
984 last_row = current_row+1;
985 precharge=0;/*set to 0 for next memory access*/
986 }
987 }
988 }
989 if (mem_access_details == true)
990 {
991 //fprintf(mem_accessfd," %09u %4d %3d %15d\n",physic_address,current_row,current_bank,(int)adjacent_access);
992 }
993 else
994 {
995 if (mem_access_output!=NULL)
996 {
997 //fprintf(mem_accessfd,"\n");
998 }
999 }
1000 total_access++;
1001
1002 if (memctrlpipe_enable == true)
1003 {
1004 overlap=(int)(busy_until[current_bank] - curTick);
1005 }
1006 else overlap=0;
1007
1008 if (cpu_ratio < 1.0)
1009 {
1010 corrected_overlap = overlap*((int)(1/cpu_ratio)); /* floor */
1011 }
1012 else
1013 {
1014 corrected_overlap = (int) (overlap/cpu_ratio);
1015 }
1016
1017 /*fprintf(stderr,"%10.0f %10.0f %6d %6d %2d %2d ",(double)busy_until, (double)curTick, overlap, corrected_overlap,precharge,adjacent);debugging*/
1018
1019 if (cmdIsRead == lastCmdIsRead)/*same command*/
1020 {
1021 if (current_bank == last_bank)/*same bank*/
1022 {
1023 if (current_row == last_row)/*same row*/
1024 {
1025 if (cmdIsRead)
1026 {
1027 if (corrected_overlap > 0)/*overlapping*/
1028 {
1029 /*best case*/
1030 if (corrected_overlap >= DR_T_READ_READ_SROW)
1031 {
1032 lat=DR_BEST_T_READ_READ_SROW;
1033 srow_flag = true;
1034 best_case++;
1035 full_overlapping++;
1036 }
1037 else/*in between case*/
1038 {
1039 lat = DR_T_READ_READ_SROW-corrected_overlap;
1040 srow_flag = true;
1041 in_between_case++;
1042 partial_overlapping++;
1043 }
1044 }
1045 else
1046 {
1047 /*worst case*/
1048 lat = DR_T_READ_READ_SROW;
1049 srow_flag = true;
1050 worst_case++;
1051 }
1052 same_row_read_access++;
1053 srr_after_read++;
1054 }
1055 else/*write, always retire the previous data*/
1056 {
1057 if (corrected_overlap > 0)/*overlapping*/
1058 {
1059 /*best case*/
1060 if (corrected_overlap >= DR_T_OWR)
1061 {
1062 lat=DR_BEST_T_WRITE_WRITE_SROW;
1063 srow_flag = true;
1064 best_case++;
1065 full_overlapping++;
1066 }
1067 else/*in between case*/
1068 {
1069 lat = DR_T_WRITE_WRITE_SROW-corrected_overlap;
1070 srow_flag = true;
1071 in_between_case++;
1072 partial_overlapping++;
1073 }
1074 }
1075 else
1076 {
1077 /*worst case*/
1078 lat = DR_T_WRITE_WRITE_SROW;
1079 srow_flag = true;
1080 worst_case++;
1081 }
1082 same_row_write_access++;
1083 srw_after_write++;
1084 }
1085 }
1086 else /*other row in same bank*/
1087 {
1088 if (cmdIsRead)
1089 {
1090 if (corrected_overlap > 0)/*overlapping*/
1091 {
1092 if (corrected_overlap >= DR_T_HELP)/*best case*/
1093 {
1094 lat = DR_BEST_T_READ_READ_SBANK;
1095 best_case++;
1096 full_overlapping++;
1097 }
1098 else/*in between case*/
1099 {
1100 lat = DR_T_READ_READ_SBANK-corrected_overlap;
1101 in_between_case++;
1102 partial_overlapping++;
1103 }
1104 }
1105 else/*worst case*/
1106 {
1107 lat = DR_T_READ_READ_SBANK;
1108 worst_case++;
1109 }
1110 same_bank_read_access++;
1111 sbr_after_read++;
1112 }
1113 else/*write*/
1114 {
1115 if (corrected_overlap > 0)/*overlapping*/
1116 {
1117 if (corrected_overlap >= DR_T_OWR)/*best case*/
1118 {
1119 lat = DR_BEST_T_WRITE_WRITE_SBANK;
1120 best_case++;
1121 full_overlapping++;
1122 }
1123 else/*in between case*/
1124 {
1125 lat = DR_T_WRITE_WRITE_SBANK-corrected_overlap;
1126 in_between_case++;
1127 partial_overlapping++;
1128 }
1129 }
1130 else/*worst case*/
1131 {
1132 lat = DR_T_WRITE_WRITE_SBANK;
1133 worst_case++;
1134 }
1135 same_bank_write_access++;
1136 sbw_after_write++;
1137 }
1138 }
1139 }
1140 else /*other bank*/
1141 {
1142 if (cmdIsRead)
1143 {
1144 if (current_row == active_row[current_bank])/*row is still active*/
1145 {
1146 if (corrected_overlap > 0 )/*overlapping*/
1147 {
1148 if(corrected_overlap >= (DR_T_CAC+DR_T_PACKET))/*best case*/
1149 {
1150 lat = DR_BEST_T_READ_READ_OBANK;
1151 best_case++;
1152 full_overlapping++;
1153 }
1154 else/*in between case*/
1155 {
1156 lat = DR_T_CAC+DR_T_PACKET-corrected_overlap;
1157 in_between_case++;
1158 partial_overlapping++;
1159 }
1160 }
1161 else/*in between case*/
1162 {
1163 lat = DR_T_CAC+DR_T_PACKET;
1164 in_between_case++;
1165 }
1166 other_bank_read_access_hit++;
1167 obr_after_read_hit++;
1168 }
1169 else/*row is not active or bank is precharged/not active*/
1170 {
1171 if (active_row[current_bank]!=DR_NUM_ROWS)/*row is not active, but bank is active*/
1172 {
1173 if (corrected_overlap > 0 )/*overlapping*/
1174 {
1175 if(corrected_overlap >= (DR_T_RP+DR_T_RCD+DR_T_CAC+DR_T_PACKET))/*best case*/
1176 {
1177 lat = DR_BEST_T_READ_READ_OBANK;
1178 best_case++;
1179 full_overlapping++;
1180 }
1181 else/*in between case*/
1182 {
1183 lat = DR_T_RP+DR_T_RCD+DR_T_CAC+DR_T_PACKET-corrected_overlap;
1184 in_between_case++;
1185 partial_overlapping++;
1186 }
1187 }
1188 else/*worst case*/
1189 {
1190 lat = DR_T_RP+DR_T_RCD+DR_T_CAC+DR_T_PACKET;
1191 in_between_case++;
1192 }
1193 }
1194 else/*current_row == DR_NUM_ROWS:precharged or inactive*/
1195 {
1196 if(precharge == 0)/*no adjacent bank is active*/
1197 {
1198 if (corrected_overlap > 0 )/*overlapping*/
1199 {
1200 if(corrected_overlap >= (DR_T_RCD+DR_T_CAC+DR_T_PACKET))/*best case*/
1201 {
1202 lat = DR_BEST_T_READ_READ_OBANK;
1203 best_case++;
1204 full_overlapping++;
1205 }
1206 else/*in between case*/
1207 {
1208 lat = DR_T_RCD+DR_T_CAC+DR_T_PACKET-corrected_overlap;
1209 in_between_case++;
1210 partial_overlapping++;
1211 }
1212 }
1213 else/*worst case*/
1214 {
1215 lat = DR_T_RCD+DR_T_CAC+DR_T_PACKET;
1216 in_between_case++;
1217 }
1218 }
1219 else/*one ore two adjacent banks are active*/
1220 {
1221 if (precharge == 1)
1222 {
1223 if (corrected_overlap > 0 )/*overlapping*/
1224 {
1225 if(corrected_overlap >= (DR_T_RP+DR_T_RCD+DR_T_CAC+DR_T_PACKET))/*best case*/
1226 {
1227 lat = DR_BEST_T_READ_READ_OBANK;
1228 best_case++;
1229 full_overlapping++;
1230 }
1231 else/*in between case*/
1232 {
1233 lat = (DR_T_RP+DR_T_RCD+DR_T_CAC+DR_T_PACKET)-corrected_overlap;
1234 in_between_case++;
1235 partial_overlapping++;
1236 }
1237 }
1238 else/*worst case*/
1239 {
1240 lat = (DR_T_RP+DR_T_RCD+DR_T_CAC+DR_T_PACKET);
1241 in_between_case++;
1242 }
1243 }
1244 else /*precharge ==2: two rows must be precharged*/
1245 {
1246 if (adjacent == 1)/*these banks are adjacent*/
1247 {
1248 if (corrected_overlap > 0 )/*overlapping*/
1249 {
1250 if(corrected_overlap >= DR_T_PP+2*DR_T_PACKET-DR_T_RDP+DR_T_CAC)/*best case*/
1251 {
1252 lat = DR_T_RDP+DR_T_RP+DR_T_RCD-DR_T_PACKET;
1253 in_between_case++;
1254 full_overlapping++;
1255 }
1256 else/*in between case*/
1257 {
1258 lat = DR_T_READ_READ_OBANK-corrected_overlap;
1259 in_between_case++;
1260 partial_overlapping++;
1261 }
1262 }
1263 else/*worst case*/
1264 {
1265 lat = DR_T_READ_READ_OBANK;
1266 worst_case++;
1267 }
1268 }
1269 else/*adjacent == 0: two not adjacent banks need to be precharged*/
1270 {
1271 if (corrected_overlap > 0 )/*overlapping*/
1272 {
1273 if(corrected_overlap >= DR_T_READ_READ_OBANK)/*best case*/
1274 {
1275 lat = DR_BEST_T_READ_READ_OBANK;
1276 best_case++;
1277 full_overlapping++;
1278 }
1279 else/*in between case*/
1280 {
1281 lat = DR_T_READ_READ_OBANK-corrected_overlap;
1282 in_between_case++;
1283 partial_overlapping++;
1284 }
1285 }
1286 else/*worst case*/
1287 {
1288 lat = DR_T_READ_READ_OBANK;
1289 worst_case++;
1290 }
1291 }
1292 }
1293 }
1294 }
1295 other_bank_read_access_miss[0]++;
1296 obr_after_read_miss++;
1297 }
1298 }
1299 else/*write*/
1300 {
1301 if (current_row == active_row[current_bank])/*row is still active*/
1302 {
1303 if (corrected_overlap > 0 )/*overlapping*/
1304 {
1305 if(corrected_overlap >= (DR_T_CWD+DR_T_PACKET))/*best case*/
1306 {
1307 lat = DR_BEST_T_WRITE_WRITE_OBANK;
1308 best_case++;
1309 full_overlapping++;
1310 }
1311 else/*in between case*/
1312 {
1313 lat = DR_T_CWD+DR_T_PACKET-corrected_overlap;
1314 in_between_case++;
1315 partial_overlapping++;
1316 }
1317 }
1318 else/*worst case*/
1319 {
1320 lat = DR_T_CWD+DR_T_PACKET;
1321 in_between_case++;
1322 }
1323 other_bank_write_access_hit++;
1324 obw_after_write_hit++;
1325 }
1326 else/*row is not active or bank is precharged/not active*/
1327 {
1328 if (active_row[current_bank] != DR_NUM_ROWS)/*row is not active,but bank is active*/
1329 {
1330 if (corrected_overlap > 0 )/*overlapping*/
1331 {
1332 if(corrected_overlap >= (DR_T_RP+DR_T_RCD+DR_T_CWD+DR_T_PACKET))/*best case*/
1333 {
1334 lat = DR_BEST_T_WRITE_WRITE_OBANK;
1335 best_case++;
1336 full_overlapping++;
1337 }
1338 else/*in between case*/
1339 {
1340 lat = DR_T_RP+DR_T_RCD+DR_T_CWD+DR_T_PACKET-corrected_overlap;
1341 in_between_case++;
1342 partial_overlapping++;
1343 }
1344 }
1345 else/*worst case*/
1346 {
1347 lat = DR_T_RP+DR_T_RCD+DR_T_CWD+DR_T_PACKET;
1348 in_between_case++;
1349 }
1350 }
1351 else/*current_row == DR_NUM_ROWS:precharged or inactive*/
1352 {
1353 if(precharge == 0)/*no adjacent bank is active*/
1354 {
1355 if (corrected_overlap > 0 )/*overlapping*/
1356 {
1357 if(corrected_overlap >= (DR_T_RCD+DR_T_CWD+DR_T_PACKET))/*best case*/
1358 {
1359 lat = DR_BEST_T_WRITE_WRITE_OBANK;
1360 best_case++;
1361 full_overlapping++;
1362 }
1363 else/*in between case*/
1364 {
1365 lat = DR_T_RCD+DR_T_CWD+DR_T_PACKET-corrected_overlap;
1366 in_between_case++;
1367 partial_overlapping++;
1368 }
1369 }
1370 else/*worst case*/
1371 {
1372 lat = DR_T_RCD+DR_T_CWD+DR_T_PACKET;
1373 in_between_case++;
1374 }
1375 }
1376 else/*one ore two adjacent banks are active*/
1377 {
1378 if (precharge == 1)/*last_bank is no adjacent*/
1379 {
1380 if (corrected_overlap > 0 )/*overlapping*/
1381 {
1382 if(corrected_overlap >= (DR_T_RP+DR_T_RCD+DR_T_CWD+DR_T_PACKET))/*best case*/
1383 {
1384 lat = DR_BEST_T_WRITE_WRITE_OBANK;
1385 best_case++;
1386 full_overlapping++;
1387 }
1388 else/*in between case*/
1389 {
1390 lat = (DR_T_RP+DR_T_RCD+DR_T_CWD+DR_T_PACKET)-corrected_overlap;
1391 in_between_case++;
1392 partial_overlapping++;
1393 }
1394 }
1395 else/*worst case*/
1396 {
1397 lat = (DR_T_RP+DR_T_RCD+DR_T_CWD+DR_T_PACKET);
1398 in_between_case++;
1399 }
1400 }
1401 else /*precharge ==2: two rows have to be precharged*/
1402 {
1403 if (adjacent == 1)/*these banks are adjacent*/
1404 {
1405 if (corrected_overlap > 0 )/*overlapping*/
1406 {
1407 if(corrected_overlap >= DR_T_OWR+DR_T_PP)/*best case*/
1408 {
1409 lat = DR_T_WRITE_WRITE_OBANK-DR_T_OWR-DR_T_PP;
1410 in_between_case++;
1411 full_overlapping++;
1412 }
1413 else/*in between case*/
1414 {
1415 lat = DR_T_WRITE_WRITE_OBANK-corrected_overlap;
1416 in_between_case++;
1417 partial_overlapping++;
1418 }
1419 }
1420 else/*worst case*/
1421 {
1422 lat = DR_T_WRITE_WRITE_OBANK;
1423 worst_case++;
1424 }
1425 }
1426 else/*adjacent == 0: two not adjacent banks need to be precharged*/
1427 {
1428 if (corrected_overlap > 0 )/*overlapping*/
1429 {
1430 if(corrected_overlap >= DR_T_WRITE_WRITE_OBANK)/*best case*/
1431 {
1432 lat = DR_BEST_T_WRITE_WRITE_OBANK;
1433 best_case++;
1434 full_overlapping++;
1435 }
1436 else/*in between case*/
1437 {
1438 lat = DR_T_WRITE_WRITE_OBANK-corrected_overlap;
1439 in_between_case++;
1440 partial_overlapping++;
1441 }
1442 }
1443 else/*worst case*/
1444 {
1445 lat = DR_T_WRITE_WRITE_OBANK;
1446 worst_case++;
1447 }
1448 }
1449 }
1450 }
1451 }
1452 other_bank_write_access_miss[0]++;
1453 obw_after_write_miss++;
1454 }
1455 }
1456 }
1457 }
1458 else /*lastCmdIsRead != cmdIsRead*/
1459 {
1460 if (current_bank == last_bank)/*same bank*/
1461 {
1462 if (current_row == last_row)/*same row*/
1463 {
1464 if (cmdIsRead)
1465 {
1466 if (corrected_overlap > 0)/*overlapping*/
1467 {
1468 /*best case*/
1469 if (corrected_overlap >= DR_T_OWR)
1470 {
1471 lat=DR_BEST_T_READ_WRITE_SROW;
1472 srow_flag = true;
1473 best_case++;
1474 full_overlapping++;
1475 }
1476 else/*in between case*/
1477 {
1478 lat = DR_T_READ_WRITE_SROW-corrected_overlap;
1479 srow_flag = true;
1480 in_between_case++;
1481 partial_overlapping++;
1482 }
1483 }
1484 else
1485 {
1486 /*worst case*/
1487 lat = DR_T_READ_WRITE_SROW;
1488 srow_flag = true;
1489 worst_case++;
1490 }
1491 same_row_read_access++;
1492 srr_after_write++;
1493 }
1494 else/*write*/
1495 {
1496 if (corrected_overlap > 0)/*overlapping*/
1497 {
1498 /*best case*/
1499 if (corrected_overlap >= DR_T_WRITE_READ_SROW)
1500 {
1501 lat=DR_BEST_T_WRITE_READ_SROW;
1502 srow_flag = true;
1503 best_case++;
1504 full_overlapping++;
1505 }
1506 else/*in between case*/
1507 {
1508 lat = DR_T_WRITE_READ_SROW-corrected_overlap;
1509 srow_flag = true;
1510 in_between_case++;
1511 partial_overlapping++;
1512 }
1513 }
1514 else
1515 {
1516 /*worst case*/
1517 lat = DR_T_WRITE_READ_SROW;
1518 srow_flag = true;
1519 worst_case++;
1520 }
1521 same_row_write_access++;
1522 srw_after_read++;
1523 }
1524 }
1525 else /*other row in same bank*/
1526 {
1527 if (cmdIsRead)
1528 {
1529 if (corrected_overlap > 0 )/*overlapping*/
1530 {
1531 if (corrected_overlap >= DR_T_OWR)/*best case*/
1532 {
1533 lat = DR_BEST_T_READ_WRITE_SBANK;
1534 best_case++;
1535 full_overlapping++;
1536 }
1537 else/*in between case*/
1538 {
1539 lat = DR_T_READ_WRITE_SBANK-corrected_overlap;
1540 in_between_case++;
1541 partial_overlapping++;
1542 }
1543 }
1544 else/*worst case*/
1545 {
1546 lat = DR_T_READ_WRITE_SBANK;
1547 worst_case++;
1548 }
1549 same_bank_read_access++;
1550 sbr_after_write++;
1551 }
1552 else/*write*/
1553 {
1554 if (corrected_overlap > 0 )/*overlapping*/
1555 {
1556 if (corrected_overlap >= DR_T_HELP)/*best case*/
1557 {
1558 lat = DR_BEST_T_WRITE_READ_SBANK;
1559 best_case++;
1560 full_overlapping++;
1561 }
1562 else/*in between case*/
1563 {
1564 lat = DR_T_WRITE_READ_SBANK-corrected_overlap;
1565 in_between_case++;
1566 partial_overlapping++;
1567 }
1568 }
1569 else/*worst case*/
1570 {
1571 lat = DR_T_WRITE_READ_SBANK;
1572 worst_case++;
1573 }
1574 same_bank_write_access++;
1575 sbw_after_read++;
1576 }
1577 }
1578 }
1579 else /*other bank*/
1580 {
1581 if (cmdIsRead)
1582 {
1583 if (current_row == active_row[current_bank])/*row is still active*/
1584 {
1585 if (corrected_overlap > 0 )/*overlapping*/
1586 {
1587 if(last_dev != current_device)
1588 {
1589 if(corrected_overlap >= DR_T_CWD+DR_T_PACKET)/*best case*/
1590 {
1591 lat = DR_BEST_T_READ_WRITE_ODEV;
1592 best_case++;
1593 full_overlapping++;
1594 }
1595 else/*in between case*/
1596 {
1597 lat = DR_T_CAC+DR_T_PACKET-corrected_overlap;
1598 in_between_case++;
1599 partial_overlapping++;
1600 }
1601 }
1602 else /* same device */
1603 {
1604 if(corrected_overlap >= DR_T_OWR)/*best case*/
1605 {
1606 lat = DR_BEST_T_READ_WRITE_OBANK;
1607 best_case++;
1608 full_overlapping++;
1609 }
1610 else/*in between case*/
1611 {
1612 lat = DR_T_CAC+DR_T_PACKET-corrected_overlap;
1613 in_between_case++;
1614 partial_overlapping++;
1615 }
1616 }
1617 }
1618 else/*in between case, no overlap*/
1619 {
1620 lat = DR_T_CAC+DR_T_PACKET;
1621 in_between_case++;
1622 }
1623 other_bank_read_access_hit++;
1624 obr_after_write_hit++;
1625 }
1626
1627 else/*row is not active or bank is precharged/not active*/
1628 {
1629 if (active_row[current_bank] != DR_NUM_ROWS)/*row is not active,but bank is active*/
1630 {
1631 if (corrected_overlap > 0 )/*overlapping*/
1632 {
1633 if (last_dev != current_device)
1634 {
1635 if(corrected_overlap >= (DR_T_RP+DR_T_RCD+DR_T_CWD+DR_T_PACKET))/*best case*/
1636 {
1637 lat = DR_BEST_T_READ_WRITE_ODEV;
1638 best_case++;
1639 full_overlapping++;
1640 }
1641 else/*in between case*/
1642 {
1643 lat = DR_T_RP+DR_T_RCD+DR_T_CAC+DR_T_PACKET-corrected_overlap;
1644 in_between_case++;
1645 partial_overlapping++;
1646 }
1647 }
1648 else /* same device */
1649 {
1650 if(corrected_overlap >= (DR_T_RP+DR_T_RCD+DR_T_OWR))/*best case*/
1651 {
1652 lat = DR_BEST_T_READ_WRITE_OBANK;
1653 best_case++;
1654 full_overlapping++;
1655 }
1656 else/*in between case*/
1657 {
1658 lat = DR_T_RP+DR_T_RCD+DR_T_CAC+DR_T_PACKET-corrected_overlap;
1659 in_between_case++;
1660 partial_overlapping++;
1661 }
1662 }
1663 }
1664 else/*worst case*/
1665 {
1666 lat = DR_T_RP+DR_T_RCD+DR_T_CAC+DR_T_PACKET;
1667 in_between_case++;
1668 }
1669 }
1670 else/*current_row == DR_NUM_ROWS:precharged or inactive*/
1671 {
1672 if(precharge == 0)/*no adjacent bank is active*/
1673 {
1674 if (corrected_overlap > 0 )/*overlapping*/
1675 {
1676 if(last_dev != current_device)
1677 {
1678 if(corrected_overlap >= (DR_T_RCD+DR_T_CWD+DR_T_PACKET))/*best case*/
1679 {
1680 lat = DR_BEST_T_READ_WRITE_ODEV;
1681 best_case++;
1682 full_overlapping++;
1683 }
1684 else/*in between case*/
1685 {
1686 lat = DR_T_RCD+DR_T_CAC+DR_T_PACKET-corrected_overlap;
1687 in_between_case++;
1688 partial_overlapping++;
1689 }
1690 }
1691 else /* same device */
1692 {
1693 if(corrected_overlap >= (DR_T_RCD+DR_T_OWR))/*best case*/
1694 {
1695 lat = DR_BEST_T_READ_WRITE_OBANK;
1696 best_case++;
1697 full_overlapping++;
1698 }
1699 else/*in between case*/
1700 {
1701 lat = DR_T_RCD+DR_T_CAC+DR_T_PACKET-corrected_overlap;
1702 in_between_case++;
1703 partial_overlapping++;
1704 }
1705 }
1706 }
1707 else/*worst case*/
1708 {
1709 lat = DR_T_RCD+DR_T_CAC+DR_T_PACKET;
1710 in_between_case++;
1711 }
1712 }
1713 else/*one or two adjacent banks are active*/
1714 {
1715 if (precharge == 1)/*an adjacent bank (!=last_bank) needs to be precharged*/
1716 {
1717 if (corrected_overlap > 0 )/*overlapping*/
1718 {
1719 if(last_dev != current_device)
1720 {
1721 if(corrected_overlap >= (DR_T_RP+DR_T_RCD+DR_T_CWD+DR_T_PACKET))/*best case*/
1722 {
1723 lat = DR_BEST_T_READ_WRITE_ODEV;
1724 best_case++;
1725 full_overlapping++;
1726 }
1727 else/*in between case*/
1728 {
1729 lat = (DR_T_RP+DR_T_RCD+DR_T_CAC+DR_T_PACKET)-corrected_overlap;
1730 in_between_case++;
1731 partial_overlapping++;
1732 }
1733 }
1734 else /* same device */
1735 {
1736 if(corrected_overlap >= (DR_T_RP+DR_T_RCD+DR_T_OWR))/*best case*/
1737 {
1738 lat = DR_BEST_T_READ_WRITE_OBANK;
1739 best_case++;
1740 full_overlapping++;
1741 }
1742 else/*in between case*/
1743 {
1744 lat = (DR_T_RP+DR_T_RCD+DR_T_CAC+DR_T_PACKET)-corrected_overlap;
1745 in_between_case++;
1746 partial_overlapping++;
1747 }
1748 }
1749 }
1750 else/*worst case*/
1751 {
1752 lat = (DR_T_RP+DR_T_RCD+DR_T_CAC+DR_T_PACKET);
1753 in_between_case++;
1754 }
1755 }
1756 else /*precharge ==2: two rows have to be precharged*/
1757 {
1758 if (adjacent == 1) /* the banks are adjacent */
1759 {
1760 if (corrected_overlap > 0 )/*overlapping*/
1761 {
1762 if(corrected_overlap >= DR_T_OWR + DR_T_PP)/*best case*/
1763 {
1764 lat = DR_T_READ_WRITE_OBANK-DR_T_OWR - DR_T_PP;
1765 in_between_case++;
1766 full_overlapping++;
1767 }
1768 else/*in between case*/
1769 {
1770 lat = DR_T_READ_WRITE_OBANK-corrected_overlap;
1771 in_between_case++;
1772 partial_overlapping++;
1773 }
1774 }
1775 else/*worst case*/
1776 {
1777 lat = DR_T_READ_WRITE_OBANK;
1778 worst_case++;
1779 }
1780 }
1781 else/*adjacent == 0: two not adjacent banks need to be precharged*/
1782 {
1783 if (corrected_overlap > 0 )/*overlapping*/
1784 {
1785 if (last_dev != current_device)
1786 {
1787 if(corrected_overlap >= (DR_T_PP+DR_T_RP+DR_T_RCD+DR_T_CWD+DR_T_PACKET))/*best case*/
1788 {
1789 lat = DR_BEST_T_READ_WRITE_ODEV;
1790 best_case++;
1791 full_overlapping++;
1792 }
1793 else/*in between case*/
1794 {
1795 lat = DR_T_READ_WRITE_OBANK-corrected_overlap;
1796 in_between_case++;
1797 partial_overlapping++;
1798 }
1799 }
1800 else /* same device */
1801 {
1802 if(corrected_overlap >= (DR_T_PP+DR_T_RP+DR_T_RCD+DR_T_OWR))/*best case*/
1803 {
1804 lat = DR_BEST_T_READ_WRITE_OBANK;
1805 best_case++;
1806 full_overlapping++;
1807 }
1808 else/*in between case*/
1809 {
1810 lat = DR_T_READ_WRITE_OBANK-corrected_overlap;
1811 in_between_case++;
1812 partial_overlapping++;
1813 }
1814 }
1815 }
1816 else/*worst case*/
1817 {
1818 lat = DR_T_READ_WRITE_OBANK;
1819 worst_case++;
1820 }
1821 }
1822 }
1823 }
1824 }
1825 other_bank_read_access_miss[0]++;
1826 obr_after_write_miss++;
1827 }
1828 }
1829 else/*write*/
1830 {
1831 if (current_row == active_row[current_bank])/*row is still active*/
1832 {
1833 if (corrected_overlap > 0 )/*overlapping*/
1834 {
1835 if(corrected_overlap >= DR_T_CWD+DR_T_PACKET)/*best case*/
1836 {
1837 lat = DR_BEST_T_WRITE_READ_OBANK;
1838 best_case++;
1839 full_overlapping++;
1840 }
1841 else/*in between case*/
1842 {
1843 lat = DR_T_CWD+DR_T_PACKET-corrected_overlap;
1844 in_between_case++;
1845 partial_overlapping++;
1846 }
1847 }
1848 else/*in between case*/
1849 {
1850 lat = DR_T_CWD+DR_T_PACKET;
1851 in_between_case++;
1852 }
1853 other_bank_write_access_hit++;
1854 obw_after_read_hit++;
1855 }
1856 else/*row is not active or bank is precharged/not active*/
1857 {
1858 if (active_row[current_bank] != DR_NUM_ROWS)/*row is not active,but bank is active*/
1859 {
1860 if (corrected_overlap > 0 )/*overlapping*/
1861 {
1862 if(corrected_overlap >= (DR_T_RP+DR_T_RCD+DR_T_CWD+DR_T_PACKET))/*best case*/
1863 {
1864 lat = DR_BEST_T_WRITE_READ_OBANK;
1865 best_case++;
1866 full_overlapping++;
1867 }
1868 else/*in between case*/
1869 {
1870 lat = DR_T_RP+DR_T_RCD+DR_T_CWD+DR_T_PACKET-corrected_overlap;
1871 in_between_case++;
1872 partial_overlapping++;
1873 }
1874 }
1875 else/*worst case*/
1876 {
1877 lat = DR_T_RP+DR_T_RCD+DR_T_CWD+DR_T_PACKET;
1878 in_between_case++;
1879 }
1880 }
1881 else/*current_row == DR_NUM_ROWS:precharged or inactive*/
1882 {
1883 if(precharge == 0)/*no adjacent bank is active*/
1884 {
1885 if (corrected_overlap > 0 )/*overlapping*/
1886 {
1887 if(corrected_overlap >= (DR_T_RCD+DR_T_CWD+DR_T_PACKET))/*best case*/
1888 {
1889 lat = DR_BEST_T_WRITE_READ_OBANK;
1890 best_case++;
1891 full_overlapping++;
1892 }
1893 else/*in between case*/
1894 {
1895 lat = DR_T_RCD+DR_T_CWD+DR_T_PACKET-corrected_overlap;
1896 in_between_case++;
1897 partial_overlapping++;
1898 }
1899 }
1900 else/*worst case*/
1901 {
1902 lat = DR_T_RCD+DR_T_CWD+DR_T_PACKET;
1903 in_between_case++;
1904 }
1905 }
1906 else/*one or two adjacent banks are active*/
1907 {
1908 if (precharge == 1)/*an adjacent bank (!=last_bank) needs to be precharged first*/
1909 {
1910 if (corrected_overlap > 0 )/*overlapping*/
1911 {
1912 if(corrected_overlap >= (DR_T_RP+DR_T_RCD+DR_T_CWD+DR_T_PACKET))/*best case*/
1913 {
1914 lat = DR_BEST_T_WRITE_READ_OBANK;
1915 best_case++;
1916 full_overlapping++;
1917 }
1918 else/*in between case*/
1919 {
1920 lat = (DR_T_RP+DR_T_RCD+DR_T_CWD+DR_T_PACKET)-corrected_overlap;
1921 in_between_case++;
1922 partial_overlapping++;
1923 }
1924 }
1925 else/*worst case*/
1926 {
1927 lat = (DR_T_RP+DR_T_RCD+DR_T_CWD+DR_T_PACKET);
1928 in_between_case++;
1929 }
1930 }
1931 else /*precharge ==2: two rows have to be precharged*/
1932 {
1933 if (adjacent == 1)/*these banks are adjacent*/
1934 {
1935 if (corrected_overlap > 0 )/*overlapping*/
1936 {
1937 if(corrected_overlap >= DR_T_PP-DR_T_RDP+2*DR_T_PACKET+DR_T_CAC)/*best case*/
1938 {
1939 lat = DR_T_WRITE_READ_OBANK-(DR_T_PP-DR_T_RDP+2*DR_T_PACKET+DR_T_CAC);
1940 in_between_case++;
1941 full_overlapping++;
1942 }
1943 else/*in between case*/
1944 {
1945 lat = DR_T_WRITE_READ_OBANK-corrected_overlap;
1946 in_between_case++;
1947 partial_overlapping++;
1948 }
1949 }
1950 else/*worst case*/
1951 {
1952 lat = DR_T_WRITE_READ_OBANK;
1953 worst_case++;
1954 }
1955 }
1956 else/*adjacent == 0: two not adjacent banks need to be precharged*/
1957 {
1958 if (corrected_overlap > 0 )/*overlapping*/
1959 {
1960 if(corrected_overlap >= DR_T_WRITE_READ_OBANK)/*best case*/
1961 {
1962 lat = DR_BEST_T_WRITE_READ_OBANK;
1963 best_case++;
1964 full_overlapping++;
1965 }
1966 else/*in between case*/
1967 {
1968 lat = DR_T_WRITE_READ_OBANK-corrected_overlap;
1969 in_between_case++;
1970 partial_overlapping++;
1971 }
1972 }
1973 else/*worst case*/
1974 {
1975 lat = DR_T_WRITE_READ_OBANK;
1976 worst_case++;
1977 }
1978 }
1979 }
1980 }
1981 }
1982 other_bank_write_access_miss[0]++;
1983 obw_after_read_miss++;
1984 }
1985 }
1986 }
1987 }
1988 /*fprintf(stderr,"%4d %4d ",lat,active_row[current_bank]);debugging*/
1989
1990 lat += chunks * DR_T_PACKET; /*every 128 bit need DR_NUM_CYCLES*/
1991
1992 /*fprintf(stderr,"%4d ",lat);debugging*/
1993
1994 if (cpu_ratio < 1.0)
1995 {
1996 lat = (lat+((int)(1/cpu_ratio)-1))/(int)(1/cpu_ratio);
1997 }
1998 else
1999 {
2000 temp = (int)(lat*cpu_ratio);
2001 lat = (lat*cpu_ratio == temp)?temp:(temp+1); /*round up*/
2002 }
2003
2004 active_row[current_bank]=current_row;
2005 lastCmdIsRead = cmdIsRead;
2006 last_bank=current_bank;
2007 last_row = current_row;
2008 last_dev = current_device;
2009
2010 /*fprintf(stderr,"%4d \n",lat);debugging*/
2011
2012 if (overlap <= 0) /*memory interface is not busy*/
2013 {
2014 if (memctrlpipe_enable == true)
2015 {
2016 busy_until[current_bank] =curTick+lat;
2017 }
2018 else
2019 {
2020 if (busy_until[current_bank] >= curTick)
2021 {
2022 busy_until[current_bank] +=lat;
2023 lat=busy_until[current_bank] - curTick;
2024 }
2025 else busy_until[current_bank] = curTick+lat;
2026 }
2027 }
2028 else/*the memory request will be satisfied temp cycles after curTick*/
2029 {
2030 busy_until[current_bank] +=lat;
2031 command_overlapping++;
2032 lat+=overlap;
2033 }
2034
2035 // if((_cpu_num < num_cpus) && (_cpu_num >= 0))
2036 // cout <<"cpu id = " << _cpu_num << "current_bank = " << current_bank << endl;
2037 // bank_access_profile[_cpu_num][current_bank]++;
2038 return lat;
2039 }
2040
2041 /******************************************************************/
2042
2043 else if ((mem_type== "SDRAM") && (mem_actpolicy == "closed") && (memctrlpipe_enable == true))
2044 /* SDRAM closed-page with overlap, 2/00 MG */
2045 {
2046 if ((memctrladdr_type != "interleaved"))/* i.e. mc_type is linear*/
2047 {
2048 // current_bank=physic_address/SD_BANK_SIZE;
2049 current_bank=physic_address/bank_size;
2050 }
2051 else/*mc_type interleaved*/
2052 /* This memory management unit maps the addresses different
2053 * depending on the row_size, every row is mapped to another
2054 * bank. So the text segment uses half of every bank. The heap
2055 * the next quarter of each bank and the stack the rest.
2056 */
2057 {
2058 num_blocks = physic_address/SD_ROW_SIZE; /* row number */
2059 // current_bank=num_blocks%SD_NUM_BANKS;
2060 current_bank=num_blocks%num_banks;
2061 }
2062
2063 if (mem_access_details == true)
2064 {
2065 //fprintf(mem_accessfd," %09u %3d\n",physic_address,current_bank);
2066 }
2067 else
2068 {
2069 if (mem_access_output!=NULL)
2070 {
2071 //fprintf(mem_accessfd,"\n");
2072 }
2073 }
2074 total_access++;
2075
2076 overlap=(int)(busy_until[current_bank] - curTick);
2077
2078 if (current_bank == last_bank)/*same bank*/
2079 {
2080 if ((lastCmdIsRead == cmdIsRead) && (cmdIsRead))/* RAR */
2081 {
2082 lat = act_lat + cas_lat;
2083 }
2084 else if ((lastCmdIsRead == cmdIsRead) && (!cmdIsRead)) /* WAW */
2085 {
2086 lat = act_lat;
2087 }
2088 else if ((lastCmdIsRead != cmdIsRead) && (cmdIsRead)) /* RAW */
2089 {
2090 lat = act_lat + cas_lat;
2091 }
2092 else /* WAR */
2093 {
2094 lat = act_lat;
2095 }
2096 }
2097 else /* other bank */
2098 {
2099 if (cpu_ratio < 1.0)
2100 {
2101 corrected_overlap = overlap*((int)(1/cpu_ratio)); /* floor */
2102 }
2103 else
2104 {
2105 corrected_overlap = (int) (overlap/cpu_ratio);
2106 }
2107
2108 if ((lastCmdIsRead == cmdIsRead) && (cmdIsRead))/* RAR */
2109 {
2110 if (corrected_overlap > act_lat + cas_lat)
2111 {
2112 lat = 0;
2113 best_case++;
2114 full_overlapping++;
2115 }
2116 else if (corrected_overlap > 0)
2117 {
2118 lat = act_lat + cas_lat - corrected_overlap;
2119 in_between_case++;
2120 partial_overlapping++;
2121 }
2122 else
2123 {
2124 lat = act_lat + cas_lat;
2125 worst_case++;
2126 }
2127 }
2128 else if ((lastCmdIsRead == cmdIsRead) && (!cmdIsRead)) /* WAW */
2129 {
2130 if (corrected_overlap > act_lat + pre_lat + (dpl_lat-1))
2131 {
2132 lat = - pre_lat - dpl_lat +1;
2133 best_case++;
2134 full_overlapping++;
2135 }
2136 else if (corrected_overlap > 0)
2137 {
2138 lat = act_lat - corrected_overlap;
2139 in_between_case++;
2140 partial_overlapping++;
2141 }
2142 else
2143 {
2144 lat = act_lat;
2145 worst_case++;
2146 }
2147 }
2148 else if ((lastCmdIsRead != cmdIsRead) && (cmdIsRead)) /* RAW */
2149 {
2150 if (corrected_overlap > cas_lat + pre_lat + dpl_lat - 1 )
2151 {
2152 lat = act_lat - (pre_lat + dpl_lat - 1);
2153 best_case++;
2154 partial_overlapping++;
2155 }
2156 else if (corrected_overlap > 0)
2157 {
2158 lat = act_lat + cas_lat - corrected_overlap;
2159 in_between_case++;
2160 partial_overlapping++;
2161 }
2162 else
2163 {
2164 lat = act_lat + cas_lat;
2165 worst_case++;
2166 }
2167 }
2168 else /* WAR */
2169 {
2170 if (corrected_overlap > act_lat - (dpl_lat-1))
2171 {
2172 lat = dpl_lat-1;
2173 best_case++;
2174 partial_overlapping++;
2175 }
2176 else if (corrected_overlap > 0)
2177 {
2178 lat = act_lat - corrected_overlap;
2179 in_between_case++;
2180 partial_overlapping++;
2181 }
2182 else
2183 {
2184 lat = act_lat;
2185 worst_case++;
2186 }
2187 }
2188 }
2189 lastCmdIsRead = cmdIsRead;
2190 last_bank=current_bank;
2191 last_row = current_row;
2192
2193 lat += chunks;
2194
2195 if (cpu_ratio < 1.0)
2196 {
2197 lat = (lat+((int)(1/cpu_ratio)-1))/(int)(1/cpu_ratio);
2198 }
2199 else
2200 {
2201 temp = (int)(lat*cpu_ratio);
2202 lat = (lat*cpu_ratio == temp)?temp:(temp+1); /*round up*/
2203 }
2204
2205 /*fprintf(stderr,"%4d \n",lat); debugging */
2206
2207 if (overlap <= 0) /*memory interface is not busy*/
2208 {
2209 busy_until[current_bank] = curTick+lat;
2210 }
2211 else /*the memory request will be satisfied temp cycles after curTick*/
2212 {
2213 busy_until[current_bank] +=lat;
2214 command_overlapping++;
2215 total_arb_latency += overlap;
2216 lat+=overlap;
2217 }
2218 if (!cmdIsRead)
2219 {
2220 temp = (int)(((dpl_lat-1) + pre_lat)*cpu_ratio);
2221 busy_until[current_bank] += (((dpl_lat-1) + pre_lat)*cpu_ratio == temp)?temp:(temp+1);
2222 }
2223
2224
2225
2226 /*fprintf(stderr,"%10.0f %10.0f %4d %4d \n",(double)busy_until, (double)curTick, overlap, lat);debug*/
2227 // if((_cpu_num < num_cpus) && (_cpu_num >= 0))
2228 // cout <<"cpu id = " << _cpu_num << "current_bank = " << current_bank << endl;
2229 // bank_access_profile[_cpu_num][current_bank]++;
2230 return lat;
2231 }
2232
2233 /******************************************************************/
2234
2235 else if ((mem_type == "DRDRAM") && (mem_actpolicy == "closed") && (memctrlpipe_enable == true))
2236 /* DRDRAM closed-page with overlap*/
2237 {
2238
2239 if ((memctrladdr_type != "interleaved"))/*i.e. mc_type is linear*/
2240 {
2241 current_bank=physic_address/DR_BANK_SIZE;
2242 current_device=current_bank/(DR_NUM_BANKS/DR_NUM_DEVS);
2243 }
2244 else/*mc_type interleaved*/
2245 /* This memory management unit maps the addresses different
2246 * depending on the row-size, every row is mapped to another
2247 * bank. So the text segment uses half of every bank. The heap
2248 * the next quarter of each bank and the stack the rest.
2249 */
2250 {
2251 num_blocks = physic_address/DR_ROW_SIZE; /* row number */
2252 current_bank=(num_blocks%DR_NUM_BANKS)*2; /*every 'second' bank will be used*/
2253 /*banks above DR_NUM_BANKS are the uneven banks*/
2254 current_bank = ((current_bank < DR_NUM_BANKS) ? current_bank:(current_bank - DR_NUM_BANKS+1));
2255 current_device=current_bank/(DR_NUM_BANKS/DR_NUM_DEVS);
2256 }
2257
2258
2259 if (mem_access_details == true)
2260 {
2261 //fprintf(mem_accessfd," %09u %3d \n",physic_address,current_bank);
2262 }
2263 else
2264 {
2265 if (mem_access_output!=NULL)
2266 {
2267 //fprintf(mem_accessfd,"\n");
2268 }
2269 }
2270 total_access++;
2271
2272 overlap=(int)(busy_until[current_bank] - curTick);
2273
2274 if (cpu_ratio < 1.0)
2275 {
2276 corrected_overlap = overlap*((int)(1/cpu_ratio)); /* floor */
2277 }
2278 else
2279 {
2280 corrected_overlap = (int) (overlap/cpu_ratio);
2281 }
2282
2283 if (current_bank == last_bank)/*same bank*/
2284 {
2285 if ((lastCmdIsRead == cmdIsRead) && (cmdIsRead))/* RAR */
2286 {
2287 lat = DR_T_RCD + DR_T_CAC + DR_T_PACKET;
2288 worst_case++;
2289 }
2290 else if ((lastCmdIsRead == cmdIsRead) && (!cmdIsRead)) /* WAW */
2291 {
2292 lat = DR_T_RCD + DR_T_CWD + DR_T_PACKET;
2293 worst_case++;
2294 }
2295 else if ((lastCmdIsRead != cmdIsRead) && (cmdIsRead)) /* RAW */
2296 {
2297 lat = DR_T_RCD + DR_T_CAC + DR_T_PACKET;
2298 worst_case++;
2299 }
2300 else /* WAR */
2301 {
2302 lat = DR_T_RCD + DR_T_CWD + DR_T_PACKET;
2303 worst_case++;
2304 }
2305 }
2306 else /* other bank */
2307 {
2308 if ((lastCmdIsRead == cmdIsRead) && (cmdIsRead))/* RAR */
2309 {
2310 if (corrected_overlap > DR_T_RAS + DR_T_RP - 2 * DR_T_PACKET)
2311 {
2312 lat = - DR_T_RAS + DR_T_RCD + DR_T_PACKET + DR_T_CAC;
2313 best_case++;
2314 full_overlapping++;
2315 }
2316 else if (corrected_overlap > 0)
2317 {
2318 lat = DR_T_RCD + DR_T_CAC + DR_T_PACKET - corrected_overlap;
2319 in_between_case++;
2320 partial_overlapping++;
2321 }
2322 else
2323 {
2324 lat = DR_T_RCD + DR_T_CAC + DR_T_PACKET;
2325 worst_case++;
2326 }
2327 }
2328 else if ((lastCmdIsRead == cmdIsRead) && (!cmdIsRead)) /* WAW */
2329 {
2330 if (corrected_overlap > DR_T_RCD + DR_T_RTR + DR_T_RP)
2331 {
2332 lat = - DR_T_CWD - 2 * DR_T_PACKET + DR_T_RTR;
2333 best_case++;
2334 full_overlapping++;
2335 }
2336 else if (corrected_overlap > 0)
2337 {
2338 lat = DR_T_RCD + DR_T_CWD + DR_T_PACKET - corrected_overlap;
2339 in_between_case++;
2340 partial_overlapping++;
2341 }
2342 else
2343 {
2344 lat = DR_T_RCD + DR_T_CWD + DR_T_PACKET;
2345 worst_case++;
2346 }
2347 }
2348 else if ((lastCmdIsRead != cmdIsRead) && (cmdIsRead)) /* RAW */
2349 {
2350 if (current_device == last_dev) /* same device */
2351 {
2352 if (corrected_overlap > DR_T_RCD + DR_T_RP)
2353 {
2354 lat = DR_T_PACKET + DR_T_CAC - DR_T_RP;
2355 best_case++;
2356 partial_overlapping++;
2357 }
2358 else if (corrected_overlap > 0)
2359 {
2360 lat = DR_T_RCD + DR_T_CAC + DR_T_PACKET - corrected_overlap;
2361 in_between_case++;
2362 partial_overlapping++;
2363 }
2364 else
2365 {
2366 lat = DR_T_RCD + DR_T_CAC + DR_T_PACKET;
2367 worst_case++;
2368 }
2369 }
2370 else /* other device */
2371 {
2372 if (corrected_overlap > DR_T_RCD + DR_T_RP + 2 * DR_T_PACKET)
2373 {
2374 lat = - DR_T_PACKET + DR_T_CAC - DR_T_RP;
2375 best_case++;
2376 partial_overlapping++;
2377 }
2378 else if (corrected_overlap > 0)
2379 {
2380 lat = DR_T_RCD + DR_T_CAC + DR_T_PACKET - corrected_overlap;
2381 in_between_case++;
2382 partial_overlapping++;
2383 }
2384 else
2385 {
2386 lat = DR_T_RCD + DR_T_CAC + DR_T_PACKET;
2387 worst_case++;
2388 }
2389 }
2390 }
2391 else /* WAR */
2392 {
2393 if (corrected_overlap > DR_T_RAS + DR_T_RP - 2 * DR_T_PACKET - (DR_T_CAC - DR_T_CWD))
2394 {
2395 lat = - DR_T_RAS + DR_T_RCD + DR_T_PACKET + DR_T_CAC;
2396 best_case++;
2397 full_overlapping++;
2398 }
2399 else if (corrected_overlap > 0)
2400 {
2401 lat = DR_T_RCD + DR_T_CWD + DR_T_PACKET - corrected_overlap;
2402 in_between_case++;
2403 partial_overlapping++;
2404 }
2405 else
2406 {
2407 lat = DR_T_RCD + DR_T_CWD + DR_T_PACKET;
2408 worst_case++;
2409 }
2410 }
2411 }
2412
2413 lat += chunks * DR_T_PACKET; /*every 128 bit need DR_NUM_CYCLES*/
2414
2415 /*fprintf(stderr,"%4d ",lat);debugging*/
2416
2417 if (cpu_ratio < 1.0)
2418 {
2419 lat = (lat+((int)(1/cpu_ratio)-1))/(int)(1/cpu_ratio);
2420 }
2421 else
2422 {
2423 temp = (int)(lat*cpu_ratio);
2424 lat = (lat*cpu_ratio == temp)?temp:(temp+1); /*round up*/
2425 }
2426
2427 lastCmdIsRead=cmdIsRead;
2428 last_bank=current_bank;
2429 last_dev = current_device;
2430
2431 /*fprintf(stderr,"%4d \n",lat);debugging*/
2432
2433 if (overlap <= 0) /*memory interface is not busy*/
2434 {
2435 busy_until[current_bank] = curTick+lat;
2436 }
2437 else/*the memory request will be satisfied temp cycles after curTick*/
2438 {
2439 busy_until[current_bank] +=lat;
2440 command_overlapping++;
2441 lat+=overlap;
2442 }
2443
2444 /*fprintf(stderr,"%10.0f %10.0f %4d %4d \n",(double)busy_until, (double)curTick, overlap, lat);*/
2445
2446 if (cmdIsRead)
2447 {
2448 if (cpu_ratio < 1.0)
2449 {
2450 busy_until[current_bank] += abs(((DR_T_RAS - (DR_T_RCD + DR_T_PACKET + DR_T_CAC)) + 1)/((int)(1/cpu_ratio))); /* CPU clock cycles */
2451 }
2452 else
2453 {
2454 busy_until[current_bank] += (int) abs(((DR_T_RAS - (DR_T_RCD + DR_T_PACKET + DR_T_CAC)) + 1)*cpu_ratio); /* CPU clock cycles */
2455 }
2456 }
2457 else /* !cmdIsRead */
2458 {
2459 if (cpu_ratio < 1.0)
2460 {
2461 busy_until[current_bank] += abs((-DR_T_PACKET + DR_T_RTR + DR_T_RP - DR_T_CWD + 1)/((int)(1/cpu_ratio))); /* CPU clock cycles */
2462 }
2463 else
2464 {
2465 busy_until[current_bank] += (int) abs((-DR_T_PACKET + DR_T_RTR + DR_T_RP - DR_T_CWD + 1)*cpu_ratio); /* CPU clock cycles */
2466 }
2467 }
2468
2469 // if((_cpu_num < num_cpus) && (_cpu_num >= 0))
2470 // cout <<"cpu id = " << _cpu_num << "current_bank = " << current_bank << endl;
2471 // bank_access_profile[_cpu_num][current_bank]++;
2472 return lat;
2473 }
2474
2475 /******************************************************************/
2476
2477 else if ((mem_type == "SDRAM") && (mem_actpolicy == "closed") && (memctrlpipe_enable == false))
2478 /* SDRAM closed-page without overlap, 7/99 MG */
2479 {
2480 if (mem_access_output != NULL)
2481 {
2482 //fprintf(mem_accessfd,"\n");
2483 }
2484 assert(chunks >0);
2485
2486 if (cmdIsRead)
2487 {
2488 lat = act_lat + cas_lat;
2489 }
2490 else /* !cmdIsRead */
2491 {
2492 lat = act_lat;
2493 }
2494 total_access++;
2495 lat += chunks;
2496
2497 overlap=(int)(busy_until[current_bank] - curTick);
2498 lastCmdIsRead=cmdIsRead;
2499
2500 if (cpu_ratio < 1.0)
2501 {
2502 lat = (lat+((int)(1/cpu_ratio)-1))/(int)(1/cpu_ratio);
2503 }
2504 else
2505 {
2506 temp = (int)(lat*cpu_ratio);
2507 lat = (lat*cpu_ratio == temp)?temp:(temp+1); /*round up*/
2508 }
2509
2510 if (overlap <= 0) /*memory interface is not busy*/
2511 {
2512 busy_until[current_bank] = curTick+lat;
2513 }
2514 else/*the memory request will be satisfied temp cycles after curTick*/
2515 {
2516 busy_until[current_bank] +=lat;
2517 command_overlapping++;
2518 lat+=overlap;
2519 }
2520 if (!cmdIsRead)
2521 {
2522 temp = (int)(((dpl_lat-1) + pre_lat)*cpu_ratio);
2523 busy_until[current_bank] += (((dpl_lat-1) + pre_lat)*cpu_ratio == temp)?temp:(temp+1);
2524 }
2525
2526 // if((_cpu_num < num_cpus) && (_cpu_num >= 0))
2527 // cout <<"cpu id = " << _cpu_num << "current_bank = " << current_bank << endl;
2528 // bank_access_profile[_cpu_num][current_bank]++;
2529 return lat;
2530 }
2531
2532 /******************************************************************/
2533
2534 else if ((mem_type == "DRDRAM") && (mem_actpolicy == "closed") && (memctrlpipe_enable == false))
2535 /* DRDRAM closed-page without overlap */
2536 {
2537 if (cmdIsRead)
2538 {
2539 lat = DR_T_RCD + DR_T_CAC + DR_T_PACKET; /* DR_T_RP + */
2540 }
2541 else /* !cmdIsRead */
2542 {
2543 lat = DR_T_RCD + DR_T_CWD + DR_T_PACKET; /* DR_T_RP + */
2544 }
2545 total_access++;
2546 overlap=(int)(busy_until[current_bank] - curTick);
2547 lat += chunks * DR_T_PACKET; /*every 128 bit need DR_NUM_CYCLES*/
2548
2549 if (cpu_ratio < 1.0)
2550 {
2551 lat = (lat+((int)(1/cpu_ratio)-1))/(int)(1/cpu_ratio);
2552 }
2553 else
2554 {
2555 temp = (int)(lat*cpu_ratio);
2556 lat = (lat*cpu_ratio == temp)?temp:(temp+1); /*round up*/
2557 }
2558
2559 lastCmdIsRead=cmdIsRead;
2560
2561 if (overlap <= 0) /*memory interface is not busy*/
2562 {
2563 busy_until[current_bank] = curTick+lat;
2564 }
2565 else/*the memory request will be satisfied temp cycles after curTick*/
2566 {
2567 busy_until[current_bank] += lat;
2568 command_overlapping++;
2569 lat+=overlap;
2570 }
2571
2572 if (cmdIsRead)
2573 {
2574 if (cpu_ratio < 1.0)
2575 {
2576 busy_until[current_bank] += abs(((DR_T_RAS - (DR_T_RCD + DR_T_PACKET + DR_T_CAC)) + 1)/((int)(1/cpu_ratio))); /* CPU clock cycles */
2577 }
2578 else
2579 {
2580 busy_until[current_bank] += (int) abs(((DR_T_RAS - (DR_T_RCD + DR_T_PACKET + DR_T_CAC)) + 1)*cpu_ratio); /* CPU clock cycles */
2581 }
2582 }
2583 else /* !cmdIsRead */
2584 {
2585 if (cpu_ratio < 1.0)
2586 {
2587 busy_until[current_bank] += abs((-DR_T_PACKET + DR_T_RTR + DR_T_RP - DR_T_CWD + 1)/((int)(1/cpu_ratio))); /* CPU clock cycles */
2588 }
2589 else
2590 {
2591 busy_until[current_bank] += (int) abs((-DR_T_PACKET + DR_T_RTR + DR_T_RP - DR_T_CWD + 1)*cpu_ratio); /* CPU clock cycles */
2592 }
2593 }
2594 // if((_cpu_num < num_cpus) && (_cpu_num >= 0))
2595 // cout <<"cpu id = " << _cpu_num << "current_bank = " << current_bank << endl;
2596 // bank_access_profile[_cpu_num][current_bank]++;
2597 return lat;
2598 }
2599
2600 /******************************************************************/
2601
2602 else /*STD*/
2603 {
2604 if (mem_access_output != NULL)
2605 {
2606 //fprintf(mem_accessfd,"\n");
2607 }
2608 assert(chunks >0);
2609 // if((_cpu_num < num_cpus) && (_cpu_num >= 0))
2610 // cout <<"cpu id = " << _cpu_num << "current_bank = " << current_bank << endl;
2611 // bank_access_profile[_cpu_num][current_bank]++;
2612 return(/* first chunk latency */act_lat +
2613 (/* remainder chunk latency */cas_lat * (chunks - 1)));
2614 }
2615
2616 }
2617
2618 /*end added by ar, MG*/
2619
2620 /*begin added by ar, MG*/
2621
2622 /* ================ helper functions ========================= */
2623
2624 /****** DRDRAM specific: shared sense amplifiers ******/
2625 /* precharges the adjacent banks and returns the number of them (1 or 2)*/
2626 int /*number of precharged banks*/
2627 DRAMMemory::prechargeBanksAround(int bank)/*access to bank */
2628 {
2629 int temp;
2630
2631 temp=bank%DR_BANK_SAMP;
2632
2633 if (temp == 0) /*bank 0, 16,32 ....*/
2634 {
2635 if (active_row[bank+1]!=DR_NUM_ROWS)
2636 {
2637 precharge++;
2638 active_row[bank+1]=DR_NUM_ROWS;
2639 }
2640 }
2641 else
2642 {
2643 if (temp==DR_BANK_SAMP-1)/*banks 15,31 ...*/
2644 {
2645 if (active_row[bank-1]!=DR_NUM_ROWS)
2646 {
2647 precharge++;
2648 active_row[bank-1]=DR_NUM_ROWS;
2649 }
2650 }
2651 else
2652 {
2653 if (active_row[bank-1]!=DR_NUM_ROWS)
2654 {
2655 precharge++;
2656 active_row[bank-1]=DR_NUM_ROWS;
2657 }
2658 if (active_row[bank+1]!=DR_NUM_ROWS)
2659 {
2660 precharge++;
2661 active_row[bank+1]=DR_NUM_ROWS;
2662 }
2663 }
2664 }
2665 return precharge;
2666 }
2667
2668 DRAMMemory *
2669 DRAMMemoryParams::create()
2670 {
2671 return new DRAMMemory(this);
2672 }