OpenASIP 2.2
Loading...
Searching...
No Matches
OutputPSocketBroker.cc
Go to the documentation of this file.
1/*
2 Copyright (c) 2002-2009 Tampere University.
3
4 This file is part of TTA-Based Codesign Environment (TCE).
5
6 Permission is hereby granted, free of charge, to any person obtaining a
7 copy of this software and associated documentation files (the "Software"),
8 to deal in the Software without restriction, including without limitation
9 the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 and/or sell copies of the Software, and to permit persons to whom the
11 Software is furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 DEALINGS IN THE SOFTWARE.
23 */
24/**
25 * @file OutputPSocketBroker.cc
26 *
27 * Implementation of OutputPSocketBroker class.
28 *
29 * @author Ari Mets�halme 2006 (ari.metsahalme-no.spam-tut.fi)
30 * @author Vladimir Guzma 2007 (vladimir.guzma-no.spam-tut.fi)
31 * @note rating: red
32 */
33
36#include "ResourceMapper.hh"
37#include "Machine.hh"
38#include "Segment.hh"
39#include "Terminal.hh"
40#include "MapTools.hh"
41#include "Move.hh"
42#include "TerminalRegister.hh"
43#include "MoveNode.hh"
44
45using std::string;
46
47using namespace TTAMachine;
48using namespace TTAProgram;
49
50/**
51 * Constructor.
52 *
53 * @param name name for this broker.
54 * @param fub reference to OutputFUBroker of this resource manager.
55 * @param initiationInterval initiationinterval when doing loop scheduling.
56 */
58 std::string name,
59 ResourceBroker& fub,
61 unsigned int initiationInterval) :
62 ResourceBroker(name, initiationInterval),
63 outputFUBroker_(fub), busBroker_(NULL), rm_(rm) {
64}
65
66/**
67 * Destructor.
68 */
71
72/**
73 * Return all resources managed by this broker that can be assigned to
74 * the given node in the given cycle.
75 *
76 * @param cycle Cycle.
77 * @param node Node.
78 * @return All resources managed by this broker that can be assigned to
79 * the given node in the given cycle.
80 */
83 int cycle,
84 const MoveNode& node,
85 const TTAMachine::Bus* preassignedBus,
88 int,
89 const TTAMachine::ImmediateUnit*, int) const {
90
91 cycle = instructionIndex(cycle);
92 if (!isApplicable(node, preassignedBus)) {
93 string msg = "Broker not capable of assigning resources to node!";
94 throw ModuleRunTimeError(__FILE__, __LINE__, __func__, msg);
95 }
96
97 TTAProgram::Move& move = const_cast<MoveNode&>(node).move();
98
99 SchedulingResourceSet resourceSet;
100
101 if (move.source().isFUPort()) {
102 // psocket is implicit by fubroker choice of FU
103 Socket& outputSocket = *move.source().port().outputSocket();
104 SchedulingResource* res = resourceOf(outputSocket);
105 if (res->canAssign(cycle,node)) {
106 resourceSet.insert(*res);
107 }
108 return resourceSet;
109 }
110 if (move.source().isGPR()) {
111 // assign psocket for reading rf
112 const RegisterFile& rf = move.source().registerFile();
113 for (int i = 0; i < rf.portCount(); i++) {
114 Port& port = *rf.port(i);
115 Socket* outputSocket = port.outputSocket();
116
117 if (outputSocket != NULL) {
118 SchedulingResource* res = resourceOf(*outputSocket);
119 if (res->canAssign(cycle, node)) {
120 resourceSet.insert(*res);
121 }
122 }
123 }
124 return resourceSet;
125 }
126 if (move.source().isImmediateRegister()) {
127 // assign psocket for reading IU
128 const ImmediateUnit& iu = move.source().immediateUnit();
129 for (int i = 0; i < iu.portCount(); i++) {
130 Port& port = *iu.port(i);
131 Socket* outputSocket = port.outputSocket();
132 if (outputSocket != NULL) {
133 SchedulingResource* res = resourceOf(*outputSocket);
134 if (res->canAssign(cycle, node)) {
135 resourceSet.insert(*res);
136 }
137 }
138 }
139 }
140 return resourceSet;
141}
142
143/**
144 * Return true if one of the resources managed by this broker is
145 * suitable for the request contained in the node and can be assigned
146 * to it in given cycle.
147 *
148 * @param cycle Cycle.
149 * @param node Node.
150 * @return True if one of the resources managed by this broker is
151 * suitable for the request contained in the node and can be assigned
152 * to it in given cycle.
153 */
154bool
156 int cycle, const MoveNode& node,
157 const TTAMachine::Bus* preassignedBus,
159 const TTAMachine::FunctionUnit*, int,
160 const TTAMachine::ImmediateUnit*, int) const {
161
162 cycle = instructionIndex(cycle);
163 if (!isApplicable(node, preassignedBus)) {
164 string msg = "Broker not capable of assigning resources to node!";
165 throw ModuleRunTimeError(__FILE__, __LINE__, __func__, msg);
166 }
167
168 TTAProgram::Move& move = const_cast<MoveNode&>(node).move();
169
170 SchedulingResourceSet resourceSet;
171
172 if (move.source().isFUPort()) {
173 // psocket is implicit by fubroker choice of FU
174 Socket& outputSocket = *move.source().port().outputSocket();
175 SchedulingResource* res = resourceOf(outputSocket);
176 if (res->canAssign(cycle,node)) {
177 return true;
178 } else {
179 return false;
180 }
181 }
182 if (move.source().isGPR()) {
183 // assign psocket for reading rf
184 const RegisterFile& rf = move.source().registerFile();
185 for (int i = 0; i < rf.portCount(); i++) {
186 Port& port = *rf.port(i);
187 Socket* outputSocket = port.outputSocket();
188
189 if (outputSocket != NULL) {
190 SchedulingResource* res = resourceOf(*outputSocket);
191 if (res->canAssign(cycle, node)) {
192 return true;
193 }
194 }
195 }
196 return false;
197 }
198 if (move.source().isImmediateRegister()) {
199 // assign psocket for reading IU
200 const ImmediateUnit& iu = move.source().immediateUnit();
201 for (int i = 0; i < iu.portCount(); i++) {
202 Port& port = *iu.port(i);
203 Socket* outputSocket = port.outputSocket();
204 if (outputSocket != NULL) {
205 SchedulingResource* res = resourceOf(*outputSocket);
206 if (res->canAssign(cycle, node)) {
207 return true;
208 }
209 }
210 }
211 return false;
212 }
213 return false;
214}
215
216
217
218
219
220
221/**
222 * Mark given resource as in use for the given node, and assign the
223 * corresponding machine part (if applicable) to the node's move.
224 *
225 * If the node is already assigned to given resource, this method does
226 * nothing.
227 *
228 * @param cycle Cycle.
229 * @param node Node to assign.
230 * @param res Resource representing Output PSocket
231 * @exception WrongSubclass If this broker does not recognise the given
232 * type of resource.
233 * @exception InvalidParameters If he given resource cannot be assigned to
234 * given node or no corresponding machine part is found.
235 */
236void
238 int cycle,
239 MoveNode& node,
241 int, int) {
242
243 cycle = instructionIndex(cycle);
244 if (!hasResource(res)) {
245 string msg = "Broker does not contain given resource.";
246 throw InvalidData(__FILE__, __LINE__, __func__, msg);
247 }
248
249 TTAProgram::Move& move = node.move();
250
251 if (move.source().isGPR() || move.source().isImmediateRegister()) {
252
253 Port* port = NULL;
254 const Socket& socket =
255 static_cast<const Socket&>(machinePartOf(res));
256 for (int i = 0; i < socket.portCount(); i++) {
257 if (socket.port(i)->outputSocket() == &socket) {
258 if ((move.source().isGPR() &&
259 socket.port(i)->parentUnit() !=
260 &move.source().registerFile()) ||
261 (move.source().isImmediateRegister() &&
262 socket.port(i)->parentUnit() !=
263 &move.source().immediateUnit()))
264 continue;
265 port = socket.port(i);
266 break;
267 }
268 }
269 if (port == NULL) {
270 throw InvalidData(
271 __FILE__, __LINE__, __func__,
272 "Broker can not find necesary Port!");
273 }
275 *port, move.source().index());
276 move.setSource(newSrc);
277 }
278 res.assign(cycle, node);
279 assignedResources_.insert(
280 std::pair<const MoveNode*, SchedulingResource*>(&node, &res));
281}
282
283/**
284 * Free the resource type managed by this broker and unassign it from
285 * given node.
286 *
287 * If this broker is not applicable to the given node, or the node is
288 * not assigned a resource of the managed type, this method does
289 * nothing.
290 *
291 * @param node Node.
292 */
293void
303
304/**
305 * Return the earliest cycle, starting from given cycle, where a
306 * resource of the type managed by this broker can be assigned to the
307 * given node.
308 *
309 * @param cycle Cycle.
310 * @param node Node.
311 * @return The earliest cycle, starting from given cycle, where a
312 * resource of the type managed by this broker can be assigned to the
313 * given node.
314 */
315int
317 const TTAMachine::Bus*,
320 int, const TTAMachine::ImmediateUnit*,
321 int) const {
322 abortWithError("Not implemented.");
323 return -1;
324}
325
326/**
327 * Return the latest cycle, starting from given cycle, where a
328 * resource of the type managed by this broker can be assigned to the
329 * given node.
330 *
331 * @param cycle Cycle.
332 * @param node Node.
333 * @return The latest cycle, starting from given cycle, where a
334 * resource of the type managed by this broker can be assigned to the
335 * given node.
336 */
337int
339 const TTAMachine::Bus*,
341 const TTAMachine::FunctionUnit*, int,
343 int) const {
344 abortWithError("Not implemented.");
345 return -1;
346}
347
348/**
349 * Return true if the given node is already assigned a resource of the
350 * type managed by this broker, and the assignment appears valid (that
351 * is, the broker has marked that resource as in use in the given
352 * cycle).
353 *
354 * @param cycle Cycle.
355 * @param node Node.
356 * @return True if the given node is already assigned a resource of the
357 * type managed by this broker, and the assignment appears valid (that
358 * is, the broker has marked that resource as in use in the given
359 * cycle).
360 */
361bool
363 int cycle,
364 const MoveNode& node, const TTAMachine::Bus* preassignedBus) const {
365 cycle = instructionIndex(cycle);
366 if (node.isSourceConstant() &&
367 node.move().hasAnnotations(
369 return true;
370 }
371 if (node.isSourceConstant() && rm_ &&
372 !rm_->canTransportImmediate(node, preassignedBus)) {
373 return true;
374 }
375 Terminal& src = const_cast<MoveNode&>(node).move().source();
376 if (src.isFUPort() || src.isGPR() || src.isImmediateRegister()) {
377 const Port& port = src.port();
378 if (port.outputSocket() == NULL)
379 return false;
381 if (res != NULL && res->isInUse(cycle) &&
383 return true;
384 }
385 }
386 return false;
387}
388
389/**
390 * Return true if the given node needs a resource of the type managed
391 * by this broker, false otherwise.
392 *
393 * @param node Node.
394 * @return True if the given node needs a resource of the type managed
395 * by this broker, false otherwise.
396 */
397bool
399 const MoveNode& node, const TTAMachine::Bus* preassignedBus) const {
400 if (!node.isMove()) {
401 return false;
402 }
403 Move& move = const_cast<MoveNode&>(node).move();
404 // If node is annotated, it will be converted to LIMM
405 // and so we will need to assign output PScoket
406 if (node.isSourceConstant() && node.move().hasAnnotations(
408 return true;
409 }
410 if (node.isSourceConstant() &&
411 rm_ && !rm_->canTransportImmediate(node, preassignedBus)) {
412 return true;
413 }
414 return (move.source().isFUPort() ||
415 move.source().isGPR() ||
416 move.source().isImmediateRegister());
417}
418
419/**
420 * Build all resource objects of the controlled type required to model
421 * scheduling resources of the given target processor.
422 *
423 * This method cannot set up the resource links (dependent and related
424 * resources) of the constructed resource objects.
425 *
426 * @param target Target machine.
427 */
428void
430
432
433 for (int i = 0; i < navi.count(); i++) {
434 Socket* socket = navi.item(i);
435 if (socket->direction() == Socket::OUTPUT) {
436 OutputPSocketResource* opsResource =
438 ResourceBroker::addResource(*socket, opsResource);
439 }
440 }
441}
442
443/**
444 * Complete resource initialisation by creating the references to
445 * other resources due to a dependency or a relation. Use the given
446 * resource mapper to lookup dependent and related resources using
447 * machine parts as keys.
448 *
449 * @param mapper Resource mapper.
450 */
451void
453
454 setResourceMapper(mapper);
455
456 for (ResourceMap::iterator resIter = resMap_.begin();
457 resIter != resMap_.end(); resIter++) {
458
459 const Socket* socket =
460 static_cast<const Socket*>((*resIter).first);
461
462 SchedulingResource* socketResource = (*resIter).second;
463
464 for (int i = 0; i < socket->portCount(); i++) {
465 Port* port = socket->port(i);
466 Unit* unit = port->parentUnit();
467 if (dynamic_cast<FunctionUnit*>(unit) != NULL) {
468
469 SchedulingResource& relRes =
471 socketResource->addToRelatedGroup(0, relRes);
472 } else if (dynamic_cast<ImmediateUnit*>(unit) != NULL) {
473 try {
474 SchedulingResource& relRes = mapper.resourceOf(*unit);
475 socketResource->addToRelatedGroup(1, relRes);
476 } catch (const KeyNotFound& e) {
477 std::string msg = "OutputPSocketBroker: finding ";
478 msg += " resource for IU ";
479 msg += " failed with error: ";
480 msg += e.errorMessageStack();
481 throw KeyNotFound(
482 __FILE__, __LINE__, __func__, msg);
483 }
484 }
485 }
486
487 for (int i = 0; i < socket->segmentCount(); i++) {
488 try {
489 Segment* segment = socket->segment(i);
490 Bus* bus = segment->parentBus();
491 SchedulingResource& relRes =
492 *busBroker_->resourceOf(*bus);
493 socketResource->addToRelatedGroup(2, relRes);
494 } catch (const KeyNotFound& e) {
495 std::string msg = "OutputPSocketBroker: finding ";
496 msg += " resource for Segment ";
497 msg += " failed with error: ";
498 msg += e.errorMessageStack();
499 throw KeyNotFound(
500 __FILE__, __LINE__, __func__, msg);
501 }
502 }
503 }
504}
505
506/**
507 * Gives reference to segmentbroker to this broker.
508 *
509 * Cannot be given in constructor because SegmentBroker is created later.
510 */
#define __func__
#define abortWithError(message)
std::string errorMessageStack(bool messagesOnly=false) const
Definition Exception.cc:138
static KeyType keyForValue(const MapType &aMap, const ValueType &aValue)
static bool containsKey(const MapType &aMap, const KeyType &aKey)
int cycle() const
Definition MoveNode.cc:421
bool isMove() const
TTAProgram::Move & move()
bool isSourceConstant() const
Definition MoveNode.cc:238
virtual int latestCycle(int cycle, const MoveNode &node, const TTAMachine::Bus *bus, const TTAMachine::FunctionUnit *srcFU, const TTAMachine::FunctionUnit *dstFU, int immWriteCycle, const TTAMachine::ImmediateUnit *immu, int immRegIndex) const override
SimpleResourceManager * rm_
ResourceBroker * busBroker_
virtual bool isApplicable(const MoveNode &node, const TTAMachine::Bus *b) const override
ResourceBroker & outputFUBroker_
virtual void buildResources(const TTAMachine::Machine &target) override
OutputPSocketBroker(std::string name, ResourceBroker &ofb, SimpleResourceManager *, unsigned int initiationInterval=0)
void setBusBroker(ResourceBroker &sb)
virtual void unassign(MoveNode &node) override
bool isAnyResourceAvailable(int cycle, const MoveNode &node, const TTAMachine::Bus *bus, const TTAMachine::FunctionUnit *srcFU, const TTAMachine::FunctionUnit *dstFU, int immWriteCycle, const TTAMachine::ImmediateUnit *immu, int immRegIndex) const override
virtual int earliestCycle(int cycle, const MoveNode &node, const TTAMachine::Bus *bus, const TTAMachine::FunctionUnit *srcFU, const TTAMachine::FunctionUnit *dstFU, int immWriteCycle, const TTAMachine::ImmediateUnit *immu, int immRegIndex) const override
virtual void assign(int cycle, MoveNode &node, SchedulingResource &res, int immWriteCycle, int immRegIndex) override
virtual bool isAlreadyAssigned(int cycle, const MoveNode &node, const TTAMachine::Bus *preassignedBus) const override
virtual void setupResourceLinks(const ResourceMapper &mapper) override
virtual SchedulingResourceSet allAvailableResources(int cycle, const MoveNode &node, const TTAMachine::Bus *bus, const TTAMachine::FunctionUnit *srcFU, const TTAMachine::FunctionUnit *dstFU, int immWriteCycle, const TTAMachine::ImmediateUnit *immu, int immRegIndex) const override
void addResource(const TTAMachine::MachinePart &mp, SchedulingResource *res)
MoveResMap assignedResources_
SchedulingResource * resourceOf(const TTAMachine::MachinePart &mp) const
unsigned int instructionIndex(unsigned int) const
bool hasResource(const SchedulingResource &r) const
void setResourceMapper(const ResourceMapper &mapper)
unsigned int initiationInterval_
virtual const TTAMachine::MachinePart & machinePartOf(const SchedulingResource &r) const
ResourceMap resMap_
SchedulingResource & resourceOf(const TTAMachine::MachinePart &mp, int index=0) const
void insert(SchedulingResource &resource)
virtual void unassign(const int cycle, MoveNode &node)=0
virtual bool canAssign(const int cycle, const MoveNode &node) const =0
virtual void addToRelatedGroup(const int group, SchedulingResource &resource)
virtual void assign(const int cycle, MoveNode &node)=0
virtual bool isInUse(const int cycle) const =0
virtual bool canTransportImmediate(const MoveNode &node, const TTAMachine::Bus *preAssignedBus=NULL) const
virtual RFPort * port(const std::string &name) const
virtual TCEString name() const
ComponentType * item(int index) const
virtual SocketNavigator socketNavigator() const
Definition Machine.cc:368
virtual Socket * outputSocket() const
Definition Port.cc:281
Unit * parentUnit() const
Bus * parentBus() const
@ OUTPUT
Data goes from port to bus.
Definition Socket.hh:60
Direction direction() const
Port * port(int index) const
Definition Socket.cc:266
Segment * segment(int index) const
Definition Socket.cc:401
int segmentCount() const
int portCount() const
virtual int portCount() const
Definition Unit.cc:135
bool hasAnnotations(ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) const
void setSource(Terminal *src)
Definition Move.cc:312
Terminal & source() const
Definition Move.cc:302
virtual int index() const
Definition Terminal.cc:274
virtual bool isGPR() const
Definition Terminal.cc:107
virtual bool isImmediateRegister() const
Definition Terminal.cc:97
virtual const TTAMachine::Port & port() const
Definition Terminal.cc:378
virtual const TTAMachine::ImmediateUnit & immediateUnit() const
Definition Terminal.cc:240
virtual const TTAMachine::RegisterFile & registerFile() const
Definition Terminal.cc:225
virtual bool isFUPort() const
Definition Terminal.cc:118