2 * Copyright (c) 2004 The Regents of The University of Michigan
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.
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.
33 Copyright (c) 2000 Computer Engineering and Communication Networks Lab (TIK)
34 Swiss Federal Institute of Technology (ETH) Zurich, Switzerland
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
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
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.
57 /* authors: Andreas Romer 4/99 - 7/99
58 Matthias Gries 4/99 - 2/01
61 References: http://www.tik.ee.ethz.ch/
62 ======================================
63 -> Publications http://www.tik.ee.ethz.ch/db/tik/publications/form_search_publications.php3
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
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.
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)
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.
87 -> performance study with SimpleScalar
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.
94 -> SDRAM + controller performance model as a high-level Petri net
99 * Definition of a DRAM like main memory.
105 #include "mem/dram.hh"
107 extern int maxThreadsPerCPU
;
109 /* SDRAM system: PC100/PC133 2-2-2 DIMM timing according to
110 PC SDRAM Specification, Rev. 1.7, Intel Corp, Nov. 1999.
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 */
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 */
171 #define MIN(a,b) ((a<b) ? a : b)
172 #define SD_ROW_SIZE 0x1000 /* size of a row : 4 Kbyte */
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)
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;
204 busy_until
= new Tick
[num_banks
];
205 std::memset(busy_until
,0,sizeof(Tick
)*num_banks
); /* initiliaze */
210 DRAMMemory::regStats()
212 using namespace Stats
;
215 .init(maxThreadsPerCPU
)
216 .name(name() + ".accesses")
217 .desc("total number of accesses")
222 .init(maxThreadsPerCPU
)
223 .name(name() + ".bytes_requested")
224 .desc("total number of bytes requested")
229 .init(maxThreadsPerCPU
)
230 .name(name() + ".bytes_sent")
231 .desc("total number of bytes sent")
236 .init(maxThreadsPerCPU
)
237 .name(name() + ".compressed_responses")
238 .desc("total number of accesses that are compressed")
242 // stats for power modelling
245 .name(name() + ".cycles_nCKE")
246 .desc("cycles when CKE is low")
250 cycles_all_precharge_CKE
252 .name(name() + ".cycles_all_precharge_CKE")
253 .desc("cycles when all banks precharged")
257 cycles_all_precharge_nCKE
259 .name(name() + ".cycles_all_precharge_nCKE")
260 .desc("cycles when all banks precharged and CKE is low")
264 cycles_bank_active_nCKE
266 .name(name() + ".cycles_bank_active_nCKE")
267 .desc("cycles when banks active and CKE low")
271 // we derive this from other stats later
272 // so DR TODO for now this counter is unused
275 .name(name() + ".cycles_avg_ACT")
276 .desc("avg cycles between ACT commands")
282 .name(name() + ".cycles_read_out")
283 .desc("cycles outputting read data")
289 .name(name() + ".cycles_write_in")
290 .desc("cycles inputting write data")
294 cycles_between_misses
296 .name(name() + ".cycles_between_misses")
297 .desc("cycles between open page misses")
301 other_bank_read_access_miss
303 .name(name() + ".other_bank_read_access_miss")
304 .desc("read miss count")
308 other_bank_write_access_miss
310 .name(name() + ".other_bank_write_access_miss")
311 .desc("write miss count")
315 // DR TODO for now, only output stats which are involved in power equations
317 .name(name() + ".total_latency")
318 .desc("total DRAM latency")
322 .name(name() + ".total_arb_latency")
323 .desc("total arbitration latency")
327 .name(name() + ".avg_latency")
328 .desc("average DRAM latency")
332 .name(name() + ".avg_arb_latency")
333 .desc("average arbitration DRAM latency")
337 .init(num_banks
,num_cpus
)
338 .name(name() + "[cpu][bank]")
339 .desc("DRAM bank access profile")
343 .name(name() + ".total_icache_req")
344 .desc("total number of requests from icache")
347 avg_latency
= total_latency
/ accesses
;
348 avg_arb_latency
= total_arb_latency
/ accesses
;
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
358 static char *mem_access_output
=NULL
;
359 /* latency of access [CPU cycles]*/
361 DRAMMemory::calculateLatency(PacketPtr pkt
)
364 bool cmdIsRead
= pkt
->isRead();
366 int lat
=0, temp
=0, current_bank
=0;
367 int current_row
=0, current_device
=0;
369 int was_miss
= 0; // determines if there was an active row miss this access
371 //md_addr_t physic_address; /* linear memory address to be accessed */
372 Addr physic_address
; /* linear memory address to be accessed */
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*/
379 int chunks
= (pkt
->getSize() + (bus_width
- 1)) / bus_width
; // burst length
381 physic_address
= pkt
->getAddr();
383 ///////////////////////////////////////////////////////////////////////////
384 // DR added more stats for power modelling
386 // for DRAM closed-page, automatic precharge after read or write,
387 // i.e. whenever idle
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 */
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;
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;
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
;
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
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;
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
);
448 cycles_all_precharge_CKE
[0] += time_since_last_access
;
450 } else { // some bank is active
452 cycles_bank_active_nCKE
[0] += MIN(curTick
-busy_until
[current_bank
], time_since_last_access
);
459 cycles_read_out
[0] += chunks
;
461 cycles_write_in
[0] += chunks
;
465 time_last_access
= curTick
;
466 ////////////////////////////////////////////////////////////////////////////
468 if ((mem_type
== "SDRAM") && (mem_actpolicy
== "open"))
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 */
484 if ((memctrladdr_type
!= "interleaved"))/* i.e. mc_type is linear */
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
;
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.
498 num_blocks
= physic_address
/SD_ROW_SIZE
; /* row number */
499 current_bank
=num_blocks
%num_banks
;
500 current_row
=num_blocks
/num_banks
;
503 if (mem_access_details
== true)
506 //fprintf(mem_accessfd," %09u %4d %3d\n",physic_address,current_row,current_bank);
510 if (mem_access_output
!=0)
512 //fprintf(mem_accessfd,"\n");
517 if (memctrlpipe_enable
== true)
519 overlap
=(int)(busy_until
[current_bank
] - curTick
);
525 corrected_overlap
= overlap
*((int)(1/cpu_ratio
)); /* floor */
529 corrected_overlap
= (int) (overlap
/cpu_ratio
);
532 /*fprintf(stderr,"%10.0f %10.0f %4d %4d ",(double)busy_until, (double)curTick, overlap, corrected_overlap); debugging*/
534 if (cmdIsRead
== lastCmdIsRead
)/*same command*/
536 if (current_bank
== last_bank
)/*same bank*/
538 if (current_row
== last_row
)/*same row*/
543 if (corrected_overlap
> 0)/*overlapping*/
546 if (corrected_overlap
>= cas_lat
)
548 lat
=SD_BEST_T_READ_READ_SROW
;
553 else/*in between case*/
555 lat
= cas_lat
-corrected_overlap
;
558 partial_overlapping
++;
564 lat
= SD_T_READ_READ_SROW
;
568 same_row_read_access
++;
573 lat
= SD_T_WRITE_WRITE_SROW
;
575 same_row_write_access
++;
580 else /*other row in same bank*/
585 if (corrected_overlap
> 0)/*overlapping*/
587 if (corrected_overlap
>= pre_lat
)/*best case*/
589 lat
= SD_BEST_T_READ_READ_SBANK
;
593 else/*in between case*/
595 lat
= SD_T_READ_READ_SBANK
-corrected_overlap
;
597 partial_overlapping
++;
602 lat
= SD_T_READ_READ_SBANK
;
605 same_bank_read_access
++;
610 lat
= SD_T_WRITE_WRITE_SBANK
;
611 same_bank_write_access
++;
622 if (current_row
== active_row
[current_bank
])/*row is still active*/
624 if (corrected_overlap
> 0 )/*overlapping*/
626 if(corrected_overlap
>= pre_lat
)/*best case*/
628 lat
= SD_BEST_T_READ_READ_OBANK
;
632 else/*in between case*/
634 lat
= SD_T_READ_READ_OBANK
- corrected_overlap
;
636 partial_overlapping
++;
639 else/*in between case*/
641 lat
= SD_T_READ_READ_OBANK
;
644 other_bank_read_access_hit
++;
645 obr_after_read_hit
++;
647 else/*row is not active*/
649 if (corrected_overlap
> 0 )/*overlapping*/
651 if(corrected_overlap
>= SD_T_READ_READ_OBANK
)/*best case*/
653 lat
= SD_BEST_T_READ_READ_OBANK
;
657 else/*in between case*/
659 lat
= SD_T_READ_READ_OBANK
-corrected_overlap
;
661 partial_overlapping
++;
666 lat
= SD_T_READ_READ_OBANK
;
670 // DR keep track of time between misses
673 other_bank_read_access_miss
[0]++;
674 obr_after_read_miss
++;
679 if (current_row
== active_row
[current_bank
])/*row is still active*/
681 lat
= SD_BEST_T_WRITE_WRITE_OBANK
;
683 other_bank_write_access_hit
++;
684 obw_after_write_hit
++;
686 else/*row is not active*/
688 if (corrected_overlap
> 0 )/*overlapping*/
690 if(corrected_overlap
>=SD_T_WRITE_WRITE_OBANK
)/*best case*/
692 lat
= SD_BEST_T_WRITE_WRITE_OBANK
;
696 else/*in between case*/
698 lat
= SD_T_WRITE_WRITE_OBANK
-corrected_overlap
;
700 partial_overlapping
++;
705 lat
= SD_T_WRITE_WRITE_OBANK
;
709 // DR keep track of time between misses
712 other_bank_write_access_miss
[0]++;
713 obw_after_write_miss
++;
719 else /*lastCmdIsRead != cmdIsRead*/
721 if (current_bank
== last_bank
)/*same bank*/
723 if (current_row
== last_row
)/*same row*/
728 lat
= SD_T_READ_WRITE_SROW
;
730 same_row_read_access
++;
736 lat
= SD_T_WRITE_READ_SROW
;
738 same_row_write_access
++;
743 else /*other row in same bank*/
748 lat
= SD_T_READ_WRITE_SBANK
;
749 same_bank_read_access
++;
755 if (corrected_overlap
> 0 )/*overlapping*/
757 if (corrected_overlap
>= pre_lat
)/*best case*/
759 lat
= SD_BEST_T_WRITE_READ_SBANK
;
763 else/*in between case*/
765 lat
= SD_T_WRITE_READ_SBANK
-corrected_overlap
;
767 partial_overlapping
++;
772 lat
= SD_T_WRITE_READ_OBANK
;
775 same_bank_write_access
++;
785 if (current_row
== active_row
[current_bank
])/*row is still active*/
787 lat
= SD_BEST_T_READ_WRITE_OBANK
;
789 other_bank_read_access_hit
++;
790 obr_after_write_hit
++;
792 else/*row is not active*/
794 if (corrected_overlap
> 0 )/*overlapping*/
796 if(corrected_overlap
>= (pre_lat
+act_lat
))/*best case*/
798 lat
= SD_BEST_T_READ_WRITE_OBANK
;
802 else/*in between case*/
804 lat
= SD_T_READ_WRITE_OBANK
-corrected_overlap
;
806 partial_overlapping
++;
811 lat
= SD_T_READ_WRITE_OBANK
;
814 // DR keep track of time between misses
817 other_bank_read_access_miss
[0]++;
818 obr_after_write_miss
++;
823 if (current_row
== active_row
[current_bank
])/*row is still active*/
825 lat
= SD_BEST_T_WRITE_READ_OBANK
;
827 other_bank_write_access_hit
++;
828 obw_after_read_hit
++;
830 else/*row is not active*/
832 if (corrected_overlap
> 0 )/*overlapping*/
834 if (corrected_overlap
>= (SD_T_WRITE_READ_OBANK
-SD_BEST_T_WRITE_READ_OBANK
))/*best case*/
836 lat
= SD_BEST_T_WRITE_READ_OBANK
;
840 else/*in between case*/
842 lat
= SD_T_WRITE_READ_OBANK
-corrected_overlap
;
844 partial_overlapping
++;
849 lat
= SD_T_WRITE_READ_OBANK
;
853 // DR keep track of time between misses
856 other_bank_write_access_miss
[0]++;
857 obw_after_read_miss
++;
862 /*fprintf(stderr,"%4d %4d ",lat,active_row[current_bank]);debugging*/
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);
869 /*fprintf(stderr,"%4d ",lat);debugging*/
871 active_row
[current_bank
]=current_row
; /* open-page (hit) register */
872 lastCmdIsRead
= cmdIsRead
;
873 last_bank
= current_bank
;
874 last_row
= current_row
;
878 lat
= (lat
+((int)(1/cpu_ratio
)-1))/(int)(1/cpu_ratio
);
882 temp
= (int)(lat
*cpu_ratio
);
883 lat
= (lat
*cpu_ratio
== temp
)?temp
:(temp
+1); /*round up*/
886 /*fprintf(stderr,"%4d \n",lat);debugging*/
888 if (overlap
<= 0) /*memory interface is not busy*/
890 if (memctrlpipe_enable
== true)
892 busy_until
[current_bank
]=curTick
+lat
+
897 if (busy_until
[current_bank
] >= curTick
)
899 busy_until
[current_bank
]+=(lat
+
901 total_arb_latency
+= (busy_until
[current_bank
]
903 - timing_correction
);
904 lat
=busy_until
[current_bank
] - curTick
;
906 else busy_until
[current_bank
]=curTick
+lat
+
910 else/*the memory request will be satisfied temp cycles after curTick*/
912 busy_until
[current_bank
] +=(lat
+
914 command_overlapping
++;
916 total_arb_latency
+= overlap
;
919 // DR for power stats
921 cycles_between_misses
[0] += (busy_until
[current_bank
] - time_last_miss
);
922 time_last_miss
= busy_until
[current_bank
];
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]++;
932 /***********************************************************/
933 /******************** DRDRAM ***********************/
934 /***********************************************************/
936 else if ((mem_type
== "DRDRAM") && (mem_actpolicy
== "open"))/*DRDRAM*/ /*a closed bank has an activ_row number of DR_NUM_ROWS: highest +1*/
938 if ((memctrladdr_type
!= "interleaved"))/* i.e. mc_type is linear */
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
);
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.
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
);
961 if (abs(current_bank
-last_bank
)==1)/*access to an adjacent bank*/
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)*/
967 adjacent
=1;/*an adjacent bank is accessed*/
974 precharge
=0;/*at this moment no bank needs to be precharged*/
975 if (active_row
[current_bank
] == DR_NUM_ROWS
)/*bank is precharged*/
977 if (prechargeBanksAround(current_bank
)> 0)/*a bank next to the current is activated*/
979 if ((adjacent
==1)&&(precharge
==1))
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*/
989 if (mem_access_details
== true)
991 //fprintf(mem_accessfd," %09u %4d %3d %15d\n",physic_address,current_row,current_bank,(int)adjacent_access);
995 if (mem_access_output
!=NULL
)
997 //fprintf(mem_accessfd,"\n");
1002 if (memctrlpipe_enable
== true)
1004 overlap
=(int)(busy_until
[current_bank
] - curTick
);
1008 if (cpu_ratio
< 1.0)
1010 corrected_overlap
= overlap
*((int)(1/cpu_ratio
)); /* floor */
1014 corrected_overlap
= (int) (overlap
/cpu_ratio
);
1017 /*fprintf(stderr,"%10.0f %10.0f %6d %6d %2d %2d ",(double)busy_until, (double)curTick, overlap, corrected_overlap,precharge,adjacent);debugging*/
1019 if (cmdIsRead
== lastCmdIsRead
)/*same command*/
1021 if (current_bank
== last_bank
)/*same bank*/
1023 if (current_row
== last_row
)/*same row*/
1027 if (corrected_overlap
> 0)/*overlapping*/
1030 if (corrected_overlap
>= DR_T_READ_READ_SROW
)
1032 lat
=DR_BEST_T_READ_READ_SROW
;
1037 else/*in between case*/
1039 lat
= DR_T_READ_READ_SROW
-corrected_overlap
;
1042 partial_overlapping
++;
1048 lat
= DR_T_READ_READ_SROW
;
1052 same_row_read_access
++;
1055 else/*write, always retire the previous data*/
1057 if (corrected_overlap
> 0)/*overlapping*/
1060 if (corrected_overlap
>= DR_T_OWR
)
1062 lat
=DR_BEST_T_WRITE_WRITE_SROW
;
1067 else/*in between case*/
1069 lat
= DR_T_WRITE_WRITE_SROW
-corrected_overlap
;
1072 partial_overlapping
++;
1078 lat
= DR_T_WRITE_WRITE_SROW
;
1082 same_row_write_access
++;
1086 else /*other row in same bank*/
1090 if (corrected_overlap
> 0)/*overlapping*/
1092 if (corrected_overlap
>= DR_T_HELP
)/*best case*/
1094 lat
= DR_BEST_T_READ_READ_SBANK
;
1098 else/*in between case*/
1100 lat
= DR_T_READ_READ_SBANK
-corrected_overlap
;
1102 partial_overlapping
++;
1107 lat
= DR_T_READ_READ_SBANK
;
1110 same_bank_read_access
++;
1115 if (corrected_overlap
> 0)/*overlapping*/
1117 if (corrected_overlap
>= DR_T_OWR
)/*best case*/
1119 lat
= DR_BEST_T_WRITE_WRITE_SBANK
;
1123 else/*in between case*/
1125 lat
= DR_T_WRITE_WRITE_SBANK
-corrected_overlap
;
1127 partial_overlapping
++;
1132 lat
= DR_T_WRITE_WRITE_SBANK
;
1135 same_bank_write_access
++;
1144 if (current_row
== active_row
[current_bank
])/*row is still active*/
1146 if (corrected_overlap
> 0 )/*overlapping*/
1148 if(corrected_overlap
>= (DR_T_CAC
+DR_T_PACKET
))/*best case*/
1150 lat
= DR_BEST_T_READ_READ_OBANK
;
1154 else/*in between case*/
1156 lat
= DR_T_CAC
+DR_T_PACKET
-corrected_overlap
;
1158 partial_overlapping
++;
1161 else/*in between case*/
1163 lat
= DR_T_CAC
+DR_T_PACKET
;
1166 other_bank_read_access_hit
++;
1167 obr_after_read_hit
++;
1169 else/*row is not active or bank is precharged/not active*/
1171 if (active_row
[current_bank
]!=DR_NUM_ROWS
)/*row is not active, but bank is active*/
1173 if (corrected_overlap
> 0 )/*overlapping*/
1175 if(corrected_overlap
>= (DR_T_RP
+DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
))/*best case*/
1177 lat
= DR_BEST_T_READ_READ_OBANK
;
1181 else/*in between case*/
1183 lat
= DR_T_RP
+DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
-corrected_overlap
;
1185 partial_overlapping
++;
1190 lat
= DR_T_RP
+DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
;
1194 else/*current_row == DR_NUM_ROWS:precharged or inactive*/
1196 if(precharge
== 0)/*no adjacent bank is active*/
1198 if (corrected_overlap
> 0 )/*overlapping*/
1200 if(corrected_overlap
>= (DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
))/*best case*/
1202 lat
= DR_BEST_T_READ_READ_OBANK
;
1206 else/*in between case*/
1208 lat
= DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
-corrected_overlap
;
1210 partial_overlapping
++;
1215 lat
= DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
;
1219 else/*one ore two adjacent banks are active*/
1223 if (corrected_overlap
> 0 )/*overlapping*/
1225 if(corrected_overlap
>= (DR_T_RP
+DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
))/*best case*/
1227 lat
= DR_BEST_T_READ_READ_OBANK
;
1231 else/*in between case*/
1233 lat
= (DR_T_RP
+DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
)-corrected_overlap
;
1235 partial_overlapping
++;
1240 lat
= (DR_T_RP
+DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
);
1244 else /*precharge ==2: two rows must be precharged*/
1246 if (adjacent
== 1)/*these banks are adjacent*/
1248 if (corrected_overlap
> 0 )/*overlapping*/
1250 if(corrected_overlap
>= DR_T_PP
+2*DR_T_PACKET
-DR_T_RDP
+DR_T_CAC
)/*best case*/
1252 lat
= DR_T_RDP
+DR_T_RP
+DR_T_RCD
-DR_T_PACKET
;
1256 else/*in between case*/
1258 lat
= DR_T_READ_READ_OBANK
-corrected_overlap
;
1260 partial_overlapping
++;
1265 lat
= DR_T_READ_READ_OBANK
;
1269 else/*adjacent == 0: two not adjacent banks need to be precharged*/
1271 if (corrected_overlap
> 0 )/*overlapping*/
1273 if(corrected_overlap
>= DR_T_READ_READ_OBANK
)/*best case*/
1275 lat
= DR_BEST_T_READ_READ_OBANK
;
1279 else/*in between case*/
1281 lat
= DR_T_READ_READ_OBANK
-corrected_overlap
;
1283 partial_overlapping
++;
1288 lat
= DR_T_READ_READ_OBANK
;
1295 other_bank_read_access_miss
[0]++;
1296 obr_after_read_miss
++;
1301 if (current_row
== active_row
[current_bank
])/*row is still active*/
1303 if (corrected_overlap
> 0 )/*overlapping*/
1305 if(corrected_overlap
>= (DR_T_CWD
+DR_T_PACKET
))/*best case*/
1307 lat
= DR_BEST_T_WRITE_WRITE_OBANK
;
1311 else/*in between case*/
1313 lat
= DR_T_CWD
+DR_T_PACKET
-corrected_overlap
;
1315 partial_overlapping
++;
1320 lat
= DR_T_CWD
+DR_T_PACKET
;
1323 other_bank_write_access_hit
++;
1324 obw_after_write_hit
++;
1326 else/*row is not active or bank is precharged/not active*/
1328 if (active_row
[current_bank
] != DR_NUM_ROWS
)/*row is not active,but bank is active*/
1330 if (corrected_overlap
> 0 )/*overlapping*/
1332 if(corrected_overlap
>= (DR_T_RP
+DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
))/*best case*/
1334 lat
= DR_BEST_T_WRITE_WRITE_OBANK
;
1338 else/*in between case*/
1340 lat
= DR_T_RP
+DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
-corrected_overlap
;
1342 partial_overlapping
++;
1347 lat
= DR_T_RP
+DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
;
1351 else/*current_row == DR_NUM_ROWS:precharged or inactive*/
1353 if(precharge
== 0)/*no adjacent bank is active*/
1355 if (corrected_overlap
> 0 )/*overlapping*/
1357 if(corrected_overlap
>= (DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
))/*best case*/
1359 lat
= DR_BEST_T_WRITE_WRITE_OBANK
;
1363 else/*in between case*/
1365 lat
= DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
-corrected_overlap
;
1367 partial_overlapping
++;
1372 lat
= DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
;
1376 else/*one ore two adjacent banks are active*/
1378 if (precharge
== 1)/*last_bank is no adjacent*/
1380 if (corrected_overlap
> 0 )/*overlapping*/
1382 if(corrected_overlap
>= (DR_T_RP
+DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
))/*best case*/
1384 lat
= DR_BEST_T_WRITE_WRITE_OBANK
;
1388 else/*in between case*/
1390 lat
= (DR_T_RP
+DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
)-corrected_overlap
;
1392 partial_overlapping
++;
1397 lat
= (DR_T_RP
+DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
);
1401 else /*precharge ==2: two rows have to be precharged*/
1403 if (adjacent
== 1)/*these banks are adjacent*/
1405 if (corrected_overlap
> 0 )/*overlapping*/
1407 if(corrected_overlap
>= DR_T_OWR
+DR_T_PP
)/*best case*/
1409 lat
= DR_T_WRITE_WRITE_OBANK
-DR_T_OWR
-DR_T_PP
;
1413 else/*in between case*/
1415 lat
= DR_T_WRITE_WRITE_OBANK
-corrected_overlap
;
1417 partial_overlapping
++;
1422 lat
= DR_T_WRITE_WRITE_OBANK
;
1426 else/*adjacent == 0: two not adjacent banks need to be precharged*/
1428 if (corrected_overlap
> 0 )/*overlapping*/
1430 if(corrected_overlap
>= DR_T_WRITE_WRITE_OBANK
)/*best case*/
1432 lat
= DR_BEST_T_WRITE_WRITE_OBANK
;
1436 else/*in between case*/
1438 lat
= DR_T_WRITE_WRITE_OBANK
-corrected_overlap
;
1440 partial_overlapping
++;
1445 lat
= DR_T_WRITE_WRITE_OBANK
;
1452 other_bank_write_access_miss
[0]++;
1453 obw_after_write_miss
++;
1458 else /*lastCmdIsRead != cmdIsRead*/
1460 if (current_bank
== last_bank
)/*same bank*/
1462 if (current_row
== last_row
)/*same row*/
1466 if (corrected_overlap
> 0)/*overlapping*/
1469 if (corrected_overlap
>= DR_T_OWR
)
1471 lat
=DR_BEST_T_READ_WRITE_SROW
;
1476 else/*in between case*/
1478 lat
= DR_T_READ_WRITE_SROW
-corrected_overlap
;
1481 partial_overlapping
++;
1487 lat
= DR_T_READ_WRITE_SROW
;
1491 same_row_read_access
++;
1496 if (corrected_overlap
> 0)/*overlapping*/
1499 if (corrected_overlap
>= DR_T_WRITE_READ_SROW
)
1501 lat
=DR_BEST_T_WRITE_READ_SROW
;
1506 else/*in between case*/
1508 lat
= DR_T_WRITE_READ_SROW
-corrected_overlap
;
1511 partial_overlapping
++;
1517 lat
= DR_T_WRITE_READ_SROW
;
1521 same_row_write_access
++;
1525 else /*other row in same bank*/
1529 if (corrected_overlap
> 0 )/*overlapping*/
1531 if (corrected_overlap
>= DR_T_OWR
)/*best case*/
1533 lat
= DR_BEST_T_READ_WRITE_SBANK
;
1537 else/*in between case*/
1539 lat
= DR_T_READ_WRITE_SBANK
-corrected_overlap
;
1541 partial_overlapping
++;
1546 lat
= DR_T_READ_WRITE_SBANK
;
1549 same_bank_read_access
++;
1554 if (corrected_overlap
> 0 )/*overlapping*/
1556 if (corrected_overlap
>= DR_T_HELP
)/*best case*/
1558 lat
= DR_BEST_T_WRITE_READ_SBANK
;
1562 else/*in between case*/
1564 lat
= DR_T_WRITE_READ_SBANK
-corrected_overlap
;
1566 partial_overlapping
++;
1571 lat
= DR_T_WRITE_READ_SBANK
;
1574 same_bank_write_access
++;
1583 if (current_row
== active_row
[current_bank
])/*row is still active*/
1585 if (corrected_overlap
> 0 )/*overlapping*/
1587 if(last_dev
!= current_device
)
1589 if(corrected_overlap
>= DR_T_CWD
+DR_T_PACKET
)/*best case*/
1591 lat
= DR_BEST_T_READ_WRITE_ODEV
;
1595 else/*in between case*/
1597 lat
= DR_T_CAC
+DR_T_PACKET
-corrected_overlap
;
1599 partial_overlapping
++;
1602 else /* same device */
1604 if(corrected_overlap
>= DR_T_OWR
)/*best case*/
1606 lat
= DR_BEST_T_READ_WRITE_OBANK
;
1610 else/*in between case*/
1612 lat
= DR_T_CAC
+DR_T_PACKET
-corrected_overlap
;
1614 partial_overlapping
++;
1618 else/*in between case, no overlap*/
1620 lat
= DR_T_CAC
+DR_T_PACKET
;
1623 other_bank_read_access_hit
++;
1624 obr_after_write_hit
++;
1627 else/*row is not active or bank is precharged/not active*/
1629 if (active_row
[current_bank
] != DR_NUM_ROWS
)/*row is not active,but bank is active*/
1631 if (corrected_overlap
> 0 )/*overlapping*/
1633 if (last_dev
!= current_device
)
1635 if(corrected_overlap
>= (DR_T_RP
+DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
))/*best case*/
1637 lat
= DR_BEST_T_READ_WRITE_ODEV
;
1641 else/*in between case*/
1643 lat
= DR_T_RP
+DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
-corrected_overlap
;
1645 partial_overlapping
++;
1648 else /* same device */
1650 if(corrected_overlap
>= (DR_T_RP
+DR_T_RCD
+DR_T_OWR
))/*best case*/
1652 lat
= DR_BEST_T_READ_WRITE_OBANK
;
1656 else/*in between case*/
1658 lat
= DR_T_RP
+DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
-corrected_overlap
;
1660 partial_overlapping
++;
1666 lat
= DR_T_RP
+DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
;
1670 else/*current_row == DR_NUM_ROWS:precharged or inactive*/
1672 if(precharge
== 0)/*no adjacent bank is active*/
1674 if (corrected_overlap
> 0 )/*overlapping*/
1676 if(last_dev
!= current_device
)
1678 if(corrected_overlap
>= (DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
))/*best case*/
1680 lat
= DR_BEST_T_READ_WRITE_ODEV
;
1684 else/*in between case*/
1686 lat
= DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
-corrected_overlap
;
1688 partial_overlapping
++;
1691 else /* same device */
1693 if(corrected_overlap
>= (DR_T_RCD
+DR_T_OWR
))/*best case*/
1695 lat
= DR_BEST_T_READ_WRITE_OBANK
;
1699 else/*in between case*/
1701 lat
= DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
-corrected_overlap
;
1703 partial_overlapping
++;
1709 lat
= DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
;
1713 else/*one or two adjacent banks are active*/
1715 if (precharge
== 1)/*an adjacent bank (!=last_bank) needs to be precharged*/
1717 if (corrected_overlap
> 0 )/*overlapping*/
1719 if(last_dev
!= current_device
)
1721 if(corrected_overlap
>= (DR_T_RP
+DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
))/*best case*/
1723 lat
= DR_BEST_T_READ_WRITE_ODEV
;
1727 else/*in between case*/
1729 lat
= (DR_T_RP
+DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
)-corrected_overlap
;
1731 partial_overlapping
++;
1734 else /* same device */
1736 if(corrected_overlap
>= (DR_T_RP
+DR_T_RCD
+DR_T_OWR
))/*best case*/
1738 lat
= DR_BEST_T_READ_WRITE_OBANK
;
1742 else/*in between case*/
1744 lat
= (DR_T_RP
+DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
)-corrected_overlap
;
1746 partial_overlapping
++;
1752 lat
= (DR_T_RP
+DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
);
1756 else /*precharge ==2: two rows have to be precharged*/
1758 if (adjacent
== 1) /* the banks are adjacent */
1760 if (corrected_overlap
> 0 )/*overlapping*/
1762 if(corrected_overlap
>= DR_T_OWR
+ DR_T_PP
)/*best case*/
1764 lat
= DR_T_READ_WRITE_OBANK
-DR_T_OWR
- DR_T_PP
;
1768 else/*in between case*/
1770 lat
= DR_T_READ_WRITE_OBANK
-corrected_overlap
;
1772 partial_overlapping
++;
1777 lat
= DR_T_READ_WRITE_OBANK
;
1781 else/*adjacent == 0: two not adjacent banks need to be precharged*/
1783 if (corrected_overlap
> 0 )/*overlapping*/
1785 if (last_dev
!= current_device
)
1787 if(corrected_overlap
>= (DR_T_PP
+DR_T_RP
+DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
))/*best case*/
1789 lat
= DR_BEST_T_READ_WRITE_ODEV
;
1793 else/*in between case*/
1795 lat
= DR_T_READ_WRITE_OBANK
-corrected_overlap
;
1797 partial_overlapping
++;
1800 else /* same device */
1802 if(corrected_overlap
>= (DR_T_PP
+DR_T_RP
+DR_T_RCD
+DR_T_OWR
))/*best case*/
1804 lat
= DR_BEST_T_READ_WRITE_OBANK
;
1808 else/*in between case*/
1810 lat
= DR_T_READ_WRITE_OBANK
-corrected_overlap
;
1812 partial_overlapping
++;
1818 lat
= DR_T_READ_WRITE_OBANK
;
1825 other_bank_read_access_miss
[0]++;
1826 obr_after_write_miss
++;
1831 if (current_row
== active_row
[current_bank
])/*row is still active*/
1833 if (corrected_overlap
> 0 )/*overlapping*/
1835 if(corrected_overlap
>= DR_T_CWD
+DR_T_PACKET
)/*best case*/
1837 lat
= DR_BEST_T_WRITE_READ_OBANK
;
1841 else/*in between case*/
1843 lat
= DR_T_CWD
+DR_T_PACKET
-corrected_overlap
;
1845 partial_overlapping
++;
1848 else/*in between case*/
1850 lat
= DR_T_CWD
+DR_T_PACKET
;
1853 other_bank_write_access_hit
++;
1854 obw_after_read_hit
++;
1856 else/*row is not active or bank is precharged/not active*/
1858 if (active_row
[current_bank
] != DR_NUM_ROWS
)/*row is not active,but bank is active*/
1860 if (corrected_overlap
> 0 )/*overlapping*/
1862 if(corrected_overlap
>= (DR_T_RP
+DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
))/*best case*/
1864 lat
= DR_BEST_T_WRITE_READ_OBANK
;
1868 else/*in between case*/
1870 lat
= DR_T_RP
+DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
-corrected_overlap
;
1872 partial_overlapping
++;
1877 lat
= DR_T_RP
+DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
;
1881 else/*current_row == DR_NUM_ROWS:precharged or inactive*/
1883 if(precharge
== 0)/*no adjacent bank is active*/
1885 if (corrected_overlap
> 0 )/*overlapping*/
1887 if(corrected_overlap
>= (DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
))/*best case*/
1889 lat
= DR_BEST_T_WRITE_READ_OBANK
;
1893 else/*in between case*/
1895 lat
= DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
-corrected_overlap
;
1897 partial_overlapping
++;
1902 lat
= DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
;
1906 else/*one or two adjacent banks are active*/
1908 if (precharge
== 1)/*an adjacent bank (!=last_bank) needs to be precharged first*/
1910 if (corrected_overlap
> 0 )/*overlapping*/
1912 if(corrected_overlap
>= (DR_T_RP
+DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
))/*best case*/
1914 lat
= DR_BEST_T_WRITE_READ_OBANK
;
1918 else/*in between case*/
1920 lat
= (DR_T_RP
+DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
)-corrected_overlap
;
1922 partial_overlapping
++;
1927 lat
= (DR_T_RP
+DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
);
1931 else /*precharge ==2: two rows have to be precharged*/
1933 if (adjacent
== 1)/*these banks are adjacent*/
1935 if (corrected_overlap
> 0 )/*overlapping*/
1937 if(corrected_overlap
>= DR_T_PP
-DR_T_RDP
+2*DR_T_PACKET
+DR_T_CAC
)/*best case*/
1939 lat
= DR_T_WRITE_READ_OBANK
-(DR_T_PP
-DR_T_RDP
+2*DR_T_PACKET
+DR_T_CAC
);
1943 else/*in between case*/
1945 lat
= DR_T_WRITE_READ_OBANK
-corrected_overlap
;
1947 partial_overlapping
++;
1952 lat
= DR_T_WRITE_READ_OBANK
;
1956 else/*adjacent == 0: two not adjacent banks need to be precharged*/
1958 if (corrected_overlap
> 0 )/*overlapping*/
1960 if(corrected_overlap
>= DR_T_WRITE_READ_OBANK
)/*best case*/
1962 lat
= DR_BEST_T_WRITE_READ_OBANK
;
1966 else/*in between case*/
1968 lat
= DR_T_WRITE_READ_OBANK
-corrected_overlap
;
1970 partial_overlapping
++;
1975 lat
= DR_T_WRITE_READ_OBANK
;
1982 other_bank_write_access_miss
[0]++;
1983 obw_after_read_miss
++;
1988 /*fprintf(stderr,"%4d %4d ",lat,active_row[current_bank]);debugging*/
1990 lat
+= chunks
* DR_T_PACKET
; /*every 128 bit need DR_NUM_CYCLES*/
1992 /*fprintf(stderr,"%4d ",lat);debugging*/
1994 if (cpu_ratio
< 1.0)
1996 lat
= (lat
+((int)(1/cpu_ratio
)-1))/(int)(1/cpu_ratio
);
2000 temp
= (int)(lat
*cpu_ratio
);
2001 lat
= (lat
*cpu_ratio
== temp
)?temp
:(temp
+1); /*round up*/
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
;
2010 /*fprintf(stderr,"%4d \n",lat);debugging*/
2012 if (overlap
<= 0) /*memory interface is not busy*/
2014 if (memctrlpipe_enable
== true)
2016 busy_until
[current_bank
] =curTick
+lat
;
2020 if (busy_until
[current_bank
] >= curTick
)
2022 busy_until
[current_bank
] +=lat
;
2023 lat
=busy_until
[current_bank
] - curTick
;
2025 else busy_until
[current_bank
] = curTick
+lat
;
2028 else/*the memory request will be satisfied temp cycles after curTick*/
2030 busy_until
[current_bank
] +=lat
;
2031 command_overlapping
++;
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]++;
2041 /******************************************************************/
2043 else if ((mem_type
== "SDRAM") && (mem_actpolicy
== "closed") && (memctrlpipe_enable
== true))
2044 /* SDRAM closed-page with overlap, 2/00 MG */
2046 if ((memctrladdr_type
!= "interleaved"))/* i.e. mc_type is linear*/
2048 // current_bank=physic_address/SD_BANK_SIZE;
2049 current_bank
=physic_address
/bank_size
;
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.
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
;
2063 if (mem_access_details
== true)
2065 //fprintf(mem_accessfd," %09u %3d\n",physic_address,current_bank);
2069 if (mem_access_output
!=NULL
)
2071 //fprintf(mem_accessfd,"\n");
2076 overlap
=(int)(busy_until
[current_bank
] - curTick
);
2078 if (current_bank
== last_bank
)/*same bank*/
2080 if ((lastCmdIsRead
== cmdIsRead
) && (cmdIsRead
))/* RAR */
2082 lat
= act_lat
+ cas_lat
;
2084 else if ((lastCmdIsRead
== cmdIsRead
) && (!cmdIsRead
)) /* WAW */
2088 else if ((lastCmdIsRead
!= cmdIsRead
) && (cmdIsRead
)) /* RAW */
2090 lat
= act_lat
+ cas_lat
;
2097 else /* other bank */
2099 if (cpu_ratio
< 1.0)
2101 corrected_overlap
= overlap
*((int)(1/cpu_ratio
)); /* floor */
2105 corrected_overlap
= (int) (overlap
/cpu_ratio
);
2108 if ((lastCmdIsRead
== cmdIsRead
) && (cmdIsRead
))/* RAR */
2110 if (corrected_overlap
> act_lat
+ cas_lat
)
2116 else if (corrected_overlap
> 0)
2118 lat
= act_lat
+ cas_lat
- corrected_overlap
;
2120 partial_overlapping
++;
2124 lat
= act_lat
+ cas_lat
;
2128 else if ((lastCmdIsRead
== cmdIsRead
) && (!cmdIsRead
)) /* WAW */
2130 if (corrected_overlap
> act_lat
+ pre_lat
+ (dpl_lat
-1))
2132 lat
= - pre_lat
- dpl_lat
+1;
2136 else if (corrected_overlap
> 0)
2138 lat
= act_lat
- corrected_overlap
;
2140 partial_overlapping
++;
2148 else if ((lastCmdIsRead
!= cmdIsRead
) && (cmdIsRead
)) /* RAW */
2150 if (corrected_overlap
> cas_lat
+ pre_lat
+ dpl_lat
- 1 )
2152 lat
= act_lat
- (pre_lat
+ dpl_lat
- 1);
2154 partial_overlapping
++;
2156 else if (corrected_overlap
> 0)
2158 lat
= act_lat
+ cas_lat
- corrected_overlap
;
2160 partial_overlapping
++;
2164 lat
= act_lat
+ cas_lat
;
2170 if (corrected_overlap
> act_lat
- (dpl_lat
-1))
2174 partial_overlapping
++;
2176 else if (corrected_overlap
> 0)
2178 lat
= act_lat
- corrected_overlap
;
2180 partial_overlapping
++;
2189 lastCmdIsRead
= cmdIsRead
;
2190 last_bank
=current_bank
;
2191 last_row
= current_row
;
2195 if (cpu_ratio
< 1.0)
2197 lat
= (lat
+((int)(1/cpu_ratio
)-1))/(int)(1/cpu_ratio
);
2201 temp
= (int)(lat
*cpu_ratio
);
2202 lat
= (lat
*cpu_ratio
== temp
)?temp
:(temp
+1); /*round up*/
2205 /*fprintf(stderr,"%4d \n",lat); debugging */
2207 if (overlap
<= 0) /*memory interface is not busy*/
2209 busy_until
[current_bank
] = curTick
+lat
;
2211 else /*the memory request will be satisfied temp cycles after curTick*/
2213 busy_until
[current_bank
] +=lat
;
2214 command_overlapping
++;
2215 total_arb_latency
+= overlap
;
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);
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]++;
2233 /******************************************************************/
2235 else if ((mem_type
== "DRDRAM") && (mem_actpolicy
== "closed") && (memctrlpipe_enable
== true))
2236 /* DRDRAM closed-page with overlap*/
2239 if ((memctrladdr_type
!= "interleaved"))/*i.e. mc_type is linear*/
2241 current_bank
=physic_address
/DR_BANK_SIZE
;
2242 current_device
=current_bank
/(DR_NUM_BANKS
/DR_NUM_DEVS
);
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.
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
);
2259 if (mem_access_details
== true)
2261 //fprintf(mem_accessfd," %09u %3d \n",physic_address,current_bank);
2265 if (mem_access_output
!=NULL
)
2267 //fprintf(mem_accessfd,"\n");
2272 overlap
=(int)(busy_until
[current_bank
] - curTick
);
2274 if (cpu_ratio
< 1.0)
2276 corrected_overlap
= overlap
*((int)(1/cpu_ratio
)); /* floor */
2280 corrected_overlap
= (int) (overlap
/cpu_ratio
);
2283 if (current_bank
== last_bank
)/*same bank*/
2285 if ((lastCmdIsRead
== cmdIsRead
) && (cmdIsRead
))/* RAR */
2287 lat
= DR_T_RCD
+ DR_T_CAC
+ DR_T_PACKET
;
2290 else if ((lastCmdIsRead
== cmdIsRead
) && (!cmdIsRead
)) /* WAW */
2292 lat
= DR_T_RCD
+ DR_T_CWD
+ DR_T_PACKET
;
2295 else if ((lastCmdIsRead
!= cmdIsRead
) && (cmdIsRead
)) /* RAW */
2297 lat
= DR_T_RCD
+ DR_T_CAC
+ DR_T_PACKET
;
2302 lat
= DR_T_RCD
+ DR_T_CWD
+ DR_T_PACKET
;
2306 else /* other bank */
2308 if ((lastCmdIsRead
== cmdIsRead
) && (cmdIsRead
))/* RAR */
2310 if (corrected_overlap
> DR_T_RAS
+ DR_T_RP
- 2 * DR_T_PACKET
)
2312 lat
= - DR_T_RAS
+ DR_T_RCD
+ DR_T_PACKET
+ DR_T_CAC
;
2316 else if (corrected_overlap
> 0)
2318 lat
= DR_T_RCD
+ DR_T_CAC
+ DR_T_PACKET
- corrected_overlap
;
2320 partial_overlapping
++;
2324 lat
= DR_T_RCD
+ DR_T_CAC
+ DR_T_PACKET
;
2328 else if ((lastCmdIsRead
== cmdIsRead
) && (!cmdIsRead
)) /* WAW */
2330 if (corrected_overlap
> DR_T_RCD
+ DR_T_RTR
+ DR_T_RP
)
2332 lat
= - DR_T_CWD
- 2 * DR_T_PACKET
+ DR_T_RTR
;
2336 else if (corrected_overlap
> 0)
2338 lat
= DR_T_RCD
+ DR_T_CWD
+ DR_T_PACKET
- corrected_overlap
;
2340 partial_overlapping
++;
2344 lat
= DR_T_RCD
+ DR_T_CWD
+ DR_T_PACKET
;
2348 else if ((lastCmdIsRead
!= cmdIsRead
) && (cmdIsRead
)) /* RAW */
2350 if (current_device
== last_dev
) /* same device */
2352 if (corrected_overlap
> DR_T_RCD
+ DR_T_RP
)
2354 lat
= DR_T_PACKET
+ DR_T_CAC
- DR_T_RP
;
2356 partial_overlapping
++;
2358 else if (corrected_overlap
> 0)
2360 lat
= DR_T_RCD
+ DR_T_CAC
+ DR_T_PACKET
- corrected_overlap
;
2362 partial_overlapping
++;
2366 lat
= DR_T_RCD
+ DR_T_CAC
+ DR_T_PACKET
;
2370 else /* other device */
2372 if (corrected_overlap
> DR_T_RCD
+ DR_T_RP
+ 2 * DR_T_PACKET
)
2374 lat
= - DR_T_PACKET
+ DR_T_CAC
- DR_T_RP
;
2376 partial_overlapping
++;
2378 else if (corrected_overlap
> 0)
2380 lat
= DR_T_RCD
+ DR_T_CAC
+ DR_T_PACKET
- corrected_overlap
;
2382 partial_overlapping
++;
2386 lat
= DR_T_RCD
+ DR_T_CAC
+ DR_T_PACKET
;
2393 if (corrected_overlap
> DR_T_RAS
+ DR_T_RP
- 2 * DR_T_PACKET
- (DR_T_CAC
- DR_T_CWD
))
2395 lat
= - DR_T_RAS
+ DR_T_RCD
+ DR_T_PACKET
+ DR_T_CAC
;
2399 else if (corrected_overlap
> 0)
2401 lat
= DR_T_RCD
+ DR_T_CWD
+ DR_T_PACKET
- corrected_overlap
;
2403 partial_overlapping
++;
2407 lat
= DR_T_RCD
+ DR_T_CWD
+ DR_T_PACKET
;
2413 lat
+= chunks
* DR_T_PACKET
; /*every 128 bit need DR_NUM_CYCLES*/
2415 /*fprintf(stderr,"%4d ",lat);debugging*/
2417 if (cpu_ratio
< 1.0)
2419 lat
= (lat
+((int)(1/cpu_ratio
)-1))/(int)(1/cpu_ratio
);
2423 temp
= (int)(lat
*cpu_ratio
);
2424 lat
= (lat
*cpu_ratio
== temp
)?temp
:(temp
+1); /*round up*/
2427 lastCmdIsRead
=cmdIsRead
;
2428 last_bank
=current_bank
;
2429 last_dev
= current_device
;
2431 /*fprintf(stderr,"%4d \n",lat);debugging*/
2433 if (overlap
<= 0) /*memory interface is not busy*/
2435 busy_until
[current_bank
] = curTick
+lat
;
2437 else/*the memory request will be satisfied temp cycles after curTick*/
2439 busy_until
[current_bank
] +=lat
;
2440 command_overlapping
++;
2444 /*fprintf(stderr,"%10.0f %10.0f %4d %4d \n",(double)busy_until, (double)curTick, overlap, lat);*/
2448 if (cpu_ratio
< 1.0)
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 */
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 */
2457 else /* !cmdIsRead */
2459 if (cpu_ratio
< 1.0)
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 */
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 */
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]++;
2475 /******************************************************************/
2477 else if ((mem_type
== "SDRAM") && (mem_actpolicy
== "closed") && (memctrlpipe_enable
== false))
2478 /* SDRAM closed-page without overlap, 7/99 MG */
2480 if (mem_access_output
!= NULL
)
2482 //fprintf(mem_accessfd,"\n");
2488 lat
= act_lat
+ cas_lat
;
2490 else /* !cmdIsRead */
2497 overlap
=(int)(busy_until
[current_bank
] - curTick
);
2498 lastCmdIsRead
=cmdIsRead
;
2500 if (cpu_ratio
< 1.0)
2502 lat
= (lat
+((int)(1/cpu_ratio
)-1))/(int)(1/cpu_ratio
);
2506 temp
= (int)(lat
*cpu_ratio
);
2507 lat
= (lat
*cpu_ratio
== temp
)?temp
:(temp
+1); /*round up*/
2510 if (overlap
<= 0) /*memory interface is not busy*/
2512 busy_until
[current_bank
] = curTick
+lat
;
2514 else/*the memory request will be satisfied temp cycles after curTick*/
2516 busy_until
[current_bank
] +=lat
;
2517 command_overlapping
++;
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);
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]++;
2532 /******************************************************************/
2534 else if ((mem_type
== "DRDRAM") && (mem_actpolicy
== "closed") && (memctrlpipe_enable
== false))
2535 /* DRDRAM closed-page without overlap */
2539 lat
= DR_T_RCD
+ DR_T_CAC
+ DR_T_PACKET
; /* DR_T_RP + */
2541 else /* !cmdIsRead */
2543 lat
= DR_T_RCD
+ DR_T_CWD
+ DR_T_PACKET
; /* DR_T_RP + */
2546 overlap
=(int)(busy_until
[current_bank
] - curTick
);
2547 lat
+= chunks
* DR_T_PACKET
; /*every 128 bit need DR_NUM_CYCLES*/
2549 if (cpu_ratio
< 1.0)
2551 lat
= (lat
+((int)(1/cpu_ratio
)-1))/(int)(1/cpu_ratio
);
2555 temp
= (int)(lat
*cpu_ratio
);
2556 lat
= (lat
*cpu_ratio
== temp
)?temp
:(temp
+1); /*round up*/
2559 lastCmdIsRead
=cmdIsRead
;
2561 if (overlap
<= 0) /*memory interface is not busy*/
2563 busy_until
[current_bank
] = curTick
+lat
;
2565 else/*the memory request will be satisfied temp cycles after curTick*/
2567 busy_until
[current_bank
] += lat
;
2568 command_overlapping
++;
2574 if (cpu_ratio
< 1.0)
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 */
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 */
2583 else /* !cmdIsRead */
2585 if (cpu_ratio
< 1.0)
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 */
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 */
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]++;
2600 /******************************************************************/
2604 if (mem_access_output
!= NULL
)
2606 //fprintf(mem_accessfd,"\n");
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)));
2618 /*end added by ar, MG*/
2620 /*begin added by ar, MG*/
2622 /* ================ helper functions ========================= */
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 */
2631 temp
=bank
%DR_BANK_SAMP
;
2633 if (temp
== 0) /*bank 0, 16,32 ....*/
2635 if (active_row
[bank
+1]!=DR_NUM_ROWS
)
2638 active_row
[bank
+1]=DR_NUM_ROWS
;
2643 if (temp
==DR_BANK_SAMP
-1)/*banks 15,31 ...*/
2645 if (active_row
[bank
-1]!=DR_NUM_ROWS
)
2648 active_row
[bank
-1]=DR_NUM_ROWS
;
2653 if (active_row
[bank
-1]!=DR_NUM_ROWS
)
2656 active_row
[bank
-1]=DR_NUM_ROWS
;
2658 if (active_row
[bank
+1]!=DR_NUM_ROWS
)
2661 active_row
[bank
+1]=DR_NUM_ROWS
;
2669 DRAMMemoryParams::create()
2671 return new DRAMMemory(this);