OpenASIP  2.0
Bus.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 Bus.cc
26  *
27  * Implementation of Bus class.
28  *
29  * @author Lasse Laasonen 2004 (lasse.laasonen-no.spam-tut.fi)
30  * @note reviewed 11 Jun 2004 by am, pj, jn, ll
31  * @note rating: red
32  */
33 
34 #include <string>
35 
36 #include "Bus.hh"
37 #include "Guard.hh"
38 #include "Segment.hh"
39 #include "Socket.hh"
40 #include "Bridge.hh"
41 #include "InstructionTemplate.hh"
42 #include "MOMTextGenerator.hh"
43 #include "Application.hh"
44 #include "ContainerTools.hh"
45 #include "ObjectState.hh"
46 
47 using std::vector;
48 using std::string;
49 using boost::format;
50 
51 namespace TTAMachine {
52 
53 // declaration of constants used in ObjectStates
54 const string Bus::OSNAME_BUS = "bus";
55 const string Bus::OSKEY_WIDTH = "width";
56 const string Bus::OSKEY_IMMWIDTH = "immwidth";
57 const string Bus::OSKEY_EXTENSION = "extension";
58 const string Bus::OSVALUE_SIGN = "sign";
59 const string Bus::OSVALUE_ZERO = "zero";
60 
61 
62 /**
63  * Constructor.
64  *
65  * @param name Name of the bus.
66  * @param width Bit width of the bus.
67  * @param immWidth Bit width of the inline immediate word.
68  * @param extensionMode Extension mode applied to the inline immediate word
69  * when it is narrower than the bus on which it is
70  * transported.
71  * @exception OutOfRange If the given width or immediate width is invalid.
72  * @exception InvalidName If the given name is not a valid component name.
73  */
75  const std::string& name, int width, int immWidth,
76  Machine::Extension extensionMode)
77  : Component(name),
78  width_(width),
79  immWidth_(immWidth),
80  extensionMode_(extensionMode) {
81  if (width <= 0 || immWidth < 0 || immWidth > width) {
82  string procName = "Bus::Bus";
83  throw OutOfRange(__FILE__, __LINE__, procName);
84  }
85 }
86 
87 /**
88  * Constructor.
89  *
90  * Loads the state of the bus from the given ObjectState instance. Does not
91  * load connections to sockets.
92  *
93  * @param state Root node of the ObjectState tree from which the state is
94  * loaded.
95  * @exception ObjectStateLoadingException If the given ObjectState instance
96  * is invalid.
97  */
98 Bus::Bus(const ObjectState* state) : Component(state) {
99  try {
101  } catch (Exception&) {
103  deleteAllGuards();
104  throw;
105  }
106 }
107 
108 /**
109  * Destructor.
110  *
111  * Before destruction detaches all sockets from the bus.
112  */
114  unsetMachine();
116  deleteAllGuards();
117 }
118 
119 
120 /**
121  * Returns the position of the bus in move slot order.
122  *
123  * @return The position (0 is the first position).
124  * @exception NotAvailable If the bus is not registered to a machine.
125  */
126 int
127 Bus::position() const {
128  if (!isRegistered()) {
129  throw NotAvailable(__FILE__, __LINE__, __func__);
130  }
131 
133  for (int i = 0; i < busNav.count(); i++) {
134  if (busNav.item(i) == this) {
135  return i;
136  }
137  }
138 
139  assert(false);
140  return 0;
141 }
142 
143 /**
144  * Returns the bit width of the bus.
145  *
146  * @return Bit width of the bus.
147  */
148 int
149 Bus::width() const {
150  return width_;
151 }
152 
153 
154 /**
155  * Returns the bit width of the inline immediate word.
156  *
157  * @return Bit width of the inline immediate word.
158  */
159 int
161  return immWidth_;
162 }
163 
164 
165 /**
166  * Returns true if the bus uses sign extension.
167  *
168  * @return True if the bus uses sign extension.
169  */
170 bool
172  return extensionMode_ == Machine::SIGN;
173 }
174 
175 
176 /**
177  * Returns true if the bus uses zero extension.
178  *
179  * @return True if the bus uses zero extension.
180  */
181 bool
183  return extensionMode_ == Machine::ZERO;
184 }
185 
186 
187 /**
188  * Sets the name of the bus.
189  *
190  * @param name Name of the bus.
191  * @exception ComponentAlreadyExists If a bus with the given name is
192  * already in the same machine.
193  * @exception InvalidName If the given name is not a valid component name.
194  */
195 void
196 Bus::setName(const std::string& name) {
197  if (name == this->name()) {
198  return;
199  }
200 
201  if (machine() != NULL) {
202  if (machine()->busNavigator().hasItem(name) ||
203  machine()->immediateSlotNavigator().hasItem(name)) {
204  string procName = "Bus::setName";
205  throw ComponentAlreadyExists(__FILE__, __LINE__, procName);
206  } else {
208  }
209  } else {
211  }
212 }
213 
214 /**
215  * Sets the bit width of the bus.
216  *
217  * @param width The new bit width of the bus.
218  * @exception OutOfRange If the given width is less or equal to zero or if
219  * there is an instruction template that has greater
220  * bit width for this slot.
221  */
222 void
223 Bus::setWidth(int width) {
224  const string procName = "Bus::setWidth";
225 
226  if (width <= 0) {
227  throw OutOfRange(__FILE__, __LINE__, procName);
228  }
229 
230  width_ = width;
231 }
232 
233 /**
234  * Sets the number of bits of inline immediates.
235  *
236  * @param width The bit width of inline immediates.
237  * @exception OutOfRange If the given width is negative or
238  greater than the bit width of the bus.
239  */
240 void
242  if (width < 0 || width > this->width()) {
243  string procName = "Bus::setImmediateWidth";
244  throw OutOfRange(__FILE__, __LINE__, procName);
245  }
246  immWidth_ = width;
247 }
248 
249 /**
250  * Sets the zero extension mode.
251  */
252 void
255 }
256 
257 
258 /**
259  * Sets the sign extension mode.
260  */
261 void
264 }
265 
266 
267 /**
268  * Sets the extension mode.
269  */
270 void
272  extensionMode_ = extension;
273 }
274 
275 
276 /**
277  * Returns true if the bus has a segment with the given name.
278  *
279  * @param name Name of the segment.
280  * @return True if the bus has a segment with the given name, otherwise
281  * false.
282  */
283 bool
284 Bus::hasSegment(const std::string& name) const {
285  SegmentTable::const_iterator iter = segments_.begin();
286  while (iter != segments_.end()) {
287  if ((*iter)->name() == name) {
288  return true;
289  }
290  iter++;
291  }
292  return false;
293 }
294 
295 
296 /**
297  * Returns true if the bus is connected to the given socket, otherwise false.
298  *
299  * @param socket Socket.
300  * @return True if the bus is connected to the given socket, otherwise false.
301  */
302 bool
303 Bus::isConnectedTo(const Socket& socket) const {
304 
305  SegmentTable::const_iterator iter = segments_.begin();
306  while (iter != segments_.end()) {
307  if ((*iter)->isConnectedTo(socket)) {
308  return true;
309  }
310  iter++;
311  }
312  return false;
313 }
314 
315 
316 /**
317  * Returns the bus segment at a given index.
318  *
319  * The index must be greater or equal to 0 and less than the number of
320  * segments. The segments are returned in the correct order. Thus, index 0
321  * returns the first segment in the segment chain, index 1 returns its
322  * destination segment and so on.
323  *
324  * @param index Index.
325  * @return The segment found on the given index.
326  * @exception OutOfRange If the given index is out of range.
327  */
328 Segment*
329 Bus::segment(int index) const {
330  if (index < 0 || index >= segmentCount()) {
331  string procName = "Bus::segment";
332  throw OutOfRange(__FILE__, __LINE__, procName);
333  }
334 
335  // find the first segment of the chain
336  Segment* firstSegment = NULL;
337  SegmentTable::const_iterator iter = segments_.begin();
338  while (iter != segments_.end()) {
339  Segment* segment = *iter;
340  if (!segment->hasSourceSegment()) {
341  firstSegment = segment;
342  break;
343  }
344  iter++;
345  }
346 
347  // follow the segment chain until the requested segment is reached
348  Segment* nextSegment = firstSegment;
349  for (int i = 0; i < index; i++) {
350  nextSegment = nextSegment->destinationSegment();
351  }
352 
353  return nextSegment;
354 }
355 
356 /**
357  * Returns the segment which has the given name.
358  *
359  * @param name Name of the segment.
360  * @return Segment which has the given name.
361  * @exception InstanceNotFound If the bus does not contain a segment by the
362  * given name.
363  */
364 Segment*
365 Bus::segment(const std::string& name) const {
366  SegmentTable::const_iterator iter = segments_.begin();
367  while (iter != segments_.end()) {
368  if ((*iter)->name() == name) {
369  return *iter;
370  }
371  iter++;
372  }
373 
374  // requested segment not found
375  string procName = "Bus::segment";
376  throw InstanceNotFound(__FILE__, __LINE__, procName);
377 }
378 
379 /**
380  * Returns the number of segments in this bus.
381  *
382  * @return Number of segments in this bus.
383  */
384 int
386  return segments_.size();
387 }
388 
389 /**
390  * Checks whether the bus has the given guard.
391  */
392 bool
393 Bus::hasGuard(const Guard& guard) const {
394  for (GuardTable::const_iterator iter = guards_.begin();
395  iter != guards_.end(); iter++) {
396  if ((*iter)->isEqual(guard)) {
397  return true;
398  }
399  }
400  return false;
401 }
402 
403 /**
404  * Adds guard to the bus.
405  *
406  * @param guard Pointer to the Guard object to be added.
407  * @exception ComponentAlreadyExists If there is an equal guard already.
408  */
409 void
411  if (hasGuard(guard)) {
412  string procName = "Bus::addGuard";
413  throw ComponentAlreadyExists(__FILE__, __LINE__, __func__,
414  "Bus already has the given guard!");
415  }
416 
417  guards_.push_back(&guard);
418 }
419 
420 /**
421  * Removes the given guard from the bus.
422  *
423  * This method should be called by Guard destructor only.
424  *
425  * @param guard Guard to be removed.
426  */
427 void
429  // run time check: can be called from Guard destructor only
430  assert(guard.parentBus() == NULL);
432 }
433 
434 
435 /**
436  * Returns the number of guards in the bus.
437  *
438  * @return The number of guards in the bus.
439  */
440 int
442  return guards_.size();
443 }
444 
445 
446 /**
447  * Returns the guard by the given index.
448  *
449  * The index must be between 0 and the return value of numberOfGuards() - 1.
450  *
451  * @param index Index.
452  * @return The guard by the given index.
453  * @exception OutOfRange If the given index is out of range.
454  */
455 Guard*
456 Bus::guard(int index) const {
457  if (index < 0 || static_cast<size_t>(index) >= guards_.size()) {
458  string procName = "Bus::guard";
459  throw OutOfRange(__FILE__, __LINE__, procName);
460  }
461  return guards_[index];
462 }
463 
464 /**
465  * Checks if the bus has previous bus.
466  *
467  * Previous does not mean source in that case but the previous bus from
468  * location point of view.
469  *
470  * @return True if the bus has previous bus, otherwise false.
471  */
472 bool
474  Bridge* prevBridge = previousBridge();
475  return prevBridge != NULL;
476 }
477 
478 
479 /**
480  * Checks if the bus has next bus.
481  *
482  * Next does not mean destination bus in that case but the next bus from
483  * location point of view.
484  *
485  * @return True if the bus has next bus, otherwise false.
486  */
487 bool
489  Bridge* nextBridge = this->nextBridge();
490  return nextBridge != NULL;
491 }
492 
493 
494 /**
495  * Returns the next bus from the location point of view.
496  *
497  * @return The next bus.
498  * @exception InstanceNotFound If the bus is the last in the chain.
499  */
500 Bus*
501 Bus::nextBus() const {
502  Bridge* nextBridge = this->nextBridge();
503  if (nextBridge != NULL) {
504  return nextBridge->nextBus();
505  } else {
506  string procName = "Bus::nextBus";
507  throw InstanceNotFound(__FILE__, __LINE__, procName);
508  }
509 }
510 
511 /**
512  * Returns the previous bus from the location point of view.
513  *
514  * @return The previous bus.
515  * @exception InstanceNotFound If the bus is the first in the chain.
516  */
517 Bus*
519  Bridge* prevBridge = previousBridge();
520  if (prevBridge != NULL) {
521  return prevBridge->previousBus();
522  } else {
523  string procName = "Bus::previousBus";
524  throw InstanceNotFound(__FILE__, __LINE__, procName);
525  }
526 }
527 
528 /**
529  * Checks if the bus can read from the given bus.
530  *
531  * That is, checks if the given bus is source bus of this bus.
532  *
533  * @param bus The bus.
534  * @return True if this bus can read from the given bus.
535  */
536 bool
537 Bus::canRead(const Bus& bus) const {
538  BridgeTable::const_iterator iter = sourceBridges_.begin();
539  while (iter != sourceBridges_.end()) {
540  if ((*iter)->sourceBus() == &bus) {
541  return true;
542  }
543  iter++;
544  }
545  return false;
546 }
547 
548 
549 /**
550  * Checks if the bus can write to the given bus.
551  *
552  * That is, checks if the given bus is destination bus of this bus.
553  *
554  * @param bus The bus.
555  * @return True if this bus can write to the given bus.
556  */
557 bool
558 Bus::canWrite(const Bus& bus) const {
559  BridgeTable::const_iterator iter = destinationBridges_.begin();
560  while (iter != destinationBridges_.end()) {
561  if ((*iter)->destinationBus() == &bus) {
562  return true;
563  }
564  iter++;
565  }
566  return false;
567 }
568 
569 
570 /**
571  * Check if the bus can both read from and write to the given bus.
572  *
573  * That is, checks if the given bus is joined by a bidirectional bridge to
574  * this bus.
575  *
576  * @param bus The bus.
577  * @return True if this bus can both read from and write to the given bus.
578  */
579 bool
580 Bus::canReadWrite(const Bus& bus) const {
581  return canWrite(bus) && canRead(bus);
582 }
583 
584 
585 /**
586  * Adds a source bridge for the bus.
587  *
588  * This method can be called from methods of Bridge only. Do not call this
589  * method.
590  *
591  * @param bridge The source bridge to add.
592  */
593 void
595 
596  // run time check: can be called from Bridge methods only
597  assert(bridge.destinationBus() == NULL);
598 
599  assert(sourceBridges_.size() < 2);
600  sourceBridges_.push_back(&bridge);
601 }
602 
603 
604 /**
605  * Adds a destination bridge for the bus.
606  *
607  * This method can be called from methods of Bridge only. Do not call this
608  * method.
609  *
610  * @param bridge The destination bridge to add.
611  */
612 void
614 
615  // run time check: can be called from Bridge methods only
616  assert(bridge.sourceBus() == NULL);
617 
618  assert(destinationBridges_.size() < 2);
619  destinationBridges_.push_back(&bridge);
620 }
621 
622 
623 /**
624  * Removes a source bridge from the bus.
625  *
626  * This method can be called from Bridge destructor only. Do not call this
627  * method.
628  *
629  * @param bridge The source bridge to remove.
630  */
631 void
633 
634  // run time check: can be called from Bridge destructor only
635  assert(bridge.destinationBus() == NULL);
636 
638  sourceBridges_, &bridge);
639  assert(removed);
640 }
641 
642 
643 /**
644  * Removes a destination bridge from the bus.
645  *
646  * This method can be called from Bridge destructor only. Do not call this
647  * method.
648  *
649  * @param bridge The destination bridge to remove.
650  */
651 void
653 
654  // run time check: can be called from Bridge destructor only
655  assert(bridge.sourceBus() == NULL);
656 
658  destinationBridges_, &bridge);
659  assert(removed);
660 }
661 
662 
663 /**
664  * Registers the bus to a machine.
665  *
666  * @param mach Machine to which the bus is going to be registered.
667  * @exception ComponentAlreadyExists If the given machine already has another
668  * bus by the same name.
669  */
670 void
672  internalSetMachine(mach);
673  mach.addBus(*this);
674 }
675 
676 /**
677  * Removes registration of the bus from its current machine.
678  *
679  * Detaches all the sockets attached to the bus and deletes all the guards and
680  * modifies instruction templates to not use this bus.
681  */
682 void
684 
685  Machine* mach = machine();
686 
687  if (mach == NULL) {
688  return;
689  }
690 
692 
693  // detach all sockets
694  SegmentTable::iterator iter = segments_.begin();
695  while (iter != segments_.end()) {
696  (*iter)->detachAllSockets();
697  iter++;
698  }
699 
700  // delete bridges
701  Machine::BridgeNavigator bNavigator = mach->bridgeNavigator();
702  for (int i = 0; i < bNavigator.count();) {
703  if (bNavigator.item(i)->sourceBus() == this ||
704  bNavigator.item(i)->destinationBus() == this) {
705  // deleting bridge removes it automatically from the container,
706  // no iterator increment needed
707  delete bNavigator.item(i);
708  } else {
709  i++;
710  }
711  }
712 
713  // delete the template slot that uses the bus
716  for (int i = 0; i < itNav.count(); i++) {
717  InstructionTemplate* it = itNav.item(i);
718  it->removeSlot(name());
719  }
720 
721  mach->removeBus(*this);
722 }
723 
724 
725 
726 /**
727  * Adds the given segment to this bus.
728  *
729  * This method should be called by Segment constructor only.
730  *
731  * @param segment Segment to be added.
732  * @exception ComponentAlreadyExists If a segment with the same name as
733  * the given segment is already existing
734  * in this bus.
735  */
736 void
738  // run time check: can be called from Segment constructor only
739  assert(segment.parentBus() == NULL);
740 
741  if (hasSegment(segment.name())) {
742  string procname = "Bus::addSegment";
743  throw ComponentAlreadyExists(__FILE__, __LINE__, procname);
744  } else {
745  segments_.push_back(&segment);
746  }
747 }
748 
749 /**
750  * Removes the given segment from the bus.
751  *
752  * This method should be called by Segment destructor only.
753  *
754  * @param segment Segment to be removed.
755  */
756 void
758 
759  // run time check: can be called from Segment destructor only
760  assert(segment.parentBus() == NULL);
761 
763  assert(removed);
764 }
765 
766 
767 /**
768  * Saves the contents to an ObjectState tree.
769  *
770  * @return Root of the created tree.
771  */
773 Bus::saveState() const {
774 
775  ObjectState* busState = Component::saveState();
776 
777  // change the name of the ObjectState
778  busState->setName(OSNAME_BUS);
779 
780  // set attributes
781  busState->setAttribute(OSKEY_WIDTH, width_);
783  if (extensionMode_ == Machine::SIGN) {
785  } else if (extensionMode_ == Machine::ZERO) {
787  }
788 
789  // add segments
790  for (int i = 0; i < segmentCount(); i++) {
791  Segment* seg = segment(i);
792  busState->addChild(seg->saveState());
793  }
794 
795  // save guards
796  for (int i = 0; i < guardCount(); i++) {
797  Guard* currentGuard = guard(i);
798  busState->addChild(currentGuard->saveState());
799  }
800 
801  return busState;
802 }
803 
804 
805 /**
806  * Loads the state of the object from the given ObjectState instance.
807  *
808  * @param state The ObjectState instance.
809  * @exception ObjectStateLoadingException If the name of this bus becomes the
810  * same as an existing bus in the
811  * same machine or if generating
812  * references to other components did
813  * not succeed.
814  */
815 void
818  deleteAllGuards();
819 
820  // load state without references to other machine parts
821  try {
823 
824  // create guards and load states of segments
825  for (int i = 0; i < state->childCount(); i++) {
826  ObjectState* childState = state->child(i);
827  if (childState->name() == PortGuard::OSNAME_PORT_GUARD) {
828  // guard is registered automatically
829  new PortGuard(childState, *this);
830  } else if (childState->name() ==
832  // guard is registered automatically
833  new RegisterGuard(childState, *this);
834  } else if (childState->name() ==
836  // guard is registered automatically.
837  new UnconditionalGuard(childState, *this);
838  } else if (childState->name() == Segment::OSNAME_SEGMENT) {
839  string segmentName =
841  Segment* segment = this->segment(segmentName);
842  segment->loadState(childState);
843  }
844  }
845  } catch (Exception& exception) {
846  const string procName = "Bus::loadState";
848  __FILE__, __LINE__, procName, exception.errorMessage());
849  }
850 }
851 
852 /**
853  * Loads the state of the object from the given ObjectState tree without
854  * references to other components/subcomponents.
855  *
856  * @param state Root node of the ObjectState tree.
857  * @exception ObjectStateLoadingException If a bus by the same name is
858  * already registered to the same
859  * machine or if the given ObjectState
860  * tree is invalid.
861  */
862 void
864  const string procName = "Bus::loadStateWithoutReferences";
865 
866  if (state->name() != OSNAME_BUS) {
868  __FILE__, __LINE__, procName,
869  "Invalid XML object state for a bus, name: " + state->name());
870  }
871 
872  Component::loadState(state);
873 
874  // read attributes
875  try {
878  string extensionMode = state->stringAttribute(OSKEY_EXTENSION);
879  if (extensionMode == OSVALUE_SIGN) {
880  setSignExtends();
881  } else if (extensionMode == OSVALUE_ZERO) {
882  setZeroExtends();
883  } else {
884  throw ObjectStateLoadingException(__FILE__, __LINE__, procName);
885  }
886  } catch (Exception& e) {
887  throw ObjectStateLoadingException(__FILE__, __LINE__, procName,
888  e.errorMessage());
889  }
890 
891  // create all segments, guards are not created because they are
892  // completely useless without references
893  for (int i = 0; i < state->childCount(); i++) {
894  ObjectState* child = state->child(i);
895  if (child->name() == Segment::OSNAME_SEGMENT) {
896  try {
897  // segment is attached automatically
898  new Segment(child, *this);
899  } catch (const ComponentAlreadyExists&) {
900  MOMTextGenerator textGen;
901  format errorMsg = textGen.text(
903  errorMsg % child->stringAttribute(Segment::OSKEY_NAME) %
904  name();
906  __FILE__, __LINE__, procName, errorMsg.str());
907  }
908  }
909  }
910 
911  adjustSegmentChain(state);
912 }
913 
914 /**
915  * Deletes all the segments.
916  */
917 void
919  // segment destructor removes the pointer from the table
920  while (segments_.size() > 0) {
921  delete segments_[0];
922  }
923 }
924 
925 
926 /**
927  * Deletes all the guards.
928  */
929 void
931  // guard destructor removes the pointer from the table
932  while (guards_.size() > 0) {
933  delete guards_[0];
934  }
935 }
936 
937 
938 /**
939  * Returns a bridge that joins this bus and the previous bus of this bus.
940  *
941  * If there is two such bridges, returns one of them. If there is no such a
942  * bridge, returns NULL.
943  *
944  * @return Previous bridge or NULL.
945  */
946 Bridge*
948  Bridge* prevBridge = previousBridge(sourceBridges_);
949  if (prevBridge == NULL) {
950  prevBridge = previousBridge(destinationBridges_);
951  }
952  return prevBridge;
953 }
954 
955 
956 /**
957  * Returns a bridge that joins this bus and the next bus of this bus.
958  *
959  * If there is two such bridges, returns one of them. If there is no such a
960  * bridge, returns NULL.
961  *
962  * @return Next bridge or NULL.
963  */
964 Bridge*
967  if (nextBridge == NULL) {
969  }
970  return nextBridge;
971 }
972 
973 
974 /**
975  * Returns a bridge that joins this bus and the previous bus of this bus.
976  *
977  * Returns NULL if such a bridge does not exist.
978  *
979  * @param bridge The bridge table to look for the bridge.
980  * @return The previous bridge.
981  */
982 Bridge*
983 Bus::previousBridge(const BridgeTable& bridges) const {
984  BridgeTable::const_iterator iter = bridges.begin();
985  while (iter != bridges.end()) {
986  Bridge* bridge = *iter;
987  if (bridge->nextBus() == this) {
988  return bridge;
989  }
990  iter++;
991  }
992  return NULL;
993 }
994 
995 
996 /**
997  * Returns a bridge that joins this bus and the next bus of this bus.
998  *
999  * Returns NULL if such a bridge does not exist.
1000  *
1001  * @param bridge The bridge table to look for the bridge.
1002  * @return The next bridge.
1003  */
1004 Bridge*
1005 Bus::nextBridge(const BridgeTable& bridges) const {
1006  BridgeTable::const_iterator iter = bridges.begin();
1007  while (iter != bridges.end()) {
1008  Bridge* bridge = *iter;
1009  if (bridge->previousBus() == this) {
1010  return bridge;
1011  }
1012  iter++;
1013  }
1014  return NULL;
1015 }
1016 
1017 
1018 /**
1019  * Adjusts the order of segments according to the order represented by the
1020  * given ObjectState tree.
1021  *
1022  * @param busState ObjectState tree representing the state of this bus.
1023  * @exception ObjectStateLoadingException If the segment chain is erroneus in
1024  * the given ObjectState tree.
1025  */
1026 void
1028  const string procName = "Bus::adjustSegmentChain";
1029 
1030  if (segmentCount() == 0) {
1032  return;
1033  }
1034 
1035  MOMTextGenerator textGenerator;
1036 
1037  try {
1038  // find the last segment, the segment that has no destination
1039  Segment* lastSegment = NULL;
1040  for (int i = 0; i < busState->childCount(); i++) {
1041  ObjectState* childState = busState->child(i);
1042  if (childState->name() == Segment::OSNAME_SEGMENT &&
1043  !childState->hasAttribute(Segment::OSKEY_DESTINATION)) {
1044  string lastSegmentName =
1045  childState->stringAttribute(Segment::OSKEY_NAME);
1046  lastSegment = segment(lastSegmentName);
1047  break;
1048  }
1049  }
1050 
1051  // if last segment was not found, throw
1052  if (lastSegment == NULL) {
1053  format errorMsg = textGenerator.text(
1055  errorMsg % name();
1057  __FILE__, __LINE__, procName, errorMsg.str());
1058  }
1059 
1060  Segment* destSegment = lastSegment;
1061  int modifications = 0;
1062 
1063  // in the following loop, find a segment whose destination should be
1064  // lastSegment and set it in front of that segment
1065  while (modifications < segmentCount() - 1) {
1066  bool chainModified = false;
1067  for (int i = 0; i < busState->childCount(); i++) {
1068  ObjectState* childState = busState->child(i);
1069  if (childState->name() == Segment::OSNAME_SEGMENT &&
1071  string destName = childState->stringAttribute(
1073  if (destName == destSegment->name()) {
1074  string thisName = childState->
1075  stringAttribute(Segment::OSKEY_NAME);
1076  Segment* thisSegment = segment(thisName);
1077  thisSegment->moveBefore(*destSegment);
1078  destSegment = thisSegment;
1079  modifications++;
1080  chainModified = true;
1081  }
1082  }
1083  }
1084 
1085  // if the source segment was not found and the segment chain is not
1086  // set completely yet, throw
1087  if (!chainModified && modifications < segmentCount() - 1) {
1088  format errorMsg = textGenerator.text(
1090  errorMsg % name() % destSegment->name();
1092  __FILE__, __LINE__, procName, errorMsg.str());
1093  }
1094  }
1095  } catch (Exception& exception) {
1097  __FILE__, __LINE__, procName, exception.errorMessage());
1098  }
1099 }
1100 
1101 /**
1102  * Checks is this bus architecture equal with the given bus.
1103  *
1104  * Architecture equality means that buses have same widths, immediate widths,
1105  * extension modes, number of segments and same guards. Bridges are not checked.
1106  *
1107  * @param bus Bus to compare with.
1108  * @return True if the buses are architecture equal.
1109  */
1110 bool
1111 Bus::isArchitectureEqual(const Bus& bus) const {
1112 
1113  if (width() != bus.width() ||
1114  immediateWidth() != bus.immediateWidth() ||
1115  signExtends() != bus.signExtends() ||
1116  segmentCount() != bus.segmentCount()) {
1117  return false;
1118  }
1119  for (int i = 0; i < guardCount(); i++) {
1120  bool match = false;
1121 
1122  // check if there is matching guard in another bus
1123  for (int j = 0; j < bus.guardCount(); j++) {
1124  if (guard(i)->isEqual(*bus.guard(j))) {
1125  match = true;
1126  break;
1127  }
1128  }
1129 
1130  // if no matching guard was not found buses are not equal
1131  if (match == false) {
1132  return false;
1133  }
1134  // otherwise continue to next guard
1135  }
1136  return true;
1137 }
1138 
1139 /**
1140  * Copies the bus.
1141  *
1142  * @return Copy of the Bus.
1143  */
1144 Bus*
1145 Bus::copy() const {
1146  ObjectState* newBusState = saveState();
1147  Bus* newBus = new Bus(newBusState);
1148 
1149  delete newBusState;
1150  newBusState = NULL;
1151  return newBus;
1152 }
1153 
1154 void
1155 Bus::copyGuardsTo(Bus& other) const {
1156  for (int i = 0; i < guardCount(); ++i) {
1157  if (!other.hasGuard(*guard(i)))
1158  guard(i)->copyTo(other);
1159  }
1160 }
1161 
1162 }
TTAMachine::Bus::hasGuard
bool hasGuard(const Guard &guard) const
Definition: Bus.cc:393
TTAMachine::Bus::immediateWidth
int immediateWidth() const
Definition: Bus.cc:160
TTAMachine::Guard
Definition: Guard.hh:55
TTAMachine::Guard::saveState
virtual ObjectState * saveState() const
Definition: Guard.cc:149
TTAMachine::Component::internalUnsetMachine
void internalUnsetMachine()
TTAMachine::Bus::segments_
SegmentTable segments_
Contains all the segments of the bus.
Definition: Bus.hh:157
ObjectState::hasAttribute
bool hasAttribute(const std::string &name) const
Definition: ObjectState.cc:205
TTAMachine::Bus::setSignExtends
virtual void setSignExtends()
Definition: Bus.cc:262
TTAMachine::Bus::OSVALUE_SIGN
static const std::string OSVALUE_SIGN
ObjectState attribute value for sign extension.
Definition: Bus.hh:124
TTAMachine::Machine::ZERO
@ ZERO
Zero extension.
Definition: Machine.hh:81
TTAMachine::Component::setName
virtual void setName(const std::string &name)
Definition: MachinePart.cc:142
TTAMachine::Bus::setDestinationBridge
virtual void setDestinationBridge(Bridge &bridge)
Definition: Bus.cc:613
TTAMachine::Bus::immWidth_
int immWidth_
Bit width of the inline immediate word.
Definition: Bus.hh:150
TTAMachine::Bus::setZeroExtends
virtual void setZeroExtends()
Definition: Bus.cc:253
TTAMachine::Bridge::sourceBus
Bus * sourceBus() const
TTAMachine::Bridge::destinationBus
Bus * destinationBus() const
TTAMachine::Component::name
virtual TCEString name() const
Definition: MachinePart.cc:125
TTAMachine::Bus::setImmediateWidth
virtual void setImmediateWidth(int width)
Definition: Bus.cc:241
ObjectState::stringAttribute
std::string stringAttribute(const std::string &name) const
Definition: ObjectState.cc:249
TTAMachine::Bus::nextBridge
Bridge * nextBridge() const
Definition: Bus.cc:965
TTAMachine::Component::isRegistered
virtual bool isRegistered() const
Definition: MachinePart.cc:177
TTAMachine::RegisterGuard::OSNAME_REGISTER_GUARD
static const std::string OSNAME_REGISTER_GUARD
ObjectState name for RegisterGuard.
Definition: Guard.hh:159
TTAMachine::Bus::setWidth
virtual void setWidth(int width)
Definition: Bus.cc:223
TTAMachine::Bus::zeroExtends
bool zeroExtends() const
Definition: Bus.cc:182
ObjectStateLoadingException
Definition: Exception.hh:551
TTAMachine::Bridge
Definition: Bridge.hh:51
TTAMachine::Bus::setSourceBridge
virtual void setSourceBridge(Bridge &bridge)
Definition: Bus.cc:594
TTAMachine::Segment
Definition: Segment.hh:54
TTAMachine::Bus::width
int width() const
Definition: Bus.cc:149
TTAMachine::Bus::loadState
virtual void loadState(const ObjectState *state)
Definition: Bus.cc:816
OutOfRange
Definition: Exception.hh:320
TTAMachine::Guard::isEqual
virtual bool isEqual(const Guard &guard) const =0
TTAMachine::Bus
Definition: Bus.hh:53
TTAMachine::Bus::previousBridge
Bridge * previousBridge() const
Definition: Bus.cc:947
TTAMachine::Component::saveState
virtual ObjectState * saveState() const
Definition: MachinePart.cc:189
TTAMachine::Bus::canWrite
virtual bool canWrite(const Bus &bus) const
Definition: Bus.cc:558
TTAMachine::Machine::removeBus
virtual void removeBus(Bus &bus)
Definition: Machine.cc:477
TTAMachine::Bus::~Bus
virtual ~Bus()
Definition: Bus.cc:113
TTAMachine::Segment::destinationSegment
Segment * destinationSegment() const
MOMTextGenerator::TXT_NO_SOURCE_SEGMENT
@ TXT_NO_SOURCE_SEGMENT
Definition: MOMTextGenerator.hh:56
TTAMachine::Segment::OSKEY_NAME
static const std::string OSKEY_NAME
ObjectState attribute key for segment name.
Definition: Segment.hh:89
ObjectState
Definition: ObjectState.hh:59
MOMTextGenerator::TXT_NO_LAST_SEGMENT
@ TXT_NO_LAST_SEGMENT
Definition: MOMTextGenerator.hh:55
TTAMachine::Bus::addGuard
void addGuard(Guard &guard)
Definition: Bus.cc:410
TTAMachine::Machine::Navigator::count
int count() const
Texts::TextGenerator::text
virtual boost::format text(int textId)
Definition: TextGenerator.cc:94
TTAMachine::Bus::segment
virtual Segment * segment(int index) const
Definition: Bus.cc:329
ObjectState::setName
void setName(const std::string &name)
TTAMachine::Bus::hasPreviousBus
virtual bool hasPreviousBus() const
Definition: Bus.cc:473
TTAMachine::Bus::guards_
GuardTable guards_
Contains all guards of the bus.
Definition: Bus.hh:155
TTAMachine::Segment::loadState
virtual void loadState(const ObjectState *state)
Definition: Segment.cc:448
Socket.hh
TTAMachine::Component::internalSetMachine
void internalSetMachine(Machine &machine)
NotAvailable
Definition: Exception.hh:728
TTAMachine::Bus::signExtends
bool signExtends() const
Definition: Bus.cc:171
TTAMachine::Bus::loadStateWithoutReferences
void loadStateWithoutReferences(const ObjectState *state)
Definition: Bus.cc:863
TTAMachine::Segment::OSNAME_SEGMENT
static const std::string OSNAME_SEGMENT
ObjectState name for Segment.
Definition: Segment.hh:87
TTAMachine::Bus::extensionMode_
Machine::Extension extensionMode_
Extension mode applied to the inline immediate word.
Definition: Bus.hh:152
TTAMachine::InstructionTemplate
Definition: InstructionTemplate.hh:49
TTAMachine::Bus::addSegment
virtual void addSegment(Segment &segment)
Definition: Bus.cc:737
assert
#define assert(condition)
Definition: Application.hh:86
TTAMachine::Bus::OSNAME_BUS
static const std::string OSNAME_BUS
ObjectState name for Bus ObjectState.
Definition: Bus.hh:116
TTAMachine::UnconditionalGuard
Definition: Guard.hh:180
TTAMachine::Bus::unsetMachine
virtual void unsetMachine()
Definition: Bus.cc:683
Segment.hh
TTAMachine::Bus::position
virtual int position() const
Definition: Bus.cc:127
TTAMachine::Bus::destinationBridges_
BridgeTable destinationBridges_
Contains the destination bridges (max 2).
Definition: Bus.hh:162
TTAMachine::Guard::copyTo
virtual void copyTo(Bus &parentBus) const =0
TTAMachine::Bus::OSKEY_IMMWIDTH
static const std::string OSKEY_IMMWIDTH
ObjectState attribute key for immediate width.
Definition: Bus.hh:120
TTAMachine::Bus::canRead
virtual bool canRead(const Bus &bus) const
Definition: Bus.cc:537
TTAMachine::Machine::bridgeNavigator
virtual BridgeNavigator bridgeNavigator() const
Definition: Machine.cc:404
TTAMachine::Bus::clearSourceBridge
virtual void clearSourceBridge(Bridge &bridge)
Definition: Bus.cc:632
InstructionTemplate.hh
ContainerTools::removeValueIfExists
static bool removeValueIfExists(ContainerType &aContainer, const ElementType &aKey)
TTAMachine::RegisterGuard
Definition: Guard.hh:137
TTAMachine::Segment::parentBus
Bus * parentBus() const
TTAMachine::Bus::width_
int width_
Bit width of the bus.
Definition: Bus.hh:148
TTAMachine::Bus::setName
virtual void setName(const std::string &name)
Definition: Bus.cc:196
TTAMachine::Component::loadState
virtual void loadState(const ObjectState *state)
Definition: MachinePart.cc:205
Application.hh
TTAMachine::Bus::isArchitectureEqual
virtual bool isArchitectureEqual(const Bus &bus) const
Definition: Bus.cc:1111
__func__
#define __func__
Definition: Application.hh:67
ObjectState.hh
TTAMachine::Component
Definition: MachinePart.hh:90
TTAMachine::Socket
Definition: Socket.hh:53
Guard.hh
ObjectState::child
ObjectState * child(int index) const
Definition: ObjectState.cc:471
ObjectState::addChild
void addChild(ObjectState *child)
Definition: ObjectState.cc:376
TTAMachine::Bus::deleteAllGuards
void deleteAllGuards()
Definition: Bus.cc:930
TTAMachine::Bus::setMachine
virtual void setMachine(Machine &mach)
Definition: Bus.cc:671
ObjectState::childCount
int childCount() const
TTAMachine::Bus::sourceBridges_
BridgeTable sourceBridges_
Contains the source bridges (max 2).
Definition: Bus.hh:160
ObjectState::hasChild
bool hasChild(const std::string &name) const
Definition: ObjectState.cc:358
Exception
Definition: Exception.hh:54
TTAMachine::Bus::hasSegment
virtual bool hasSegment(const std::string &name) const
Definition: Bus.cc:284
Bus.hh
TTAMachine::Bus::deleteAllSegments
void deleteAllSegments()
Definition: Bus.cc:918
TTAMachine::Bus::isConnectedTo
virtual bool isConnectedTo(const Socket &socket) const
Definition: Bus.cc:303
TTAMachine::Machine::addBus
virtual void addBus(Bus &bus)
Definition: Machine.cc:139
ObjectState::name
std::string name() const
TTAMachine::Bus::adjustSegmentChain
void adjustSegmentChain(const ObjectState *busState)
Definition: Bus.cc:1027
TTAMachine::Bus::guardCount
int guardCount() const
Definition: Bus.cc:441
TTAMachine::Machine::SIGN
@ SIGN
Sign extension.
Definition: Machine.hh:82
TTAMachine::Segment::hasSourceSegment
bool hasSourceSegment() const
Definition: Segment.cc:388
TTAMachine::Bus::guard
Guard * guard(int index) const
Definition: Bus.cc:456
TTAMachine::Segment::saveState
virtual ObjectState * saveState() const
Definition: Segment.cc:421
Exception::errorMessage
std::string errorMessage() const
Definition: Exception.cc:123
TTAMachine::Bridge::previousBus
Bus * previousBus() const
Definition: Bridge.cc:164
TTAMachine::Bus::canReadWrite
virtual bool canReadWrite(const Bus &bus) const
Definition: Bus.cc:580
TTAMachine::Bridge::nextBus
Bus * nextBus() const
Definition: Bridge.cc:179
TTAMachine::Bus::clearDestinationBridge
virtual void clearDestinationBridge(Bridge &bridge)
Definition: Bus.cc:652
TTAMachine::Guard::parentBus
virtual Bus * parentBus() const
TTAMachine::Bus::saveState
virtual ObjectState * saveState() const
Definition: Bus.cc:773
TTAMachine::Bus::hasNextBus
virtual bool hasNextBus() const
Definition: Bus.cc:488
TTAMachine::Bus::removeGuard
virtual void removeGuard(Guard &guard)
Definition: Bus.cc:428
TTAMachine::Bus::OSKEY_WIDTH
static const std::string OSKEY_WIDTH
ObjectState attribute key for bus width.
Definition: Bus.hh:118
TTAMachine::Bus::removeSegment
virtual void removeSegment(Segment &segment)
Definition: Bus.cc:757
TTAMachine::Bus::previousBus
virtual Bus * previousBus() const
Definition: Bus.cc:518
TTAMachine::Component::machine
virtual Machine * machine() const
MOMTextGenerator
Definition: MOMTextGenerator.hh:40
TTAMachine::Bus::setExtensionMode
virtual void setExtensionMode(const Machine::Extension extension)
Definition: Bus.cc:271
TTAMachine::Machine::busNavigator
virtual BusNavigator busNavigator() const
Definition: Machine.cc:356
ComponentAlreadyExists
Definition: Exception.hh:510
TTAMachine::Segment::moveBefore
void moveBefore(Segment &segment)
Definition: Segment.cc:320
MOMTextGenerator.hh
ObjectState::intAttribute
int intAttribute(const std::string &name) const
Definition: ObjectState.cc:276
TTAMachine::Bus::BridgeTable
std::vector< Bridge * > BridgeTable
Definition: Bus.hh:134
TTAMachine::Segment::OSKEY_DESTINATION
static const std::string OSKEY_DESTINATION
ObjectState attribute key for destination segment name.
Definition: Segment.hh:91
TTAMachine::Machine::Extension
Extension
Definition: Machine.hh:80
MOMTextGenerator::TXT_SEGMENT_WITH_SAME_NAME
@ TXT_SEGMENT_WITH_SAME_NAME
Definition: MOMTextGenerator.hh:57
TTAMachine::Machine::Navigator::item
ComponentType * item(int index) const
TTAMachine::Bus::OSVALUE_ZERO
static const std::string OSVALUE_ZERO
ObjectState attribute key for zero extension.
Definition: Bus.hh:126
TTAMachine::PortGuard
Definition: Guard.hh:99
TTAMachine::Segment::name
std::string name() const
TTAMachine
Definition: Assembler.hh:48
TTAMachine::PortGuard::OSNAME_PORT_GUARD
static const std::string OSNAME_PORT_GUARD
ObjectState name for PortGuard ObjectState.
Definition: Guard.hh:117
TTAMachine::Bus::nextBus
virtual Bus * nextBus() const
Definition: Bus.cc:501
TTAMachine::InstructionTemplate::removeSlot
virtual void removeSlot(const std::string &slotName)
Definition: InstructionTemplate.cc:201
TTAMachine::Machine::instructionTemplateNavigator
virtual InstructionTemplateNavigator instructionTemplateNavigator() const
Definition: Machine.cc:428
TTAMachine::UnconditionalGuard::OSNAME_UNCONDITIONAL_GUARD
static const std::string OSNAME_UNCONDITIONAL_GUARD
ObjectState name for UnconditionalGuard.
Definition: Guard.hh:195
TTAMachine::Machine::Navigator
Definition: Machine.hh:186
TTAMachine::Bus::OSKEY_EXTENSION
static const std::string OSKEY_EXTENSION
ObjectState attribute key for extension mode.
Definition: Bus.hh:122
TTAMachine::Bus::segmentCount
virtual int segmentCount() const
Definition: Bus.cc:385
ObjectState::setAttribute
void setAttribute(const std::string &name, const std::string &value)
Definition: ObjectState.cc:100
InstanceNotFound
Definition: Exception.hh:304
Bridge.hh
TTAMachine::Machine
Definition: Machine.hh:73
TTAMachine::Bus::copy
virtual Bus * copy() const
Definition: Bus.cc:1145
TTAMachine::Bus::Bus
Bus(const std::string &name, int width, int immWidth, Machine::Extension extensionMode)
Definition: Bus.cc:74
ContainerTools.hh
TTAMachine::Bus::copyGuardsTo
virtual void copyGuardsTo(Bus &other) const
Definition: Bus.cc:1155