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.
103 #include "mem/dram.hh"
104 #include "sim/builder.hh"
108 extern int maxThreadsPerCPU
;
110 /* SDRAM system: PC100/PC133 2-2-2 DIMM timing according to
111 PC SDRAM Specification, Rev. 1.7, Intel Corp, Nov. 1999.
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 */
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 */
172 #define MIN(a,b) ((a<b) ? a : b)
173 #define SD_ROW_SIZE 0x1000 /* size of a row : 4 Kbyte */
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)
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;
205 busy_until
= new Tick
[num_banks
];
206 memset(busy_until
,0,sizeof(Tick
)*num_banks
); /* initiliaze */
211 DRAMMemory::regStats()
213 using namespace Stats
;
216 .init(maxThreadsPerCPU
)
217 .name(name() + ".accesses")
218 .desc("total number of accesses")
223 .init(maxThreadsPerCPU
)
224 .name(name() + ".bytes_requested")
225 .desc("total number of bytes requested")
230 .init(maxThreadsPerCPU
)
231 .name(name() + ".bytes_sent")
232 .desc("total number of bytes sent")
237 .init(maxThreadsPerCPU
)
238 .name(name() + ".compressed_responses")
239 .desc("total number of accesses that are compressed")
243 // stats for power modelling
246 .name(name() + ".cycles_nCKE")
247 .desc("cycles when CKE is low")
251 cycles_all_precharge_CKE
253 .name(name() + ".cycles_all_precharge_CKE")
254 .desc("cycles when all banks precharged")
258 cycles_all_precharge_nCKE
260 .name(name() + ".cycles_all_precharge_nCKE")
261 .desc("cycles when all banks precharged and CKE is low")
265 cycles_bank_active_nCKE
267 .name(name() + ".cycles_bank_active_nCKE")
268 .desc("cycles when banks active and CKE low")
272 // we derive this from other stats later
273 // so DR TODO for now this counter is unused
276 .name(name() + ".cycles_avg_ACT")
277 .desc("avg cycles between ACT commands")
283 .name(name() + ".cycles_read_out")
284 .desc("cycles outputting read data")
290 .name(name() + ".cycles_write_in")
291 .desc("cycles inputting write data")
295 cycles_between_misses
297 .name(name() + ".cycles_between_misses")
298 .desc("cycles between open page misses")
302 other_bank_read_access_miss
304 .name(name() + ".other_bank_read_access_miss")
305 .desc("read miss count")
309 other_bank_write_access_miss
311 .name(name() + ".other_bank_write_access_miss")
312 .desc("write miss count")
316 // DR TODO for now, only output stats which are involved in power equations
318 .name(name() + ".total_latency")
319 .desc("total DRAM latency")
323 .name(name() + ".total_arb_latency")
324 .desc("total arbitration latency")
328 .name(name() + ".avg_latency")
329 .desc("average DRAM latency")
333 .name(name() + ".avg_arb_latency")
334 .desc("average arbitration DRAM latency")
338 .init(num_banks
,num_cpus
)
339 .name(name() + "[cpu][bank]")
340 .desc("DRAM bank access profile")
344 .name(name() + ".total_icache_req")
345 .desc("total number of requests from icache")
348 avg_latency
= total_latency
/ accesses
;
349 avg_arb_latency
= total_arb_latency
/ accesses
;
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
359 static char *mem_access_output
=NULL
;
360 /* latency of access [CPU cycles]*/
362 DRAMMemory::calculateLatency(Packet
*pkt
)
365 bool cmdIsRead
= pkt
->isRead();
367 int lat
=0, temp
=0, current_bank
=0;
368 int current_row
=0, current_device
=0;
370 int was_miss
= 0; // determines if there was an active row miss this access
372 //md_addr_t physic_address; /* linear memory address to be accessed */
373 Addr physic_address
; /* linear memory address to be accessed */
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*/
380 int chunks
= (pkt
->getSize() + (bus_width
- 1)) / bus_width
; // burst length
382 physic_address
= pkt
->getAddr();
384 ///////////////////////////////////////////////////////////////////////////
385 // DR added more stats for power modelling
387 // for DRAM closed-page, automatic precharge after read or write,
388 // i.e. whenever idle
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 */
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;
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;
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
;
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
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;
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
);
449 cycles_all_precharge_CKE
[0] += time_since_last_access
;
451 } else { // some bank is active
453 cycles_bank_active_nCKE
[0] += MIN(curTick
-busy_until
[current_bank
], time_since_last_access
);
460 cycles_read_out
[0] += chunks
;
462 cycles_write_in
[0] += chunks
;
466 time_last_access
= curTick
;
467 ////////////////////////////////////////////////////////////////////////////
469 if ((mem_type
== "SDRAM") && (mem_actpolicy
== "open"))
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 */
485 if ((memctrladdr_type
!= "interleaved"))/* i.e. mc_type is linear */
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
;
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.
499 num_blocks
= physic_address
/SD_ROW_SIZE
; /* row number */
500 current_bank
=num_blocks
%num_banks
;
501 current_row
=num_blocks
/num_banks
;
504 if (mem_access_details
== true)
507 //fprintf(mem_accessfd," %09u %4d %3d\n",physic_address,current_row,current_bank);
511 if (mem_access_output
!=0)
513 //fprintf(mem_accessfd,"\n");
518 if (memctrlpipe_enable
== true)
520 overlap
=(int)(busy_until
[current_bank
] - curTick
);
526 corrected_overlap
= overlap
*((int)(1/cpu_ratio
)); /* floor */
530 corrected_overlap
= (int) (overlap
/cpu_ratio
);
533 /*fprintf(stderr,"%10.0f %10.0f %4d %4d ",(double)busy_until, (double)curTick, overlap, corrected_overlap); debugging*/
535 if (cmdIsRead
== lastCmdIsRead
)/*same command*/
537 if (current_bank
== last_bank
)/*same bank*/
539 if (current_row
== last_row
)/*same row*/
544 if (corrected_overlap
> 0)/*overlapping*/
547 if (corrected_overlap
>= cas_lat
)
549 lat
=SD_BEST_T_READ_READ_SROW
;
554 else/*in between case*/
556 lat
= cas_lat
-corrected_overlap
;
559 partial_overlapping
++;
565 lat
= SD_T_READ_READ_SROW
;
569 same_row_read_access
++;
574 lat
= SD_T_WRITE_WRITE_SROW
;
576 same_row_write_access
++;
581 else /*other row in same bank*/
586 if (corrected_overlap
> 0)/*overlapping*/
588 if (corrected_overlap
>= pre_lat
)/*best case*/
590 lat
= SD_BEST_T_READ_READ_SBANK
;
594 else/*in between case*/
596 lat
= SD_T_READ_READ_SBANK
-corrected_overlap
;
598 partial_overlapping
++;
603 lat
= SD_T_READ_READ_SBANK
;
606 same_bank_read_access
++;
611 lat
= SD_T_WRITE_WRITE_SBANK
;
612 same_bank_write_access
++;
623 if (current_row
== active_row
[current_bank
])/*row is still active*/
625 if (corrected_overlap
> 0 )/*overlapping*/
627 if(corrected_overlap
>= pre_lat
)/*best case*/
629 lat
= SD_BEST_T_READ_READ_OBANK
;
633 else/*in between case*/
635 lat
= SD_T_READ_READ_OBANK
- corrected_overlap
;
637 partial_overlapping
++;
640 else/*in between case*/
642 lat
= SD_T_READ_READ_OBANK
;
645 other_bank_read_access_hit
++;
646 obr_after_read_hit
++;
648 else/*row is not active*/
650 if (corrected_overlap
> 0 )/*overlapping*/
652 if(corrected_overlap
>= SD_T_READ_READ_OBANK
)/*best case*/
654 lat
= SD_BEST_T_READ_READ_OBANK
;
658 else/*in between case*/
660 lat
= SD_T_READ_READ_OBANK
-corrected_overlap
;
662 partial_overlapping
++;
667 lat
= SD_T_READ_READ_OBANK
;
671 // DR keep track of time between misses
674 other_bank_read_access_miss
[0]++;
675 obr_after_read_miss
++;
680 if (current_row
== active_row
[current_bank
])/*row is still active*/
682 lat
= SD_BEST_T_WRITE_WRITE_OBANK
;
684 other_bank_write_access_hit
++;
685 obw_after_write_hit
++;
687 else/*row is not active*/
689 if (corrected_overlap
> 0 )/*overlapping*/
691 if(corrected_overlap
>=SD_T_WRITE_WRITE_OBANK
)/*best case*/
693 lat
= SD_BEST_T_WRITE_WRITE_OBANK
;
697 else/*in between case*/
699 lat
= SD_T_WRITE_WRITE_OBANK
-corrected_overlap
;
701 partial_overlapping
++;
706 lat
= SD_T_WRITE_WRITE_OBANK
;
710 // DR keep track of time between misses
713 other_bank_write_access_miss
[0]++;
714 obw_after_write_miss
++;
720 else /*lastCmdIsRead != cmdIsRead*/
722 if (current_bank
== last_bank
)/*same bank*/
724 if (current_row
== last_row
)/*same row*/
729 lat
= SD_T_READ_WRITE_SROW
;
731 same_row_read_access
++;
737 lat
= SD_T_WRITE_READ_SROW
;
739 same_row_write_access
++;
744 else /*other row in same bank*/
749 lat
= SD_T_READ_WRITE_SBANK
;
750 same_bank_read_access
++;
756 if (corrected_overlap
> 0 )/*overlapping*/
758 if (corrected_overlap
>= pre_lat
)/*best case*/
760 lat
= SD_BEST_T_WRITE_READ_SBANK
;
764 else/*in between case*/
766 lat
= SD_T_WRITE_READ_SBANK
-corrected_overlap
;
768 partial_overlapping
++;
773 lat
= SD_T_WRITE_READ_OBANK
;
776 same_bank_write_access
++;
786 if (current_row
== active_row
[current_bank
])/*row is still active*/
788 lat
= SD_BEST_T_READ_WRITE_OBANK
;
790 other_bank_read_access_hit
++;
791 obr_after_write_hit
++;
793 else/*row is not active*/
795 if (corrected_overlap
> 0 )/*overlapping*/
797 if(corrected_overlap
>= (pre_lat
+act_lat
))/*best case*/
799 lat
= SD_BEST_T_READ_WRITE_OBANK
;
803 else/*in between case*/
805 lat
= SD_T_READ_WRITE_OBANK
-corrected_overlap
;
807 partial_overlapping
++;
812 lat
= SD_T_READ_WRITE_OBANK
;
815 // DR keep track of time between misses
818 other_bank_read_access_miss
[0]++;
819 obr_after_write_miss
++;
824 if (current_row
== active_row
[current_bank
])/*row is still active*/
826 lat
= SD_BEST_T_WRITE_READ_OBANK
;
828 other_bank_write_access_hit
++;
829 obw_after_read_hit
++;
831 else/*row is not active*/
833 if (corrected_overlap
> 0 )/*overlapping*/
835 if (corrected_overlap
>= (SD_T_WRITE_READ_OBANK
-SD_BEST_T_WRITE_READ_OBANK
))/*best case*/
837 lat
= SD_BEST_T_WRITE_READ_OBANK
;
841 else/*in between case*/
843 lat
= SD_T_WRITE_READ_OBANK
-corrected_overlap
;
845 partial_overlapping
++;
850 lat
= SD_T_WRITE_READ_OBANK
;
854 // DR keep track of time between misses
857 other_bank_write_access_miss
[0]++;
858 obw_after_read_miss
++;
863 /*fprintf(stderr,"%4d %4d ",lat,active_row[current_bank]);debugging*/
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);
870 /*fprintf(stderr,"%4d ",lat);debugging*/
872 active_row
[current_bank
]=current_row
; /* open-page (hit) register */
873 lastCmdIsRead
= cmdIsRead
;
874 last_bank
= current_bank
;
875 last_row
= current_row
;
879 lat
= (lat
+((int)(1/cpu_ratio
)-1))/(int)(1/cpu_ratio
);
883 temp
= (int)(lat
*cpu_ratio
);
884 lat
= (lat
*cpu_ratio
== temp
)?temp
:(temp
+1); /*round up*/
887 /*fprintf(stderr,"%4d \n",lat);debugging*/
889 if (overlap
<= 0) /*memory interface is not busy*/
891 if (memctrlpipe_enable
== true)
893 busy_until
[current_bank
]=curTick
+lat
+
898 if (busy_until
[current_bank
] >= curTick
)
900 busy_until
[current_bank
]+=(lat
+
902 total_arb_latency
+= (busy_until
[current_bank
]
904 - timing_correction
);
905 lat
=busy_until
[current_bank
] - curTick
;
907 else busy_until
[current_bank
]=curTick
+lat
+
911 else/*the memory request will be satisfied temp cycles after curTick*/
913 busy_until
[current_bank
] +=(lat
+
915 command_overlapping
++;
917 total_arb_latency
+= overlap
;
920 // DR for power stats
922 cycles_between_misses
[0] += (busy_until
[current_bank
] - time_last_miss
);
923 time_last_miss
= busy_until
[current_bank
];
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]++;
933 /***********************************************************/
934 /******************** DRDRAM ***********************/
935 /***********************************************************/
937 else if ((mem_type
== "DRDRAM") && (mem_actpolicy
== "open"))/*DRDRAM*/ /*a closed bank has an activ_row number of DR_NUM_ROWS: highest +1*/
939 if ((memctrladdr_type
!= "interleaved"))/* i.e. mc_type is linear */
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
);
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.
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
);
962 if (abs(current_bank
-last_bank
)==1)/*access to an adjacent bank*/
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)*/
968 adjacent
=1;/*an adjacent bank is accessed*/
975 precharge
=0;/*at this moment no bank needs to be precharged*/
976 if (active_row
[current_bank
] == DR_NUM_ROWS
)/*bank is precharged*/
978 if (prechargeBanksAround(current_bank
)> 0)/*a bank next to the current is activated*/
980 if ((adjacent
==1)&&(precharge
==1))
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*/
990 if (mem_access_details
== true)
992 //fprintf(mem_accessfd," %09u %4d %3d %15d\n",physic_address,current_row,current_bank,(int)adjacent_access);
996 if (mem_access_output
!=NULL
)
998 //fprintf(mem_accessfd,"\n");
1003 if (memctrlpipe_enable
== true)
1005 overlap
=(int)(busy_until
[current_bank
] - curTick
);
1009 if (cpu_ratio
< 1.0)
1011 corrected_overlap
= overlap
*((int)(1/cpu_ratio
)); /* floor */
1015 corrected_overlap
= (int) (overlap
/cpu_ratio
);
1018 /*fprintf(stderr,"%10.0f %10.0f %6d %6d %2d %2d ",(double)busy_until, (double)curTick, overlap, corrected_overlap,precharge,adjacent);debugging*/
1020 if (cmdIsRead
== lastCmdIsRead
)/*same command*/
1022 if (current_bank
== last_bank
)/*same bank*/
1024 if (current_row
== last_row
)/*same row*/
1028 if (corrected_overlap
> 0)/*overlapping*/
1031 if (corrected_overlap
>= DR_T_READ_READ_SROW
)
1033 lat
=DR_BEST_T_READ_READ_SROW
;
1038 else/*in between case*/
1040 lat
= DR_T_READ_READ_SROW
-corrected_overlap
;
1043 partial_overlapping
++;
1049 lat
= DR_T_READ_READ_SROW
;
1053 same_row_read_access
++;
1056 else/*write, always retire the previous data*/
1058 if (corrected_overlap
> 0)/*overlapping*/
1061 if (corrected_overlap
>= DR_T_OWR
)
1063 lat
=DR_BEST_T_WRITE_WRITE_SROW
;
1068 else/*in between case*/
1070 lat
= DR_T_WRITE_WRITE_SROW
-corrected_overlap
;
1073 partial_overlapping
++;
1079 lat
= DR_T_WRITE_WRITE_SROW
;
1083 same_row_write_access
++;
1087 else /*other row in same bank*/
1091 if (corrected_overlap
> 0)/*overlapping*/
1093 if (corrected_overlap
>= DR_T_HELP
)/*best case*/
1095 lat
= DR_BEST_T_READ_READ_SBANK
;
1099 else/*in between case*/
1101 lat
= DR_T_READ_READ_SBANK
-corrected_overlap
;
1103 partial_overlapping
++;
1108 lat
= DR_T_READ_READ_SBANK
;
1111 same_bank_read_access
++;
1116 if (corrected_overlap
> 0)/*overlapping*/
1118 if (corrected_overlap
>= DR_T_OWR
)/*best case*/
1120 lat
= DR_BEST_T_WRITE_WRITE_SBANK
;
1124 else/*in between case*/
1126 lat
= DR_T_WRITE_WRITE_SBANK
-corrected_overlap
;
1128 partial_overlapping
++;
1133 lat
= DR_T_WRITE_WRITE_SBANK
;
1136 same_bank_write_access
++;
1145 if (current_row
== active_row
[current_bank
])/*row is still active*/
1147 if (corrected_overlap
> 0 )/*overlapping*/
1149 if(corrected_overlap
>= (DR_T_CAC
+DR_T_PACKET
))/*best case*/
1151 lat
= DR_BEST_T_READ_READ_OBANK
;
1155 else/*in between case*/
1157 lat
= DR_T_CAC
+DR_T_PACKET
-corrected_overlap
;
1159 partial_overlapping
++;
1162 else/*in between case*/
1164 lat
= DR_T_CAC
+DR_T_PACKET
;
1167 other_bank_read_access_hit
++;
1168 obr_after_read_hit
++;
1170 else/*row is not active or bank is precharged/not active*/
1172 if (active_row
[current_bank
]!=DR_NUM_ROWS
)/*row is not active, but bank is active*/
1174 if (corrected_overlap
> 0 )/*overlapping*/
1176 if(corrected_overlap
>= (DR_T_RP
+DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
))/*best case*/
1178 lat
= DR_BEST_T_READ_READ_OBANK
;
1182 else/*in between case*/
1184 lat
= DR_T_RP
+DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
-corrected_overlap
;
1186 partial_overlapping
++;
1191 lat
= DR_T_RP
+DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
;
1195 else/*current_row == DR_NUM_ROWS:precharged or inactive*/
1197 if(precharge
== 0)/*no adjacent bank is active*/
1199 if (corrected_overlap
> 0 )/*overlapping*/
1201 if(corrected_overlap
>= (DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
))/*best case*/
1203 lat
= DR_BEST_T_READ_READ_OBANK
;
1207 else/*in between case*/
1209 lat
= DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
-corrected_overlap
;
1211 partial_overlapping
++;
1216 lat
= DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
;
1220 else/*one ore two adjacent banks are active*/
1224 if (corrected_overlap
> 0 )/*overlapping*/
1226 if(corrected_overlap
>= (DR_T_RP
+DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
))/*best case*/
1228 lat
= DR_BEST_T_READ_READ_OBANK
;
1232 else/*in between case*/
1234 lat
= (DR_T_RP
+DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
)-corrected_overlap
;
1236 partial_overlapping
++;
1241 lat
= (DR_T_RP
+DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
);
1245 else /*precharge ==2: two rows must be precharged*/
1247 if (adjacent
== 1)/*these banks are adjacent*/
1249 if (corrected_overlap
> 0 )/*overlapping*/
1251 if(corrected_overlap
>= DR_T_PP
+2*DR_T_PACKET
-DR_T_RDP
+DR_T_CAC
)/*best case*/
1253 lat
= DR_T_RDP
+DR_T_RP
+DR_T_RCD
-DR_T_PACKET
;
1257 else/*in between case*/
1259 lat
= DR_T_READ_READ_OBANK
-corrected_overlap
;
1261 partial_overlapping
++;
1266 lat
= DR_T_READ_READ_OBANK
;
1270 else/*adjacent == 0: two not adjacent banks need to be precharged*/
1272 if (corrected_overlap
> 0 )/*overlapping*/
1274 if(corrected_overlap
>= DR_T_READ_READ_OBANK
)/*best case*/
1276 lat
= DR_BEST_T_READ_READ_OBANK
;
1280 else/*in between case*/
1282 lat
= DR_T_READ_READ_OBANK
-corrected_overlap
;
1284 partial_overlapping
++;
1289 lat
= DR_T_READ_READ_OBANK
;
1296 other_bank_read_access_miss
[0]++;
1297 obr_after_read_miss
++;
1302 if (current_row
== active_row
[current_bank
])/*row is still active*/
1304 if (corrected_overlap
> 0 )/*overlapping*/
1306 if(corrected_overlap
>= (DR_T_CWD
+DR_T_PACKET
))/*best case*/
1308 lat
= DR_BEST_T_WRITE_WRITE_OBANK
;
1312 else/*in between case*/
1314 lat
= DR_T_CWD
+DR_T_PACKET
-corrected_overlap
;
1316 partial_overlapping
++;
1321 lat
= DR_T_CWD
+DR_T_PACKET
;
1324 other_bank_write_access_hit
++;
1325 obw_after_write_hit
++;
1327 else/*row is not active or bank is precharged/not active*/
1329 if (active_row
[current_bank
] != DR_NUM_ROWS
)/*row is not active,but bank is active*/
1331 if (corrected_overlap
> 0 )/*overlapping*/
1333 if(corrected_overlap
>= (DR_T_RP
+DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
))/*best case*/
1335 lat
= DR_BEST_T_WRITE_WRITE_OBANK
;
1339 else/*in between case*/
1341 lat
= DR_T_RP
+DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
-corrected_overlap
;
1343 partial_overlapping
++;
1348 lat
= DR_T_RP
+DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
;
1352 else/*current_row == DR_NUM_ROWS:precharged or inactive*/
1354 if(precharge
== 0)/*no adjacent bank is active*/
1356 if (corrected_overlap
> 0 )/*overlapping*/
1358 if(corrected_overlap
>= (DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
))/*best case*/
1360 lat
= DR_BEST_T_WRITE_WRITE_OBANK
;
1364 else/*in between case*/
1366 lat
= DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
-corrected_overlap
;
1368 partial_overlapping
++;
1373 lat
= DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
;
1377 else/*one ore two adjacent banks are active*/
1379 if (precharge
== 1)/*last_bank is no adjacent*/
1381 if (corrected_overlap
> 0 )/*overlapping*/
1383 if(corrected_overlap
>= (DR_T_RP
+DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
))/*best case*/
1385 lat
= DR_BEST_T_WRITE_WRITE_OBANK
;
1389 else/*in between case*/
1391 lat
= (DR_T_RP
+DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
)-corrected_overlap
;
1393 partial_overlapping
++;
1398 lat
= (DR_T_RP
+DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
);
1402 else /*precharge ==2: two rows have to be precharged*/
1404 if (adjacent
== 1)/*these banks are adjacent*/
1406 if (corrected_overlap
> 0 )/*overlapping*/
1408 if(corrected_overlap
>= DR_T_OWR
+DR_T_PP
)/*best case*/
1410 lat
= DR_T_WRITE_WRITE_OBANK
-DR_T_OWR
-DR_T_PP
;
1414 else/*in between case*/
1416 lat
= DR_T_WRITE_WRITE_OBANK
-corrected_overlap
;
1418 partial_overlapping
++;
1423 lat
= DR_T_WRITE_WRITE_OBANK
;
1427 else/*adjacent == 0: two not adjacent banks need to be precharged*/
1429 if (corrected_overlap
> 0 )/*overlapping*/
1431 if(corrected_overlap
>= DR_T_WRITE_WRITE_OBANK
)/*best case*/
1433 lat
= DR_BEST_T_WRITE_WRITE_OBANK
;
1437 else/*in between case*/
1439 lat
= DR_T_WRITE_WRITE_OBANK
-corrected_overlap
;
1441 partial_overlapping
++;
1446 lat
= DR_T_WRITE_WRITE_OBANK
;
1453 other_bank_write_access_miss
[0]++;
1454 obw_after_write_miss
++;
1459 else /*lastCmdIsRead != cmdIsRead*/
1461 if (current_bank
== last_bank
)/*same bank*/
1463 if (current_row
== last_row
)/*same row*/
1467 if (corrected_overlap
> 0)/*overlapping*/
1470 if (corrected_overlap
>= DR_T_OWR
)
1472 lat
=DR_BEST_T_READ_WRITE_SROW
;
1477 else/*in between case*/
1479 lat
= DR_T_READ_WRITE_SROW
-corrected_overlap
;
1482 partial_overlapping
++;
1488 lat
= DR_T_READ_WRITE_SROW
;
1492 same_row_read_access
++;
1497 if (corrected_overlap
> 0)/*overlapping*/
1500 if (corrected_overlap
>= DR_T_WRITE_READ_SROW
)
1502 lat
=DR_BEST_T_WRITE_READ_SROW
;
1507 else/*in between case*/
1509 lat
= DR_T_WRITE_READ_SROW
-corrected_overlap
;
1512 partial_overlapping
++;
1518 lat
= DR_T_WRITE_READ_SROW
;
1522 same_row_write_access
++;
1526 else /*other row in same bank*/
1530 if (corrected_overlap
> 0 )/*overlapping*/
1532 if (corrected_overlap
>= DR_T_OWR
)/*best case*/
1534 lat
= DR_BEST_T_READ_WRITE_SBANK
;
1538 else/*in between case*/
1540 lat
= DR_T_READ_WRITE_SBANK
-corrected_overlap
;
1542 partial_overlapping
++;
1547 lat
= DR_T_READ_WRITE_SBANK
;
1550 same_bank_read_access
++;
1555 if (corrected_overlap
> 0 )/*overlapping*/
1557 if (corrected_overlap
>= DR_T_HELP
)/*best case*/
1559 lat
= DR_BEST_T_WRITE_READ_SBANK
;
1563 else/*in between case*/
1565 lat
= DR_T_WRITE_READ_SBANK
-corrected_overlap
;
1567 partial_overlapping
++;
1572 lat
= DR_T_WRITE_READ_SBANK
;
1575 same_bank_write_access
++;
1584 if (current_row
== active_row
[current_bank
])/*row is still active*/
1586 if (corrected_overlap
> 0 )/*overlapping*/
1588 if(last_dev
!= current_device
)
1590 if(corrected_overlap
>= DR_T_CWD
+DR_T_PACKET
)/*best case*/
1592 lat
= DR_BEST_T_READ_WRITE_ODEV
;
1596 else/*in between case*/
1598 lat
= DR_T_CAC
+DR_T_PACKET
-corrected_overlap
;
1600 partial_overlapping
++;
1603 else /* same device */
1605 if(corrected_overlap
>= DR_T_OWR
)/*best case*/
1607 lat
= DR_BEST_T_READ_WRITE_OBANK
;
1611 else/*in between case*/
1613 lat
= DR_T_CAC
+DR_T_PACKET
-corrected_overlap
;
1615 partial_overlapping
++;
1619 else/*in between case, no overlap*/
1621 lat
= DR_T_CAC
+DR_T_PACKET
;
1624 other_bank_read_access_hit
++;
1625 obr_after_write_hit
++;
1628 else/*row is not active or bank is precharged/not active*/
1630 if (active_row
[current_bank
] != DR_NUM_ROWS
)/*row is not active,but bank is active*/
1632 if (corrected_overlap
> 0 )/*overlapping*/
1634 if (last_dev
!= current_device
)
1636 if(corrected_overlap
>= (DR_T_RP
+DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
))/*best case*/
1638 lat
= DR_BEST_T_READ_WRITE_ODEV
;
1642 else/*in between case*/
1644 lat
= DR_T_RP
+DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
-corrected_overlap
;
1646 partial_overlapping
++;
1649 else /* same device */
1651 if(corrected_overlap
>= (DR_T_RP
+DR_T_RCD
+DR_T_OWR
))/*best case*/
1653 lat
= DR_BEST_T_READ_WRITE_OBANK
;
1657 else/*in between case*/
1659 lat
= DR_T_RP
+DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
-corrected_overlap
;
1661 partial_overlapping
++;
1667 lat
= DR_T_RP
+DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
;
1671 else/*current_row == DR_NUM_ROWS:precharged or inactive*/
1673 if(precharge
== 0)/*no adjacent bank is active*/
1675 if (corrected_overlap
> 0 )/*overlapping*/
1677 if(last_dev
!= current_device
)
1679 if(corrected_overlap
>= (DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
))/*best case*/
1681 lat
= DR_BEST_T_READ_WRITE_ODEV
;
1685 else/*in between case*/
1687 lat
= DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
-corrected_overlap
;
1689 partial_overlapping
++;
1692 else /* same device */
1694 if(corrected_overlap
>= (DR_T_RCD
+DR_T_OWR
))/*best case*/
1696 lat
= DR_BEST_T_READ_WRITE_OBANK
;
1700 else/*in between case*/
1702 lat
= DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
-corrected_overlap
;
1704 partial_overlapping
++;
1710 lat
= DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
;
1714 else/*one or two adjacent banks are active*/
1716 if (precharge
== 1)/*an adjacent bank (!=last_bank) needs to be precharged*/
1718 if (corrected_overlap
> 0 )/*overlapping*/
1720 if(last_dev
!= current_device
)
1722 if(corrected_overlap
>= (DR_T_RP
+DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
))/*best case*/
1724 lat
= DR_BEST_T_READ_WRITE_ODEV
;
1728 else/*in between case*/
1730 lat
= (DR_T_RP
+DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
)-corrected_overlap
;
1732 partial_overlapping
++;
1735 else /* same device */
1737 if(corrected_overlap
>= (DR_T_RP
+DR_T_RCD
+DR_T_OWR
))/*best case*/
1739 lat
= DR_BEST_T_READ_WRITE_OBANK
;
1743 else/*in between case*/
1745 lat
= (DR_T_RP
+DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
)-corrected_overlap
;
1747 partial_overlapping
++;
1753 lat
= (DR_T_RP
+DR_T_RCD
+DR_T_CAC
+DR_T_PACKET
);
1757 else /*precharge ==2: two rows have to be precharged*/
1759 if (adjacent
== 1) /* the banks are adjacent */
1761 if (corrected_overlap
> 0 )/*overlapping*/
1763 if(corrected_overlap
>= DR_T_OWR
+ DR_T_PP
)/*best case*/
1765 lat
= DR_T_READ_WRITE_OBANK
-DR_T_OWR
- DR_T_PP
;
1769 else/*in between case*/
1771 lat
= DR_T_READ_WRITE_OBANK
-corrected_overlap
;
1773 partial_overlapping
++;
1778 lat
= DR_T_READ_WRITE_OBANK
;
1782 else/*adjacent == 0: two not adjacent banks need to be precharged*/
1784 if (corrected_overlap
> 0 )/*overlapping*/
1786 if (last_dev
!= current_device
)
1788 if(corrected_overlap
>= (DR_T_PP
+DR_T_RP
+DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
))/*best case*/
1790 lat
= DR_BEST_T_READ_WRITE_ODEV
;
1794 else/*in between case*/
1796 lat
= DR_T_READ_WRITE_OBANK
-corrected_overlap
;
1798 partial_overlapping
++;
1801 else /* same device */
1803 if(corrected_overlap
>= (DR_T_PP
+DR_T_RP
+DR_T_RCD
+DR_T_OWR
))/*best case*/
1805 lat
= DR_BEST_T_READ_WRITE_OBANK
;
1809 else/*in between case*/
1811 lat
= DR_T_READ_WRITE_OBANK
-corrected_overlap
;
1813 partial_overlapping
++;
1819 lat
= DR_T_READ_WRITE_OBANK
;
1826 other_bank_read_access_miss
[0]++;
1827 obr_after_write_miss
++;
1832 if (current_row
== active_row
[current_bank
])/*row is still active*/
1834 if (corrected_overlap
> 0 )/*overlapping*/
1836 if(corrected_overlap
>= DR_T_CWD
+DR_T_PACKET
)/*best case*/
1838 lat
= DR_BEST_T_WRITE_READ_OBANK
;
1842 else/*in between case*/
1844 lat
= DR_T_CWD
+DR_T_PACKET
-corrected_overlap
;
1846 partial_overlapping
++;
1849 else/*in between case*/
1851 lat
= DR_T_CWD
+DR_T_PACKET
;
1854 other_bank_write_access_hit
++;
1855 obw_after_read_hit
++;
1857 else/*row is not active or bank is precharged/not active*/
1859 if (active_row
[current_bank
] != DR_NUM_ROWS
)/*row is not active,but bank is active*/
1861 if (corrected_overlap
> 0 )/*overlapping*/
1863 if(corrected_overlap
>= (DR_T_RP
+DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
))/*best case*/
1865 lat
= DR_BEST_T_WRITE_READ_OBANK
;
1869 else/*in between case*/
1871 lat
= DR_T_RP
+DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
-corrected_overlap
;
1873 partial_overlapping
++;
1878 lat
= DR_T_RP
+DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
;
1882 else/*current_row == DR_NUM_ROWS:precharged or inactive*/
1884 if(precharge
== 0)/*no adjacent bank is active*/
1886 if (corrected_overlap
> 0 )/*overlapping*/
1888 if(corrected_overlap
>= (DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
))/*best case*/
1890 lat
= DR_BEST_T_WRITE_READ_OBANK
;
1894 else/*in between case*/
1896 lat
= DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
-corrected_overlap
;
1898 partial_overlapping
++;
1903 lat
= DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
;
1907 else/*one or two adjacent banks are active*/
1909 if (precharge
== 1)/*an adjacent bank (!=last_bank) needs to be precharged first*/
1911 if (corrected_overlap
> 0 )/*overlapping*/
1913 if(corrected_overlap
>= (DR_T_RP
+DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
))/*best case*/
1915 lat
= DR_BEST_T_WRITE_READ_OBANK
;
1919 else/*in between case*/
1921 lat
= (DR_T_RP
+DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
)-corrected_overlap
;
1923 partial_overlapping
++;
1928 lat
= (DR_T_RP
+DR_T_RCD
+DR_T_CWD
+DR_T_PACKET
);
1932 else /*precharge ==2: two rows have to be precharged*/
1934 if (adjacent
== 1)/*these banks are adjacent*/
1936 if (corrected_overlap
> 0 )/*overlapping*/
1938 if(corrected_overlap
>= DR_T_PP
-DR_T_RDP
+2*DR_T_PACKET
+DR_T_CAC
)/*best case*/
1940 lat
= DR_T_WRITE_READ_OBANK
-(DR_T_PP
-DR_T_RDP
+2*DR_T_PACKET
+DR_T_CAC
);
1944 else/*in between case*/
1946 lat
= DR_T_WRITE_READ_OBANK
-corrected_overlap
;
1948 partial_overlapping
++;
1953 lat
= DR_T_WRITE_READ_OBANK
;
1957 else/*adjacent == 0: two not adjacent banks need to be precharged*/
1959 if (corrected_overlap
> 0 )/*overlapping*/
1961 if(corrected_overlap
>= DR_T_WRITE_READ_OBANK
)/*best case*/
1963 lat
= DR_BEST_T_WRITE_READ_OBANK
;
1967 else/*in between case*/
1969 lat
= DR_T_WRITE_READ_OBANK
-corrected_overlap
;
1971 partial_overlapping
++;
1976 lat
= DR_T_WRITE_READ_OBANK
;
1983 other_bank_write_access_miss
[0]++;
1984 obw_after_read_miss
++;
1989 /*fprintf(stderr,"%4d %4d ",lat,active_row[current_bank]);debugging*/
1991 lat
+= chunks
* DR_T_PACKET
; /*every 128 bit need DR_NUM_CYCLES*/
1993 /*fprintf(stderr,"%4d ",lat);debugging*/
1995 if (cpu_ratio
< 1.0)
1997 lat
= (lat
+((int)(1/cpu_ratio
)-1))/(int)(1/cpu_ratio
);
2001 temp
= (int)(lat
*cpu_ratio
);
2002 lat
= (lat
*cpu_ratio
== temp
)?temp
:(temp
+1); /*round up*/
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
;
2011 /*fprintf(stderr,"%4d \n",lat);debugging*/
2013 if (overlap
<= 0) /*memory interface is not busy*/
2015 if (memctrlpipe_enable
== true)
2017 busy_until
[current_bank
] =curTick
+lat
;
2021 if (busy_until
[current_bank
] >= curTick
)
2023 busy_until
[current_bank
] +=lat
;
2024 lat
=busy_until
[current_bank
] - curTick
;
2026 else busy_until
[current_bank
] = curTick
+lat
;
2029 else/*the memory request will be satisfied temp cycles after curTick*/
2031 busy_until
[current_bank
] +=lat
;
2032 command_overlapping
++;
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]++;
2042 /******************************************************************/
2044 else if ((mem_type
== "SDRAM") && (mem_actpolicy
== "closed") && (memctrlpipe_enable
== true))
2045 /* SDRAM closed-page with overlap, 2/00 MG */
2047 if ((memctrladdr_type
!= "interleaved"))/* i.e. mc_type is linear*/
2049 // current_bank=physic_address/SD_BANK_SIZE;
2050 current_bank
=physic_address
/bank_size
;
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.
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
;
2064 if (mem_access_details
== true)
2066 //fprintf(mem_accessfd," %09u %3d\n",physic_address,current_bank);
2070 if (mem_access_output
!=NULL
)
2072 //fprintf(mem_accessfd,"\n");
2077 overlap
=(int)(busy_until
[current_bank
] - curTick
);
2079 if (current_bank
== last_bank
)/*same bank*/
2081 if ((lastCmdIsRead
== cmdIsRead
) && (cmdIsRead
))/* RAR */
2083 lat
= act_lat
+ cas_lat
;
2085 else if ((lastCmdIsRead
== cmdIsRead
) && (!cmdIsRead
)) /* WAW */
2089 else if ((lastCmdIsRead
!= cmdIsRead
) && (cmdIsRead
)) /* RAW */
2091 lat
= act_lat
+ cas_lat
;
2098 else /* other bank */
2100 if (cpu_ratio
< 1.0)
2102 corrected_overlap
= overlap
*((int)(1/cpu_ratio
)); /* floor */
2106 corrected_overlap
= (int) (overlap
/cpu_ratio
);
2109 if ((lastCmdIsRead
== cmdIsRead
) && (cmdIsRead
))/* RAR */
2111 if (corrected_overlap
> act_lat
+ cas_lat
)
2117 else if (corrected_overlap
> 0)
2119 lat
= act_lat
+ cas_lat
- corrected_overlap
;
2121 partial_overlapping
++;
2125 lat
= act_lat
+ cas_lat
;
2129 else if ((lastCmdIsRead
== cmdIsRead
) && (!cmdIsRead
)) /* WAW */
2131 if (corrected_overlap
> act_lat
+ pre_lat
+ (dpl_lat
-1))
2133 lat
= - pre_lat
- dpl_lat
+1;
2137 else if (corrected_overlap
> 0)
2139 lat
= act_lat
- corrected_overlap
;
2141 partial_overlapping
++;
2149 else if ((lastCmdIsRead
!= cmdIsRead
) && (cmdIsRead
)) /* RAW */
2151 if (corrected_overlap
> cas_lat
+ pre_lat
+ dpl_lat
- 1 )
2153 lat
= act_lat
- (pre_lat
+ dpl_lat
- 1);
2155 partial_overlapping
++;
2157 else if (corrected_overlap
> 0)
2159 lat
= act_lat
+ cas_lat
- corrected_overlap
;
2161 partial_overlapping
++;
2165 lat
= act_lat
+ cas_lat
;
2171 if (corrected_overlap
> act_lat
- (dpl_lat
-1))
2175 partial_overlapping
++;
2177 else if (corrected_overlap
> 0)
2179 lat
= act_lat
- corrected_overlap
;
2181 partial_overlapping
++;
2190 lastCmdIsRead
= cmdIsRead
;
2191 last_bank
=current_bank
;
2192 last_row
= current_row
;
2196 if (cpu_ratio
< 1.0)
2198 lat
= (lat
+((int)(1/cpu_ratio
)-1))/(int)(1/cpu_ratio
);
2202 temp
= (int)(lat
*cpu_ratio
);
2203 lat
= (lat
*cpu_ratio
== temp
)?temp
:(temp
+1); /*round up*/
2206 /*fprintf(stderr,"%4d \n",lat); debugging */
2208 if (overlap
<= 0) /*memory interface is not busy*/
2210 busy_until
[current_bank
] = curTick
+lat
;
2212 else /*the memory request will be satisfied temp cycles after curTick*/
2214 busy_until
[current_bank
] +=lat
;
2215 command_overlapping
++;
2216 total_arb_latency
+= overlap
;
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);
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]++;
2234 /******************************************************************/
2236 else if ((mem_type
== "DRDRAM") && (mem_actpolicy
== "closed") && (memctrlpipe_enable
== true))
2237 /* DRDRAM closed-page with overlap*/
2240 if ((memctrladdr_type
!= "interleaved"))/*i.e. mc_type is linear*/
2242 current_bank
=physic_address
/DR_BANK_SIZE
;
2243 current_device
=current_bank
/(DR_NUM_BANKS
/DR_NUM_DEVS
);
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.
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
);
2260 if (mem_access_details
== true)
2262 //fprintf(mem_accessfd," %09u %3d \n",physic_address,current_bank);
2266 if (mem_access_output
!=NULL
)
2268 //fprintf(mem_accessfd,"\n");
2273 overlap
=(int)(busy_until
[current_bank
] - curTick
);
2275 if (cpu_ratio
< 1.0)
2277 corrected_overlap
= overlap
*((int)(1/cpu_ratio
)); /* floor */
2281 corrected_overlap
= (int) (overlap
/cpu_ratio
);
2284 if (current_bank
== last_bank
)/*same bank*/
2286 if ((lastCmdIsRead
== cmdIsRead
) && (cmdIsRead
))/* RAR */
2288 lat
= DR_T_RCD
+ DR_T_CAC
+ DR_T_PACKET
;
2291 else if ((lastCmdIsRead
== cmdIsRead
) && (!cmdIsRead
)) /* WAW */
2293 lat
= DR_T_RCD
+ DR_T_CWD
+ DR_T_PACKET
;
2296 else if ((lastCmdIsRead
!= cmdIsRead
) && (cmdIsRead
)) /* RAW */
2298 lat
= DR_T_RCD
+ DR_T_CAC
+ DR_T_PACKET
;
2303 lat
= DR_T_RCD
+ DR_T_CWD
+ DR_T_PACKET
;
2307 else /* other bank */
2309 if ((lastCmdIsRead
== cmdIsRead
) && (cmdIsRead
))/* RAR */
2311 if (corrected_overlap
> DR_T_RAS
+ DR_T_RP
- 2 * DR_T_PACKET
)
2313 lat
= - DR_T_RAS
+ DR_T_RCD
+ DR_T_PACKET
+ DR_T_CAC
;
2317 else if (corrected_overlap
> 0)
2319 lat
= DR_T_RCD
+ DR_T_CAC
+ DR_T_PACKET
- corrected_overlap
;
2321 partial_overlapping
++;
2325 lat
= DR_T_RCD
+ DR_T_CAC
+ DR_T_PACKET
;
2329 else if ((lastCmdIsRead
== cmdIsRead
) && (!cmdIsRead
)) /* WAW */
2331 if (corrected_overlap
> DR_T_RCD
+ DR_T_RTR
+ DR_T_RP
)
2333 lat
= - DR_T_CWD
- 2 * DR_T_PACKET
+ DR_T_RTR
;
2337 else if (corrected_overlap
> 0)
2339 lat
= DR_T_RCD
+ DR_T_CWD
+ DR_T_PACKET
- corrected_overlap
;
2341 partial_overlapping
++;
2345 lat
= DR_T_RCD
+ DR_T_CWD
+ DR_T_PACKET
;
2349 else if ((lastCmdIsRead
!= cmdIsRead
) && (cmdIsRead
)) /* RAW */
2351 if (current_device
== last_dev
) /* same device */
2353 if (corrected_overlap
> DR_T_RCD
+ DR_T_RP
)
2355 lat
= DR_T_PACKET
+ DR_T_CAC
- DR_T_RP
;
2357 partial_overlapping
++;
2359 else if (corrected_overlap
> 0)
2361 lat
= DR_T_RCD
+ DR_T_CAC
+ DR_T_PACKET
- corrected_overlap
;
2363 partial_overlapping
++;
2367 lat
= DR_T_RCD
+ DR_T_CAC
+ DR_T_PACKET
;
2371 else /* other device */
2373 if (corrected_overlap
> DR_T_RCD
+ DR_T_RP
+ 2 * DR_T_PACKET
)
2375 lat
= - DR_T_PACKET
+ DR_T_CAC
- DR_T_RP
;
2377 partial_overlapping
++;
2379 else if (corrected_overlap
> 0)
2381 lat
= DR_T_RCD
+ DR_T_CAC
+ DR_T_PACKET
- corrected_overlap
;
2383 partial_overlapping
++;
2387 lat
= DR_T_RCD
+ DR_T_CAC
+ DR_T_PACKET
;
2394 if (corrected_overlap
> DR_T_RAS
+ DR_T_RP
- 2 * DR_T_PACKET
- (DR_T_CAC
- DR_T_CWD
))
2396 lat
= - DR_T_RAS
+ DR_T_RCD
+ DR_T_PACKET
+ DR_T_CAC
;
2400 else if (corrected_overlap
> 0)
2402 lat
= DR_T_RCD
+ DR_T_CWD
+ DR_T_PACKET
- corrected_overlap
;
2404 partial_overlapping
++;
2408 lat
= DR_T_RCD
+ DR_T_CWD
+ DR_T_PACKET
;
2414 lat
+= chunks
* DR_T_PACKET
; /*every 128 bit need DR_NUM_CYCLES*/
2416 /*fprintf(stderr,"%4d ",lat);debugging*/
2418 if (cpu_ratio
< 1.0)
2420 lat
= (lat
+((int)(1/cpu_ratio
)-1))/(int)(1/cpu_ratio
);
2424 temp
= (int)(lat
*cpu_ratio
);
2425 lat
= (lat
*cpu_ratio
== temp
)?temp
:(temp
+1); /*round up*/
2428 lastCmdIsRead
=cmdIsRead
;
2429 last_bank
=current_bank
;
2430 last_dev
= current_device
;
2432 /*fprintf(stderr,"%4d \n",lat);debugging*/
2434 if (overlap
<= 0) /*memory interface is not busy*/
2436 busy_until
[current_bank
] = curTick
+lat
;
2438 else/*the memory request will be satisfied temp cycles after curTick*/
2440 busy_until
[current_bank
] +=lat
;
2441 command_overlapping
++;
2445 /*fprintf(stderr,"%10.0f %10.0f %4d %4d \n",(double)busy_until, (double)curTick, overlap, lat);*/
2449 if (cpu_ratio
< 1.0)
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 */
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 */
2458 else /* !cmdIsRead */
2460 if (cpu_ratio
< 1.0)
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 */
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 */
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]++;
2476 /******************************************************************/
2478 else if ((mem_type
== "SDRAM") && (mem_actpolicy
== "closed") && (memctrlpipe_enable
== false))
2479 /* SDRAM closed-page without overlap, 7/99 MG */
2481 if (mem_access_output
!= NULL
)
2483 //fprintf(mem_accessfd,"\n");
2489 lat
= act_lat
+ cas_lat
;
2491 else /* !cmdIsRead */
2498 overlap
=(int)(busy_until
[current_bank
] - curTick
);
2499 lastCmdIsRead
=cmdIsRead
;
2501 if (cpu_ratio
< 1.0)
2503 lat
= (lat
+((int)(1/cpu_ratio
)-1))/(int)(1/cpu_ratio
);
2507 temp
= (int)(lat
*cpu_ratio
);
2508 lat
= (lat
*cpu_ratio
== temp
)?temp
:(temp
+1); /*round up*/
2511 if (overlap
<= 0) /*memory interface is not busy*/
2513 busy_until
[current_bank
] = curTick
+lat
;
2515 else/*the memory request will be satisfied temp cycles after curTick*/
2517 busy_until
[current_bank
] +=lat
;
2518 command_overlapping
++;
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);
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]++;
2533 /******************************************************************/
2535 else if ((mem_type
== "DRDRAM") && (mem_actpolicy
== "closed") && (memctrlpipe_enable
== false))
2536 /* DRDRAM closed-page without overlap */
2540 lat
= DR_T_RCD
+ DR_T_CAC
+ DR_T_PACKET
; /* DR_T_RP + */
2542 else /* !cmdIsRead */
2544 lat
= DR_T_RCD
+ DR_T_CWD
+ DR_T_PACKET
; /* DR_T_RP + */
2547 overlap
=(int)(busy_until
[current_bank
] - curTick
);
2548 lat
+= chunks
* DR_T_PACKET
; /*every 128 bit need DR_NUM_CYCLES*/
2550 if (cpu_ratio
< 1.0)
2552 lat
= (lat
+((int)(1/cpu_ratio
)-1))/(int)(1/cpu_ratio
);
2556 temp
= (int)(lat
*cpu_ratio
);
2557 lat
= (lat
*cpu_ratio
== temp
)?temp
:(temp
+1); /*round up*/
2560 lastCmdIsRead
=cmdIsRead
;
2562 if (overlap
<= 0) /*memory interface is not busy*/
2564 busy_until
[current_bank
] = curTick
+lat
;
2566 else/*the memory request will be satisfied temp cycles after curTick*/
2568 busy_until
[current_bank
] += lat
;
2569 command_overlapping
++;
2575 if (cpu_ratio
< 1.0)
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 */
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 */
2584 else /* !cmdIsRead */
2586 if (cpu_ratio
< 1.0)
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 */
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 */
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]++;
2601 /******************************************************************/
2605 if (mem_access_output
!= NULL
)
2607 //fprintf(mem_accessfd,"\n");
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)));
2619 /*end added by ar, MG*/
2621 /*begin added by ar, MG*/
2623 /* ================ helper functions ========================= */
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 */
2632 temp
=bank
%DR_BANK_SAMP
;
2634 if (temp
== 0) /*bank 0, 16,32 ....*/
2636 if (active_row
[bank
+1]!=DR_NUM_ROWS
)
2639 active_row
[bank
+1]=DR_NUM_ROWS
;
2644 if (temp
==DR_BANK_SAMP
-1)/*banks 15,31 ...*/
2646 if (active_row
[bank
-1]!=DR_NUM_ROWS
)
2649 active_row
[bank
-1]=DR_NUM_ROWS
;
2654 if (active_row
[bank
-1]!=DR_NUM_ROWS
)
2657 active_row
[bank
-1]=DR_NUM_ROWS
;
2659 if (active_row
[bank
+1]!=DR_NUM_ROWS
)
2662 active_row
[bank
+1]=DR_NUM_ROWS
;
2670 #ifndef DOXYGEN_SHOULD_SKIP_THIS
2672 BEGIN_DECLARE_SIM_OBJECT_PARAMS(DRAMMemory
)
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
;
2689 Param
<int> num_banks
;
2690 Param
<int> num_cpus
;
2692 END_DECLARE_SIM_OBJECT_PARAMS(DRAMMemory
)
2694 BEGIN_INIT_SIM_OBJECT_PARAMS(DRAMMemory
)
2696 INIT_PARAM_DFLT(file
, "memory mapped file", ""),
2697 INIT_PARAM(range
, "Device Address Range"),
2698 INIT_PARAM(latency
, "Memory access latency"),
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)
2715 END_INIT_SIM_OBJECT_PARAMS(DRAMMemory
)
2717 CREATE_SIM_OBJECT(DRAMMemory
)
2719 DRAMMemory::Params
*p
= new DRAMMemory::Params
;
2720 p
->name
= getInstanceName();
2721 p
->addrRange
= range
;
2722 p
->latency
= latency
;
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
;
2739 return new DRAMMemory(p
);
2742 REGISTER_SIM_OBJECT("DRAMMemory", DRAMMemory
)
2744 #endif // DOXYGEN_SHOULD_SKIP_THIS