OpenASIP 2.2
Loading...
Searching...
No Matches
BusBroker.cc
Go to the documentation of this file.
1/*
2 Copyright (c) 2002-2011 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 BusBroker.cc
26 *
27 * Implementation of BusBroker 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
34#include "BusBroker.hh"
35#include "BusResource.hh"
39#include "ResourceMapper.hh"
40#include "Machine.hh"
41#include "Segment.hh"
42#include "Move.hh"
43#include "MoveGuard.hh"
44#include "Guard.hh"
45#include "AssocTools.hh"
46#include "MathTools.hh"
47#include "MapTools.hh"
48#include "MoveNode.hh"
50#include "SequenceTools.hh"
51#include "TemplateSlot.hh"
52#include "TerminalImmediate.hh"
53#include "UniversalMachine.hh"
54#include "ControlUnit.hh"
55#include "BasicBlockNode.hh"
57#include "BasicBlock.hh"
58#include "ControlFlowGraph.hh"
59
60using std::string;
61using std::set;
62using namespace TTAProgram;
63using namespace TTAMachine;
64
65/**
66 * Constructor.
67 *
68 * @param name name for this broker.
69 * @param ipsb reference to InputPSocketBroker of this RM.
70 * @param opsb reference to OutputPSocketBroker of this RM.
71 * @param initiationInterval initiationinterval when doing loop scheduling.
72 */
74 std::string name,
75 ResourceBroker& ipBroker,
76 ResourceBroker& opBroker,
77 const TTAMachine::Machine& mach,
78 unsigned int initiationInterval) :
79 ResourceBroker(name, initiationInterval), inputPSocketBroker_(ipBroker),
80 outputPSocketBroker_(opBroker), hasLimm_(false), mach_(&mach) {
81}
82
83/**
84 * Destructor.
85 */
89
90/**
91 * Return true if one of the resources managed by this broker is
92 * suitable for the request contained in the node and can be assigned
93 * to it in given cycle.
94 *
95 * @param cycle Cycle.
96 * @param node Node.
97 * @param bus if not null, bus that has to be used.
98 * @param srcFU if not null, srcFu that has to be used.
99 * @param dstFU if not null, dstFU that has to be used.
100 * @param immWriteCycle if not -1 and src is imm, write cycle of limm.
101 * @return True if one of the resources managed by this broker is
102 * suitable for the request contained in the node and can be assigned
103 * to it in given cycle.
104 */
105bool
107 const TTAMachine::Bus* bus,
108 const TTAMachine::FunctionUnit* srcFU,
109 const TTAMachine::FunctionUnit* dstFU,
110 int immWriteCycle,
111 const TTAMachine::ImmediateUnit* immu,
112 int immRegIndex) const {
113
114 cycle = instructionIndex(cycle);
115 SchedulingResourceSet allAvailableBuses =
117 cycle, node, bus, srcFU, dstFU, immWriteCycle, immu, immRegIndex);
118 return allAvailableBuses.count() > 0;
119}
120
121/**
122 * Return one (any) resource managed by this broker that can be
123 * assigned to the given node in the given cycle.
124 *
125 * If no change occurs to the state of the resources, the broker
126 * should always return the same object. If a resource of the type
127 * managed by this broker is already assigned to the node, it is
128 * returned.
129 *
130 * @param cycle Cycle.
131 * @param node Node.
132 * @param bus if not null, bus that has to be used.
133 * @param srcFU if not null, srcFu that has to be used.
134 * @param dstFU if not null, dstFU that has to be used.
135 * @param immWriteCycle if not -1 and src is imm, write cycle of limm.
136 * @return One (any) resource managed by this broker that can be
137 * assigned to the given node in the given cycle.
138 * @exception InstanceNotFound If no available resource is found.
139 */
142 const TTAMachine::Bus* bus,
143 const TTAMachine::FunctionUnit* srcFU,
144 const TTAMachine::FunctionUnit* dstFU,
145 int immWriteCycle,
146 const TTAMachine::ImmediateUnit* immu,
147 int immRegIndex) const {
148
149 cycle = instructionIndex(cycle);
150 SchedulingResourceSet allAvailableBuses =
151 allAvailableResources(cycle, node, bus, srcFU, dstFU, immWriteCycle,
152 immu, immRegIndex);
153 if (allAvailableBuses.count() == 0) {
154 string msg = "No available resource found.";
155 throw InstanceNotFound(__FILE__, __LINE__, __func__, msg);
156 } else {
157 if (bus != NULL) {
158 assert(allAvailableBuses.count() == 1);
159 }
160 return allAvailableBuses.resource(0);
161 }
162}
163
164/**
165 * Return all resources managed by this broker that can be assigned to
166 * the given node in the given cycle.
167 *
168 * @param cycle Cycle.
169 * @param node Node.
170 * @param bus if not null, bus that has to be used.
171 * @param srcFU if not null, srcFu that has to be used.
172 * @param dstFU if not null, dstFU that has to be used.
173 * @param immWriteCycle if not -1 and src is imm, write cycle of limm.
174 * @return All resources managed by this broker that can be assigned to
175 * the given node in the given cycle.
176 */
179 int cycle,
180 const MoveNode& node,
181 const TTAMachine::Bus* bus,
183 const TTAMachine::FunctionUnit*, int,
184 const TTAMachine::ImmediateUnit*, int) const {
185
186 cycle = instructionIndex(cycle);
187 SchedulingResourceSet candidates;
188
189 Move& move = const_cast<MoveNode&>(node).move();
190 const Port* dstPort = &move.destination().port();
191 Socket* inputSocket = dstPort->inputSocket();
192
193 // In case bus was already assigned previously, pick only relevant resource.
195 BusResource* preassignedBus = NULL;
196 if (&move.bus() != &um.universalBus()) {
197 preassignedBus = dynamic_cast<BusResource*>(resourceOf(move.bus()));
198 }
199 if (bus != NULL) {
200 preassignedBus = dynamic_cast<BusResource*>(resourceOf(*bus));
201 }
202
203 if (inputSocket == NULL) {
204 string unit = dstPort->parentUnit()->name();
205 string port = dstPort->name();
206 string msg =
207 "Tried to find bus for a move to '" + unit + "." + port +
208 "' which has no connections to an input socket. "
209 "Check operation bindings!";
210 throw ModuleRunTimeError(__FILE__, __LINE__, __func__, msg);
211 }
212
213 InputPSocketResource* iPSocket = NULL;
214 try {
215 iPSocket =
216 static_cast<InputPSocketResource*>(
217 inputPSocketBroker_.resourceOf(*inputSocket));
218 } catch (const KeyNotFound& e) {
219 std::string msg = "BusBroker: finding ";
220 msg += " resource for Socket ";
221 msg += " failed with error: ";
222 msg += e.errorMessageStack();
223 throw KeyNotFound(
224 __FILE__, __LINE__, __func__, msg);
225 }
226
227 OutputPSocketResource* oPSocket = NULL;
228
229 if (move.source().isImmediate()) {
230
231 // find a bus with appropriate immediate width that is connected to
232 // destination
233 ResourceMap::const_iterator resIter = resMap_.begin();
234 while (resIter != resMap_.end()) {
235 // look for bus resources with appropriate related shortimmsocket
236 // resources
237 BusResource* busRes =
238 static_cast<BusResource*>((*resIter).second);
239 if (busRes == NULL) {
240 throw InvalidData(
241 __FILE__, __LINE__, __func__,
242 "Bus broker has other then Bus Resource registered!");
243 }
244
245 ShortImmPSocketResource& immRes = findImmResource(*busRes);
246 if (preassignedBus == NULL || busRes == preassignedBus) {
247 if (canTransportImmediate(node, immRes) &&
248 busRes->canAssign(cycle, node, immRes, *iPSocket)) {
249 candidates.insert(*busRes);
250 }
251 }
252 resIter++;
253 }
254
255 } else {
256
257 const Port* srcPort = &move.source().port();
258 Socket* outputSocket = srcPort->outputSocket();
259 if (outputSocket == NULL) {
260 string unit = srcPort->parentUnit()->name();
261 string port = srcPort->name();
262 string msg =
263 "Tried to find bus for a move from '" + unit + "." + port +
264 "' which has no connections to an output socket! Check "
265 "operation bindings!";
266 throw ModuleRunTimeError(__FILE__, __LINE__, __func__, msg);
267 }
268
269 oPSocket = NULL;
270 try {
271 oPSocket =
272 static_cast<OutputPSocketResource*>(
273 outputPSocketBroker_.resourceOf(*outputSocket));
274 } catch (const KeyNotFound& e) {
275 std::string msg = "BusBroker: finding ";
276 msg += " resource for Socket ";
277 msg += " failed with error: ";
278 msg += e.errorMessageStack();
279 throw KeyNotFound(
280 __FILE__, __LINE__, __func__, msg);
281 }
282
283 ResourceMap::const_iterator resIter = resMap_.begin();
284 while (resIter != resMap_.end()) {
285 BusResource* busRes =
286 static_cast<BusResource*>((*resIter).second);
287 if (preassignedBus == NULL ||
288 busRes == preassignedBus) {
289 if (busRes->canAssign(cycle, node, *oPSocket, *iPSocket)) {
290 candidates.insert(*busRes);
291 }
292 }
293 resIter++;
294 }
295 }
296 if (!move.isUnconditional()) {
297
298 const Guard& guard = move.guard().guard();
299 for (int i = 0; i < candidates.count(); i++) {
300 SchedulingResource& busResource = candidates.resource(i);
301 const Bus* aBus =
302 static_cast<const Bus*>(&machinePartOf(busResource));
303 if (aBus == NULL) {
304 throw InvalidData(
305 __FILE__, __LINE__, __func__,
306 "Bus Resource is missing bus in MOM!");
307 }
308
309 bool guardFound = false;
310 for (int j = 0; j < aBus->guardCount(); j++) {
311 Guard* busGuard = aBus->guard(j);
312 if (busGuard->isEqual(guard)) {
313 guardFound = true;
314 break;
315 }
316 }
317
318 if (!guardFound) {
319 candidates.remove(busResource);
320 i--;
321 }
322 }
323 }
324 return candidates;
325}
326
327/**
328 * Tells whether the given resource is available for given node at
329 * given cycle.
330 */
331bool
333 SchedulingResource& res, const MoveNode& node, int cycle,
334 const TTAMachine::Bus* bus,
337 int,
338 const TTAMachine::ImmediateUnit*, int) const {
339
340 if (bus != NULL && resourceOf(*bus) != &res) {
341 return false;
342 }
343 cycle = instructionIndex(cycle);
344
345 Move& move = const_cast<MoveNode&>(node).move();
346 const Port* dstPort = &move.destination().port();
347 Socket* inputSocket = dstPort->inputSocket();
348
349 if (inputSocket == NULL) {
350 string unit = dstPort->parentUnit()->name();
351 string port = dstPort->name();
352 string msg =
353 "Tried to find bus for a move to '" + unit + "." + port +
354 "' which has no connections to an input socket. "
355 "Check operation bindings!";
356 throw ModuleRunTimeError(__FILE__, __LINE__, __func__, msg);
357 }
358
359 InputPSocketResource* iPSocket = NULL;
360 try {
361 iPSocket =
362 static_cast<InputPSocketResource*>(
363 inputPSocketBroker_.resourceOf(*inputSocket));
364 } catch (const KeyNotFound& e) {
365 std::string msg = "BusBroker: finding ";
366 msg += " resource for Socket ";
367 msg += " failed with error: ";
368 msg += e.errorMessageStack();
369 throw KeyNotFound(
370 __FILE__, __LINE__, __func__, msg);
371 }
372
373 OutputPSocketResource* oPSocket = NULL;
374
375 if (move.source().isImmediate()) {
376
377 // look for bus resources with appropriate related shortimmsocket
378 // resources
379 BusResource* busRes =
380 dynamic_cast<BusResource*>(&res);
381 if (busRes == NULL) {
382 throw InvalidData(
383 __FILE__, __LINE__, __func__,
384 "Wrong type of resource for the broker given!");
385 }
386
387 ShortImmPSocketResource& immRes = findImmResource(*busRes);
388 if (!canTransportImmediate(node, immRes) &&
389 busRes->canAssign(cycle, node, immRes, *iPSocket)) {
390 return false;
391 }
392 } else {
393 const Port* srcPort = &move.source().port();
394 Socket* outputSocket = srcPort->outputSocket();
395 if (outputSocket == NULL) {
396 string unit = srcPort->parentUnit()->name();
397 string port = srcPort->name();
398 string msg =
399 "Tried to find bus for a move from '" + unit + "." + port +
400 "' which has no connections to an output socket! Check "
401 "operation bindings!";
402 throw ModuleRunTimeError(__FILE__, __LINE__, __func__, msg);
403 }
404
405 oPSocket = NULL;
406 try {
407 oPSocket =
408 static_cast<OutputPSocketResource*>(
409 outputPSocketBroker_.resourceOf(*outputSocket));
410 } catch (const KeyNotFound& e) {
411 std::string msg = "BusBroker: finding ";
412 msg += " resource for Socket ";
413 msg += " failed with error: ";
414 msg += e.errorMessageStack();
415 throw KeyNotFound(
416 __FILE__, __LINE__, __func__, msg);
417 }
418
419 BusResource* busRes =
420 dynamic_cast<BusResource*>(&res);
421 if (busRes == NULL) {
422 throw InvalidData(
423 __FILE__, __LINE__, __func__,
424 "Wrong type of resource for the broker given!");
425 }
426
427 if (!busRes->canAssign(cycle, node, *oPSocket, *iPSocket)) {
428 return false;
429 }
430 }
431 if (!move.isUnconditional()) {
432
433 const Guard& guard = move.guard().guard();
434 const Bus* aBus =
435 dynamic_cast<const Bus*>(&machinePartOf(res));
436 if (aBus == NULL) {
437 throw InvalidData(
438 __FILE__, __LINE__, __func__,
439 "Bus Resource is missing bus in MOM!");
440 }
441
442 bool guardFound = false;
443 for (int j = 0; j < aBus->guardCount(); j++) {
444 Guard* busGuard = aBus->guard(j);
445 if (busGuard->isEqual(guard)) {
446 guardFound = true;
447 break;
448 }
449 }
450
451 if (!guardFound) {
452 return false;
453 }
454 }
455 return true;
456}
457
458/**
459 * Mark given resource as in use for the given node, and assign the
460 * corresponding machine part (if applicable) to the node's move.
461 *
462 * If the node is already assigned to given resource, this method does
463 * nothing.
464 *
465 * @param cycle Cycle for which to assign bus
466 * @param node Node which will be transfered using a bus
467 * @param res ResourceObject referring to particular bus to assign
468 * @exception WrongSubclass If this broker does not recognise the given
469 * type of resource.
470 * @exception InvalidParameters If he given resource cannot be assigned to
471 * given node or no corresponding machine part is found.
472 */
473void
475 int cycle, MoveNode& node, SchedulingResource& res, int, int) {
476
477 cycle = instructionIndex(cycle);
478 BusResource& busRes = static_cast<BusResource&>(res);
479 Move& move = const_cast<MoveNode&>(node).move();
480 if (hasResource(res)) {
481 Bus& bus =
482 const_cast<Bus&>(static_cast<const Bus&>(machinePartOf(res)));
483
485 if (&move.bus() != &um.universalBus()) {
486 busPreassigned_[&node] = true;
487 assert(&bus == &move.bus() &&
488 "preassigned bus which is different than selected bus?");
489 } else {
490 move.setBus(bus);
491 busPreassigned_[&node] = false;
492 }
493 if (!move.isUnconditional()) {
494 for (int j = 0; j < bus.guardCount(); j++) {
495 Guard* busGuard = bus.guard(j);
496 if (busGuard->isEqual(move.guard().guard())) {
497 move.setGuard(new MoveGuard(*busGuard));
498 break;
499 }
500 }
501 }
502 busRes.assign(cycle,node);
503 } else {
504 string msg = "Broker does not contain given resource.";
505 throw InvalidData(__FILE__, __LINE__, __func__, msg);
506 }
507 assignedResources_.insert(
508 std::pair<const MoveNode*, SchedulingResource*>(&node, &busRes));
509}
510
511/**
512 * Free the resource type managed by this broker and unassign it from
513 * given node.
514 *
515 * If this broker is not applicable to the given node, or the node is
516 * not assigned a resource of the managed type, this method does
517 * nothing.
518 *
519 * @param node Node to unassign.
520 */
521void
523
525 Move& move = const_cast<MoveNode&>(node).move();
526 const Bus& bus = move.bus();
527 SchedulingResource* res = resourceOf(bus);
528 BusResource& busRes = static_cast<BusResource&>(*res);
529 busRes.unassign(node.cycle(),node);
530 assignedResources_.erase(&node);
531 if (!busPreassigned_[&node]) {
533 move.setBus(um.universalBus());
534 }
535 }
536}
537
538/**
539 * Return the earliest cycle, starting from given cycle, where a
540 * resource of the type managed by this broker can be assigned to the
541 * given node.
542 *
543 * @param cycle Cycle.
544 * @param node Node.
545 * @return The earliest cycle, starting from given cycle, where a
546 * resource of the type managed by this broker can be assigned to the
547 * given node.
548 */
549int
552 const TTAMachine::FunctionUnit*, int,
554 int) const {
555 abortWithError("Not implemented.");
556 return -1;
557}
558
559/**
560 * Return the latest cycle, starting from given cycle, where a
561 * resource of the type managed by this broker can be assigned to the
562 * given node.
563 *
564 * @param cycle Cycle.
565 * @param node Node.
566 * @return The latest cycle, starting from given cycle, where a
567 * resource of the type managed by this broker can be assigned to the
568 * given node.
569 */
570int
573 const TTAMachine::FunctionUnit*, int,
575 int) const {
576 abortWithError("Not implemented.");
577 return -1;
578}
579
580/**
581 * Return true if the given node is already assigned a resource of the
582 * type managed by this broker, and the assignment appears valid (that
583 * is, the broker has marked that resource as in use in the given
584 * cycle).
585 *
586 * @param cycle Cycle.
587 * @param node Node.
588 * @return True if the given node is already assigned a resource of the
589 * type managed by this broker, and the assignment appears valid (that
590 * is, the broker has marked that resource as in use in the given
591 * cycle).
592 */
593bool
595 int cycle, const MoveNode& node, const TTAMachine::Bus*) const {
597 return false;
598 }
599 return isInUse(instructionIndex(cycle),node);
600}
601
602/**
603 * Return true if given node already uses a resource of the type
604 * managed by this broker and assignment appears to be valid.
605 *
606 * @param cycle Cycle to test
607 * @param node Node to test
608 * @return True if given node already uses a resource of the
609 * type managed by the broker.
610 */
611bool
612BusBroker::isInUse(int cycle, const MoveNode& node) const {
613 cycle = instructionIndex(cycle);
614 const Bus& bus = const_cast<MoveNode&>(node).move().bus();
615 if (!hasResourceOf(bus)) {
616 return false;
617 }
618
619 SchedulingResource* res = resourceOf(bus);
620 BusResource& busRes = static_cast<BusResource&>(*res);
621 return busRes.isInUse(cycle);
622}
623/**
624 * Return true if the given node needs a resource of the type managed
625 * by this broker, false otherwise.
626 *
627 * @param node Node.
628 * @return True if the given node needs a resource of the type managed
629 * by this broker, false otherwise.
630 */
631bool
633 return mn.isMove();
634}
635
636/**
637 * Build all resource objects of the controlled type required to model
638 * scheduling resources of the given target processor.
639 *
640 * This method cannot set up the resource links (dependent and related
641 * resources) of the constructed resource objects.
642 *
643 * @param target Target machine.
644 */
645void
647 hasLimm_ = target.immediateUnitNavigator().count() > 0;
648 Machine::BusNavigator navi = target.busNavigator();
651
652 std::map<const Bus*,int> limmSlotCounts;
653 std::map<const Bus*,int> nopSlotCounts;
654
655 // calculate count of limm slots and nop slots associated with each bus.
656 // used to priorize busses which do not get into way of limm writes.
657 for (int i = 0; i < itn.count(); i++) {
658 InstructionTemplate* it = itn.item(i);
659 for (int j = 0; j < it->slotCount(); j++) {
660 TemplateSlot* itSlot = it->slot(j);
661 if (itSlot->destination() != NULL) {
662 limmSlotCounts[itSlot->bus()]++;
663 }
664 }
665 }
666
667 for (int i = 0; i < navi.count(); i++) {
668 Bus* bus = navi.item(i);
669 assert(bus->segmentCount() == 1);
670 int socketCount = bus->segment(0)->connectionCount();
671 BusResource* busResource = new BusResource(
672 bus->name(), bus->width(),limmSlotCounts[bus],
673 nopSlotCounts[bus], bus->guardCount(),
674 bus->immediateWidth(), socketCount, initiationInterval_);
675 ResourceBroker::addResource(*bus, busResource);
676 }
677}
678
679/**
680 * Complete resource initialisation by creating the references to
681 * other resources due to a dependency or a relation. Use the given
682 * resource mapper to lookup dependent and related resources using
683 * machine parts as keys.
684 *
685 * @param mapper Resource mapper.
686 */
687void
689
690 setResourceMapper(mapper);
691
692 for (ResourceMap::iterator resIter = resMap_.begin();
693 resIter != resMap_.end(); resIter++) {
694
695 const Bus* bus = dynamic_cast<const Bus*>((*resIter).first);
696 if (bus == NULL) {
697 throw InvalidData(
698 __FILE__, __LINE__, __func__,
699 "Bus broker has other then Bus Resource registered!");
700 }
701
702 SchedulingResource* busResource = (*resIter).second;
703
704 int immWidth = bus->immediateWidth();
705
706 ShortImmPSocketResource* immSocketResource =
708 bus->name() + "Imm", immWidth, bus->signExtends(),
710
711 shortImmPSocketResources_.push_back(immSocketResource);
712 busResource->addToRelatedGroup(0, *immSocketResource);
713
714 for (int i = 0; i < bus->segmentCount(); i++) {
715 Segment* seg = bus->segment(i);
716 for (int j = 0; j < seg->connectionCount(); j++) {
717 Socket* socket = seg->connection(j);
718 SchedulingResource* relRes =
720 if (relRes == NULL) {
721 relRes = outputPSocketBroker_.resourceOf(*socket);
722 }
723 if (relRes != NULL) {
724 busResource->addToRelatedGroup(0, *relRes);
725 } else {
726 std::string msg = "BusBroker: finding ";
727 msg += " resource for Socket ";
728 msg += " failed. ";
729 throw KeyNotFound(
730 __FILE__, __LINE__, __func__, msg);
731 }
732 }
733 }
734 }
735}
736
737/**
738 * Return true always.
739 *
740 * @return True always.
741 */
742bool
744 return true;
745}
746
747/**
748 * Return true if immediate in given node can be transported by any bus
749 * in broker, with the guard which the move contains.
750 *
751 * @param node Node that contains immediate read.
752 * @return True if immediate in given node can be transported by any bus
753 * in broker.
754 */
755bool
757 const MoveNode& node, const TTAMachine::Bus* preassignedBus) const {
758 ResourceMap::const_iterator resIter = resMap_.begin();
759 while (resIter != resMap_.end()) {
760 BusResource* busRes = static_cast<BusResource*>((*resIter).second);
761 ShortImmPSocketResource* immRes = &findImmResource(*busRes);
762 const Bus* aBus = static_cast<const Bus*>(resIter->first);
763 if (preassignedBus != NULL && aBus != preassignedBus) {
764 resIter++;
765 continue;
766 }
767 if (canTransportImmediate(node, *immRes)) {
768 bool guardOK = false;
769 if (node.move().isUnconditional()) {
770 guardOK = true;
771 } else {
772 // We need to check that the bus contains the guard
773 // which the move has. Only return true if the
774 // guard is found from the bus.
775 const Guard& guard = node.move().guard().guard();
776 for (int j = 0; j < aBus->guardCount(); j++) {
777 Guard* busGuard = aBus->guard(j);
778 if (busGuard->isEqual(guard)) {
779 guardOK = true;
780 break;
781 }
782 }
783 }
784 if (guardOK) {
785 if (!hasLimm_) {
786 return true;
787 } else {
789 *aBus, node)) {
790 return true;
791 }
792 }
793 }
794 }
795 resIter++;
796 }
797 return false;
798}
799
800
802 const MoveNode&, ShortImmPSocketResource&) const {
803 return false; // WiP.
804}
805
806/**
807 * Return true if immediate in given node can be transported by bus
808 * that is represented by given p-socket resource.
809 *
810 * @param node Node that contains immediate read.
811 * @param immRes P-socket resource representing write if immediate to related
812 * bus.
813 * @return True if immediate in given node can be transported by bus
814 * that is represented by given p-socket resource.
815 */
816bool
818 const MoveNode& node,
819 ShortImmPSocketResource& immRes) const {
820
821 Move& move = const_cast<MoveNode&>(node).move();
822
823 if (move.isJump() && canPerformSIMMJump(node, immRes)) {
824 return true;
825 }
826
828 immRes.signExtends(),
829 static_cast<const TTAProgram::TerminalImmediate&>(move.source()),
830 *mach_);
831
832 if (bits <= immRes.immediateWidth()) {
833 return true;
834 } else {
835 return false;
836 }
837}
838
839/**
840 * Return the short immediate p-socket resource related to given bus.
841 *
842 * @param busRes Bus resource.
843 * @return The short immediate p-socket resource related to given bus.
844 */
847 int i = 0;
848 SchedulingResource* socketRes = NULL;
849 ShortImmPSocketResource* immRes = NULL;
850 while (i < busRes.relatedResourceCount(0)) {
851 socketRes = &busRes.relatedResource(0, i);
852 if (socketRes->isShortImmPSocketResource()) {
853 return *(static_cast<ShortImmPSocketResource*>(socketRes));
854 }
855 i++;
856 }
857 return *immRes;
858}
859
860/**
861 * Tests if any of a buses known to BusBroker supports a guard
862 * required by MoveNode.
863 *
864 * @param node MoveNode to test.
865 * @return true if some of the buses supports guard of node.
866 */
867bool
868BusBroker::hasGuard(const MoveNode& node) const {
869 Move& move = const_cast<MoveNode&>(node).move();
870 const Guard& guard = move.guard().guard();
871 ResourceMap::const_iterator resIter = resMap_.begin();
872 while (resIter != resMap_.end()) {
873 SchedulingResource& busResource = *(*resIter).second;
874 const Bus* aBus =
875 static_cast<const Bus*>(&machinePartOf(busResource));
876
877 for (int j = 0; j < aBus->guardCount(); j++) {
878 Guard* busGuard = aBus->guard(j);
879 if (busGuard->isEqual(guard)) {
880 return true;
881 }
882 }
883 resIter++;
884 }
885 return false;
886}
887
888void
891 for (std::list<SchedulingResource*>::iterator i =
893 i != shortImmPSocketResources_.end(); i++) {
894 (*i)->clear();
895 }
896 busPreassigned_.clear();
897}
898
#define __func__
#define abortWithError(message)
#define assert(condition)
find Finds info of the inner loops in the false
const TTAMachine::Machine * mach_
Definition BusBroker.hh:151
virtual ShortImmPSocketResource & findImmResource(BusResource &busRes) const
Definition BusBroker.cc:846
bool hasLimm_
Definition BusBroker.hh:150
virtual bool isAlreadyAssigned(int cycle, const MoveNode &node, const TTAMachine::Bus *preassignedBus) const override
Definition BusBroker.cc:594
ResourceBroker & outputPSocketBroker_
Definition BusBroker.hh:149
virtual void setupResourceLinks(const ResourceMapper &mapper)
Definition BusBroker.cc:688
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
Definition BusBroker.cc:550
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
Definition BusBroker.cc:178
virtual void unassign(MoveNode &node)
Definition BusBroker.cc:522
virtual bool isAvailable(SchedulingResource &des, const MoveNode &node, int cycle, const TTAMachine::Bus *bus, const TTAMachine::FunctionUnit *srcFU, const TTAMachine::FunctionUnit *dstFU, int immWriteCycle, const TTAMachine::ImmediateUnit *immu, int immRegIndex) const override
Definition BusBroker.cc:332
virtual ~BusBroker()
Definition BusBroker.cc:86
void clear() override
Definition BusBroker.cc:889
BusBroker(std::string name, ResourceBroker &ipBroker, ResourceBroker &opBroker, const TTAMachine::Machine &mach, unsigned int initiationInterval=0)
Definition BusBroker.cc:73
std::list< SchedulingResource * > shortImmPSocketResources_
Definition BusBroker.hh:146
virtual bool canTransportImmediate(const MoveNode &node, const TTAMachine::Bus *preAssigndBus) const
Definition BusBroker.cc:756
virtual void assign(int cycle, MoveNode &node, SchedulingResource &res, int immWriteCycle, int immRegIndex) override
Definition BusBroker.cc:474
virtual bool hasGuard(const MoveNode &node) const
Definition BusBroker.cc:868
virtual 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
Definition BusBroker.cc:106
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
Definition BusBroker.cc:571
std::map< const MoveNode *, bool > busPreassigned_
Definition BusBroker.hh:147
ResourceBroker & inputPSocketBroker_
Definition BusBroker.hh:148
virtual SchedulingResource & availableResource(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
Definition BusBroker.cc:141
virtual bool isInUse(int cycle, const MoveNode &node) const
Definition BusBroker.cc:612
virtual void buildResources(const TTAMachine::Machine &target)
Definition BusBroker.cc:646
virtual bool isBusBroker() const
Definition BusBroker.cc:743
virtual bool isApplicable(const MoveNode &node, const TTAMachine::Bus *) const override
Definition BusBroker.cc:632
bool canPerformSIMMJump(const MoveNode &mn, ShortImmPSocketResource &immRes) const
Definition BusBroker.cc:801
virtual bool canAssign(const int cycle, const MoveNode &node) const override
virtual bool isInUse(const int cycle) const override
virtual void assign(const int cycle, MoveNode &node) override
virtual void unassign(const int cycle, MoveNode &node) override
std::string errorMessageStack(bool messagesOnly=false) const
Definition Exception.cc:138
static int requiredImmediateWidth(bool signExtension, const TTAProgram::TerminalImmediate &source, const TTAMachine::Machine &mach)
static bool busConnectedToDestination(const TTAMachine::Bus &bus, const MoveNode &moveNode)
static bool containsKey(const MapType &aMap, const KeyType &aKey)
int cycle() const
Definition MoveNode.cc:421
bool isMove() const
TTAProgram::Move & move()
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
virtual void clear()
void setResourceMapper(const ResourceMapper &mapper)
unsigned int initiationInterval_
bool hasResourceOf(const TTAMachine::MachinePart &mp) const
virtual const TTAMachine::MachinePart & machinePartOf(const SchedulingResource &r) const
ResourceMap resMap_
void remove(SchedulingResource &resource)
SchedulingResource & resource(int index) const
void insert(SchedulingResource &resource)
virtual SchedulingResource & relatedResource(const int group, const int index) const
int relatedResourceCount(const int group) const
virtual bool isShortImmPSocketResource() const
virtual void addToRelatedGroup(const int group, SchedulingResource &resource)
static void deleteAllItems(SequenceType &aSequence)
virtual Segment * segment(int index) const
Definition Bus.cc:329
int width() const
Definition Bus.cc:149
int immediateWidth() const
Definition Bus.cc:160
bool signExtends() const
Definition Bus.cc:171
Guard * guard(int index) const
Definition Bus.cc:456
virtual int segmentCount() const
Definition Bus.cc:385
int guardCount() const
Definition Bus.cc:441
virtual TCEString name() const
virtual bool isEqual(const Guard &guard) const =0
virtual TemplateSlot * slot(int index) const
ComponentType * item(int index) const
virtual InstructionTemplateNavigator instructionTemplateNavigator() const
Definition Machine.cc:428
virtual ImmediateUnitNavigator immediateUnitNavigator() const
Definition Machine.cc:416
virtual BusNavigator busNavigator() const
Definition Machine.cc:356
virtual Socket * outputSocket() const
Definition Port.cc:281
Unit * parentUnit() const
virtual Socket * inputSocket() const
Definition Port.cc:261
virtual std::string name() const
Definition Port.cc:141
const Connection & connection(const Socket &socket) const
Definition Segment.cc:250
int connectionCount() const
const Bus * bus() const
ImmediateUnit * destination() const
const TTAMachine::Guard & guard() const
Definition MoveGuard.cc:86
MoveGuard & guard() const
Definition Move.cc:345
bool isUnconditional() const
Definition Move.cc:154
Terminal & source() const
Definition Move.cc:302
bool isJump() const
Definition Move.cc:164
void setGuard(MoveGuard *guard)
Definition Move.cc:360
void setBus(const TTAMachine::Bus &bus)
Definition Move.cc:383
Terminal & destination() const
Definition Move.cc:323
const TTAMachine::Bus & bus() const
Definition Move.cc:373
virtual const TTAMachine::Port & port() const
Definition Terminal.cc:378
virtual bool isImmediate() const
Definition Terminal.cc:63
static UniversalMachine & instance()
TTAMachine::Bus & universalBus() const