2 * Copyright (c) 2007 MIPS Technologies, Inc.
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.
28 * Authors: Korey Sewell
35 #include "cpu/inorder/resources/resource_list.hh"
36 #include "cpu/inorder/resource_pool.hh"
39 using namespace ThePipeline
;
41 ResourcePool::ResourcePool(InOrderCPU
*_cpu
, InOrderCPUParams
*params
)
44 //@todo: use this function to instantiate the resources in resource pool. This will help in the
45 //auto-generation of this pipeline model.
46 //ThePipeline::addResources(resources, memObjects);
48 // Declare Resource Objects
49 // name - id - bandwidth - latency - CPU - Parameters
50 // --------------------------------------------------
51 resources
.push_back(new FetchSeqUnit("fetch_seq_unit", FetchSeq
,
52 StageWidth
* 2, 0, _cpu
, params
));
54 resources
.push_back(new TLBUnit("itlb", ITLB
, StageWidth
, 0, _cpu
, params
));
56 memObjects
.push_back(ICache
);
57 resources
.push_back(new CacheUnit("icache_port", ICache
,
58 StageWidth
* MaxThreads
, 0, _cpu
, params
));
60 resources
.push_back(new DecodeUnit("decode_unit", Decode
, StageWidth
, 0,
63 resources
.push_back(new BranchPredictor("branch_predictor", BPred
,
64 StageWidth
, 0, _cpu
, params
));
66 for (int i
= 0; i
< params
->numberOfThreads
; i
++) {
68 sprintf(fbuff_name
, "fetch_buffer_t%i", i
);
69 resources
.push_back(new InstBuffer(fbuff_name
, FetchBuff
+ i
, 4, 0,
73 resources
.push_back(new UseDefUnit("regfile_manager", RegManager
,
74 StageWidth
* MaxThreads
, 0, _cpu
, params
));
76 resources
.push_back(new AGENUnit("agen_unit", AGEN
, StageWidth
, 0, _cpu
,
79 resources
.push_back(new ExecutionUnit("execution_unit", ExecUnit
,
80 StageWidth
, 0, _cpu
, params
));
82 resources
.push_back(new MultDivUnit("mult_div_unit", MDU
, 5, 0, _cpu
,
85 resources
.push_back(new TLBUnit("dtlb", DTLB
, StageWidth
, 0, _cpu
, params
));
87 memObjects
.push_back(DCache
);
88 resources
.push_back(new CacheUnit("dcache_port", DCache
,
89 StageWidth
* MaxThreads
, 0, _cpu
, params
));
91 resources
.push_back(new GraduationUnit("graduation_unit", Grad
,
92 StageWidth
* MaxThreads
, 0, _cpu
, params
));
98 for (int i
=0; i
< resources
.size(); i
++) {
106 return cpu
->name() + ".ResourcePool";
111 ResourcePool::regStats()
113 DPRINTF(Resource
, "Registering Stats Throughout Resource Pool.\n");
115 int num_resources
= resources
.size();
117 for (int idx
= 0; idx
< num_resources
; idx
++) {
118 resources
[idx
]->regStats();
123 ResourcePool::getPort(const std::string
&if_name
, int idx
)
125 for (int i
= 0; i
< memObjects
.size(); i
++) {
126 int obj_idx
= memObjects
[i
];
127 Port
*port
= resources
[obj_idx
]->getPort(if_name
, idx
);
137 ResourcePool::getPortIdx(const std::string
&port_name
)
139 for (int i
= 0; i
< memObjects
.size(); i
++) {
140 unsigned obj_idx
= memObjects
[i
];
141 Port
*port
= resources
[obj_idx
]->getPort(port_name
, obj_idx
);
151 ResourcePool::request(int res_idx
, DynInstPtr inst
)
153 //Make Sure This is a valid resource ID
154 assert(res_idx
>= 0 && res_idx
< resources
.size());
156 return resources
[res_idx
]->request(inst
);
160 ResourcePool::squash(DynInstPtr inst
, int res_idx
, InstSeqNum done_seq_num
,
163 resources
[res_idx
]->squash(inst
, ThePipeline::NumStages
-1, done_seq_num
, tid
);
167 ResourcePool::slotsAvail(int res_idx
)
169 return resources
[res_idx
]->slotsAvail();
173 ResourcePool::slotsInUse(int res_idx
)
175 return resources
[res_idx
]->slotsInUse();
179 ResourcePool::scheduleEvent(InOrderCPU::CPUEventType e_type
, DynInstPtr inst
,
180 int delay
, int res_idx
, ThreadID tid
)
184 ResPoolEvent
*res_pool_event
= new ResPoolEvent(this);
188 case InOrderCPU::ActivateThread
:
190 DPRINTF(Resource
, "Scheduling Activate Thread Resource Pool Event for tick %i.\n",
192 res_pool_event
->setEvent(e_type
,
194 inst
->squashingStage
,
197 res_pool_event
->schedule(curTick() + cpu
->cycles(delay
));
202 case InOrderCPU::SuspendThread
:
203 case InOrderCPU::DeallocateThread
:
205 DPRINTF(Resource
, "Scheduling Deactivate Thread Resource Pool Event for tick %i.\n",
208 res_pool_event
->setEvent(e_type
,
210 inst
->squashingStage
,
214 res_pool_event
->schedule(curTick() + cpu
->cycles(delay
));
219 case ResourcePool::InstGraduated
:
221 DPRINTF(Resource
, "Scheduling Inst-Graduated Resource Pool Event for tick %i.\n",
224 res_pool_event
->setEvent(e_type
,
226 inst
->squashingStage
,
229 res_pool_event
->schedule(curTick() + cpu
->cycles(delay
));
234 case ResourcePool::SquashAll
:
236 DPRINTF(Resource
, "Scheduling Squash Resource Pool Event for tick %i.\n",
238 res_pool_event
->setEvent(e_type
,
240 inst
->squashingStage
,
243 res_pool_event
->schedule(curTick() + cpu
->cycles(delay
));
249 DPRINTF(Resource
, "Ignoring Unrecognized CPU Event Type #%i.\n", e_type
);
250 ; // If Resource Pool doesnt recognize event, we ignore it.
255 ResourcePool::unscheduleEvent(int res_idx
, DynInstPtr inst
)
257 resources
[res_idx
]->unscheduleEvent(inst
);
261 ResourcePool::squashAll(DynInstPtr inst
, int stage_num
,
262 InstSeqNum done_seq_num
, ThreadID tid
)
264 DPRINTF(Resource
, "[tid:%i] Stage %i squashing all instructions above [sn:%i].\n",
265 stage_num
, tid
, done_seq_num
);
267 int num_resources
= resources
.size();
269 for (int idx
= 0; idx
< num_resources
; idx
++) {
270 resources
[idx
]->squash(inst
, stage_num
, done_seq_num
, tid
);
275 ResourcePool::activateAll(ThreadID tid
)
277 DPRINTF(Resource
, "[tid:%i] Broadcasting Thread Activation to all resources.\n",
280 int num_resources
= resources
.size();
282 for (int idx
= 0; idx
< num_resources
; idx
++) {
283 resources
[idx
]->activateThread(tid
);
288 ResourcePool::deactivateAll(ThreadID tid
)
290 DPRINTF(Resource
, "[tid:%i] Broadcasting Thread Deactivation to all resources.\n",
293 int num_resources
= resources
.size();
295 for (int idx
= 0; idx
< num_resources
; idx
++) {
296 resources
[idx
]->deactivateThread(tid
);
301 ResourcePool::instGraduated(InstSeqNum seq_num
, ThreadID tid
)
303 DPRINTF(Resource
, "[tid:%i] Broadcasting [sn:%i] graduation to all resources.\n",
306 int num_resources
= resources
.size();
308 for (int idx
= 0; idx
< num_resources
; idx
++) {
309 resources
[idx
]->instGraduated(seq_num
, tid
);
313 ResourcePool::ResPoolEvent::ResPoolEvent(ResourcePool
*_resPool
)
314 : Event(&mainEventQueue
, CPU_Tick_Pri
),
316 { eventType
= (InOrderCPU::CPUEventType
) Default
; }
319 ResourcePool::ResPoolEvent::process()
323 case InOrderCPU::ActivateThread
:
324 resPool
->activateAll(tid
);
327 case InOrderCPU::SuspendThread
:
328 case InOrderCPU::DeallocateThread
:
329 resPool
->deactivateAll(tid
);
332 case ResourcePool::InstGraduated
:
333 resPool
->instGraduated(seqNum
, tid
);
336 case ResourcePool::SquashAll
:
337 resPool
->squashAll(inst
, stageNum
, seqNum
, tid
);
341 fatal("Unrecognized Event Type");
344 resPool
->cpu
->cpuEventRemoveList
.push(this);
349 ResourcePool::ResPoolEvent::description()
351 return "Resource Pool event";
354 /** Schedule resource event, regardless of its current state. */
356 ResourcePool::ResPoolEvent::scheduleEvent(int delay
)
359 reschedule(curTick() + resPool
->cpu
->cycles(delay
));
360 else if (!scheduled())
361 schedule(curTick() + resPool
->cpu
->cycles(delay
));
364 /** Unschedule resource event, regardless of its current state. */
366 ResourcePool::ResPoolEvent::unscheduleEvent()