2 * Copyright (c) 2002-2005 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.
31 #include "cpu/o3/fu_pool.hh"
32 #include "encumbered/cpu/full/fu_pool.hh"
33 #include "sim/builder.hh"
37 ////////////////////////////////////////////////////////////////////////////
39 // A pool of function units
43 FUPool::FUIdxQueue::addFU(int fu_idx
)
45 funcUnitsIdx
.push_back(fu_idx
);
50 FUPool::FUIdxQueue::getFU()
52 int retval
= funcUnitsIdx
[idx
++];
62 fuListIterator i
= funcUnits
.begin();
63 fuListIterator end
= funcUnits
.end();
70 FUPool::FUPool(string name
, vector
<FUDesc
*> paramList
)
77 for (int i
= 0; i
< Num_OpClasses
; ++i
) {
78 maxOpLatencies
[i
] = 0;
79 maxIssueLatencies
[i
] = 0;
83 // Iterate through the list of FUDescData structures
85 for (FUDDiterator i
= paramList
.begin(); i
!= paramList
.end(); ++i
) {
88 // Don't bother with this if we're not going to create any FU's
92 // Create the FuncUnit object from this structure
93 // - add the capabilities listed in the FU's operation
96 // We create the first unit, then duplicate it as needed
98 FuncUnit
*fu
= new FuncUnit
;
100 OPDDiterator j
= (*i
)->opDescList
.begin();
101 OPDDiterator end
= (*i
)->opDescList
.end();
102 for (; j
!= end
; ++j
) {
103 // indicate that this pool has this capability
104 capabilityList
.set((*j
)->opClass
);
106 // Add each of the FU's that will have this capability to the
107 // appropriate queue.
108 for (int k
= 0; k
< (*i
)->number
; ++k
)
109 fuPerCapList
[(*j
)->opClass
].addFU(numFU
+ k
);
111 // indicate that this FU has the capability
112 fu
->addCapability((*j
)->opClass
, (*j
)->opLat
, (*j
)->issueLat
);
114 if ((*j
)->opLat
> maxOpLatencies
[(*j
)->opClass
])
115 maxOpLatencies
[(*j
)->opClass
] = (*j
)->opLat
;
117 if ((*j
)->issueLat
> maxIssueLatencies
[(*j
)->opClass
])
118 maxIssueLatencies
[(*j
)->opClass
] = (*j
)->issueLat
;
123 // Add the appropriate number of copies of this FU to the list
126 s
<< (*i
)->name() << "(0)";
128 funcUnits
.push_back(fu
);
130 for (int c
= 1; c
< (*i
)->number
; ++c
) {
133 FuncUnit
*fu2
= new FuncUnit(*fu
);
135 s
<< (*i
)->name() << "(" << c
<< ")";
137 funcUnits
.push_back(fu2
);
142 unitBusy
.resize(numFU
);
144 for (int i
= 0; i
< numFU
; i
++) {
150 FUPool::annotateMemoryUnits(unsigned hit_latency
)
152 maxOpLatencies
[MemReadOp
] = hit_latency
;
154 fuListIterator i
= funcUnits
.begin();
155 fuListIterator iend
= funcUnits
.end();
156 for (; i
!= iend
; ++i
) {
157 if ((*i
)->provides(MemReadOp
))
158 (*i
)->opLatency(MemReadOp
) = hit_latency
;
160 if ((*i
)->provides(MemWriteOp
))
161 (*i
)->opLatency(MemWriteOp
) = hit_latency
;
166 FUPool::getUnit(OpClass capability
)
168 // If this pool doesn't have the specified capability,
169 // return this information to the caller
170 if (!capabilityList
[capability
])
173 int fu_idx
= fuPerCapList
[capability
].getFU();
174 int start_idx
= fu_idx
;
176 // Iterate through the circular queue if needed, stopping if we've reached
177 // the first element again.
178 while (unitBusy
[fu_idx
]) {
179 fu_idx
= fuPerCapList
[capability
].getFU();
180 if (fu_idx
== start_idx
) {
186 assert(fu_idx
< numFU
);
188 unitBusy
[fu_idx
] = true;
194 FUPool::freeUnitNextCycle(int fu_idx
)
196 assert(unitBusy
[fu_idx
]);
197 unitsToBeFreed
.push_back(fu_idx
);
201 FUPool::processFreeUnits()
203 while (!unitsToBeFreed
.empty()) {
204 int fu_idx
= unitsToBeFreed
.back();
205 unitsToBeFreed
.pop_back();
207 assert(unitBusy
[fu_idx
]);
209 unitBusy
[fu_idx
] = false;
216 cout
<< "Function Unit Pool (" << name() << ")\n";
217 cout
<< "======================================\n";
218 cout
<< "Free List:\n";
220 for (int i
= 0; i
< numFU
; ++i
) {
225 cout
<< " [" << i
<< "] : ";
227 cout
<< funcUnits
[i
]->name
<< " ";
232 cout
<< "======================================\n";
233 cout
<< "Busy List:\n";
234 for (int i
= 0; i
< numFU
; ++i
) {
239 cout
<< " [" << i
<< "] : ";
241 cout
<< funcUnits
[i
]->name
<< " ";
253 FUPool::takeOverFrom()
255 for (int i
= 0; i
< numFU
; i
++) {
258 unitsToBeFreed
.clear();
263 ////////////////////////////////////////////////////////////////////////////
265 // The SimObjects we use to get the FU information into the simulator
267 ////////////////////////////////////////////////////////////////////////////
270 // FUPool - Contails a list of FUDesc objects to make available
277 BEGIN_DECLARE_SIM_OBJECT_PARAMS(FUPool
)
279 SimObjectVectorParam
<FUDesc
*> FUList
;
281 END_DECLARE_SIM_OBJECT_PARAMS(FUPool
)
284 BEGIN_INIT_SIM_OBJECT_PARAMS(FUPool
)
286 INIT_PARAM(FUList
, "list of FU's for this pool")
288 END_INIT_SIM_OBJECT_PARAMS(FUPool
)
291 CREATE_SIM_OBJECT(FUPool
)
293 return new FUPool(getInstanceName(), FUList
);
296 REGISTER_SIM_OBJECT("FUPool", FUPool
)