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