2 * Copyright (c) 2006 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 #include "cpu/o3/fu_pool.hh"
34 #include "cpu/func_unit.hh"
38 ////////////////////////////////////////////////////////////////////////////
40 // A pool of function units
44 FUPool::FUIdxQueue::addFU(int fu_idx
)
46 funcUnitsIdx
.push_back(fu_idx
);
51 FUPool::FUIdxQueue::getFU()
53 int retval
= funcUnitsIdx
[idx
++];
63 fuListIterator i
= funcUnits
.begin();
64 fuListIterator end
= funcUnits
.end();
71 FUPool::FUPool(const Params
*p
)
78 for (int i
= 0; i
< Num_OpClasses
; ++i
) {
79 maxOpLatencies
[i
] = 0;
80 maxIssueLatencies
[i
] = 0;
84 // Iterate through the list of FUDescData structures
86 const vector
<FUDesc
*> ¶mList
= p
->FUList
;
87 for (FUDDiterator i
= paramList
.begin(); i
!= paramList
.end(); ++i
) {
90 // Don't bother with this if we're not going to create any FU's
94 // Create the FuncUnit object from this structure
95 // - add the capabilities listed in the FU's operation
98 // We create the first unit, then duplicate it as needed
100 FuncUnit
*fu
= new FuncUnit
;
102 OPDDiterator j
= (*i
)->opDescList
.begin();
103 OPDDiterator end
= (*i
)->opDescList
.end();
104 for (; j
!= end
; ++j
) {
105 // indicate that this pool has this capability
106 capabilityList
.set((*j
)->opClass
);
108 // Add each of the FU's that will have this capability to the
109 // appropriate queue.
110 for (int k
= 0; k
< (*i
)->number
; ++k
)
111 fuPerCapList
[(*j
)->opClass
].addFU(numFU
+ k
);
113 // indicate that this FU has the capability
114 fu
->addCapability((*j
)->opClass
, (*j
)->opLat
, (*j
)->issueLat
);
116 if ((*j
)->opLat
> maxOpLatencies
[(*j
)->opClass
])
117 maxOpLatencies
[(*j
)->opClass
] = (*j
)->opLat
;
119 if ((*j
)->issueLat
> maxIssueLatencies
[(*j
)->opClass
])
120 maxIssueLatencies
[(*j
)->opClass
] = (*j
)->issueLat
;
125 // Add the appropriate number of copies of this FU to the list
128 s
<< (*i
)->name() << "(0)";
130 funcUnits
.push_back(fu
);
132 for (int c
= 1; c
< (*i
)->number
; ++c
) {
135 FuncUnit
*fu2
= new FuncUnit(*fu
);
137 s
<< (*i
)->name() << "(" << c
<< ")";
139 funcUnits
.push_back(fu2
);
144 unitBusy
.resize(numFU
);
146 for (int i
= 0; i
< numFU
; i
++) {
152 FUPool::annotateMemoryUnits(unsigned hit_latency
)
154 maxOpLatencies
[MemReadOp
] = hit_latency
;
156 fuListIterator i
= funcUnits
.begin();
157 fuListIterator iend
= funcUnits
.end();
158 for (; i
!= iend
; ++i
) {
159 if ((*i
)->provides(MemReadOp
))
160 (*i
)->opLatency(MemReadOp
) = hit_latency
;
162 if ((*i
)->provides(MemWriteOp
))
163 (*i
)->opLatency(MemWriteOp
) = hit_latency
;
168 FUPool::getUnit(OpClass capability
)
170 // If this pool doesn't have the specified capability,
171 // return this information to the caller
172 if (!capabilityList
[capability
])
175 int fu_idx
= fuPerCapList
[capability
].getFU();
176 int start_idx
= fu_idx
;
178 // Iterate through the circular queue if needed, stopping if we've reached
179 // the first element again.
180 while (unitBusy
[fu_idx
]) {
181 fu_idx
= fuPerCapList
[capability
].getFU();
182 if (fu_idx
== start_idx
) {
188 assert(fu_idx
< numFU
);
190 unitBusy
[fu_idx
] = true;
196 FUPool::freeUnitNextCycle(int fu_idx
)
198 assert(unitBusy
[fu_idx
]);
199 unitsToBeFreed
.push_back(fu_idx
);
203 FUPool::processFreeUnits()
205 while (!unitsToBeFreed
.empty()) {
206 int fu_idx
= unitsToBeFreed
.back();
207 unitsToBeFreed
.pop_back();
209 assert(unitBusy
[fu_idx
]);
211 unitBusy
[fu_idx
] = false;
218 cout
<< "Function Unit Pool (" << name() << ")\n";
219 cout
<< "======================================\n";
220 cout
<< "Free List:\n";
222 for (int i
= 0; i
< numFU
; ++i
) {
227 cout
<< " [" << i
<< "] : ";
229 cout
<< funcUnits
[i
]->name
<< " ";
234 cout
<< "======================================\n";
235 cout
<< "Busy List:\n";
236 for (int i
= 0; i
< numFU
; ++i
) {
241 cout
<< " [" << i
<< "] : ";
243 cout
<< funcUnits
[i
]->name
<< " ";
257 for (int i
= 0; i
< numFU
; i
++) {
260 unitsToBeFreed
.clear();
265 ////////////////////////////////////////////////////////////////////////////
267 // The SimObjects we use to get the FU information into the simulator
269 ////////////////////////////////////////////////////////////////////////////
272 // FUPool - Contails a list of FUDesc objects to make available
279 FUPoolParams::create()
281 return new FUPool(this);