OpenASIP  2.0
Machine.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 Machine.cc
26  *
27  * Implementation of Machine class.
28  *
29  * @author Lasse Laasonen 2003 (lasse.laasonen-no.spam-tut.fi)
30  * @note reviewed 16 Jun 2004 by ml, tr, jm, ll
31  * @note rating: red
32  */
33 
34 #include <string>
35 #include <set>
36 #include <boost/functional/hash.hpp>
37 
38 #include "Machine.hh"
39 #include "Bus.hh"
40 #include "Segment.hh"
41 #include "Socket.hh"
42 #include "Bridge.hh"
43 #include "AddressSpace.hh"
44 #include "InstructionTemplate.hh"
45 #include "ImmediateUnit.hh"
46 #include "FunctionUnit.hh"
47 #include "RegisterFile.hh"
48 #include "ControlUnit.hh"
49 #include "MachineTester.hh"
50 #include "DummyMachineTester.hh"
51 #include "ContainerTools.hh"
52 #include "Guard.hh"
53 #include "FUPort.hh"
54 #include "ImmediateSlot.hh"
55 #include "Application.hh"
56 #include "ADFSerializer.hh"
57 #include "ObjectState.hh"
59 
60 using std::string;
61 using std::set;
62 
63 namespace TTAMachine {
64 
65 // initialization of static data members
66 const string Machine::OSNAME_MACHINE = "machine";
68  = "always-write-back";
70  = "trigger-invalidates";
71 const string Machine::OSKEY_FUNCTION_UNITS_ORDERED = "fu-ordered";
72 
73 /**
74  * Constructor.
75  */
77  controlUnit_(NULL), doValidityChecks_(true),
78  machineTester_(new MachineTester(*this)),
79  dummyMachineTester_(new DummyMachineTester(*this)),
80  EMPTY_ITEMP_NAME_("no_limm"), alwaysWriteResults_(false),
81  triggerInvalidatesResults_(false), fuOrdered_(false),
82  littleEndian_(true), bitness64_(false) {
83 
85 }
86 
87 
88 /**
89  * Copy constructor.
90  *
91  * Creates a copy of the given machine.
92  *
93  * @param old The machine to be copied.
94  */
95 Machine::Machine(const Machine& old) :
96  Serializable(), controlUnit_(NULL), doValidityChecks_(false),
97  machineTester_(new MachineTester(*this)),
98  dummyMachineTester_(new DummyMachineTester(*this)),
99  littleEndian_(old.littleEndian_),
100  bitness64_(old.bitness64_) {
101 
102  ObjectState* state = old.saveState();
103  loadState(state);
104  delete state;
105  doValidityChecks_ = true;
106 }
107 
108 
109 /**
110  * Destructor.
111  *
112  * Deletes all the components of the machine as well.
113  */
115 
116  if (controlUnit_ != NULL) {
117  delete controlUnit_;
118  }
119 
120  delete machineTester_;
121  delete dummyMachineTester_;
122 
123  // NOTE! other components are deleted in ComponentContainer's destructor
124 }
125 
126 bool
128  return false;
129 }
130 
131 /**
132  * Adds a bus into the machine.
133  *
134  * @param bus Bus being added.
135  * @exception ComponentAlreadyExists If a bus or immediate slot by the same
136  * name already exists in the machine.
137  */
138 void
140  // check that the name is unique among immediate slots
141  if (immediateSlotNavigator().hasItem(bus.name())) {
142  const string procName = "Machine::addBus";
143  throw ComponentAlreadyExists(__FILE__, __LINE__, procName);
144  }
145 
146  addComponent(busses_, bus);
147 }
148 
149 /**
150  * Adds a socket into the machine.
151  *
152  * @param socket Socket being added.
153  * @exception ComponentAlreadyExists If a socket by the same name already
154  * exists in the machine.
155  */
156 void
158  addComponent(sockets_, socket);
159 }
160 
161 /**
162  * Adds a unit into the machine.
163  *
164  * Use methods intended to add particular unit types like addFunctionUnit,
165  * addRegisterFile and addImmediateUnit if possible. Global control unit
166  * must be set using setGlobalControl function.
167  *
168  * @param unit Unit being added.
169  * @exception ComponentAlreadyExists If a unit by the same name and type
170  * already exists in the machine.
171  * @exception IllegalParameters If ControlUnit is tried to add with this
172  * method.
173  */
174 void
176  FunctionUnit* fu = dynamic_cast<FunctionUnit*>(&unit);
177  ImmediateUnit* iu = dynamic_cast<ImmediateUnit*>(&unit);
178  RegisterFile* rf = dynamic_cast<RegisterFile*>(&unit);
179 
180  if (fu != NULL) {
181  addFunctionUnit(*fu);
182  } else if (iu != NULL) {
183  addImmediateUnit(*iu);
184  } else if (rf != NULL) {
185  addRegisterFile(*rf);
186  } else {
187  const string procName = "Machine::addUnit";
188  throw IllegalParameters(__FILE__, __LINE__, procName);
189  }
190 }
191 
192 /**
193  * Adds the given function unit to the machine.
194  *
195  * @param unit The function unit to be added.
196  * @exception ComponentAlreadyExists If a function unit by the same
197  * name exists already.
198  * @exception IllegalParameters If tried to add control unit with this
199  * method.
200  */
201 void
203  const string procName = "Machine::addFunctionUnit";
204 
205  if (dynamic_cast<ControlUnit*>(&unit) != NULL) {
206  throw IllegalParameters(__FILE__, __LINE__, procName);
207  }
208 
209  if (controlUnit() != NULL && controlUnit()->name() == unit.name()) {
210  throw ComponentAlreadyExists(__FILE__, __LINE__, procName);
211  }
212 
214 }
215 
216 /**
217  * Adds the given immediate unit to the machine.
218  *
219  * @param unit The immediate unit to be added.
220  * @exception ComponentAlreadyExists If an immediate unit by the same
221  * name exists already.
222  */
223 void
226 }
227 
228 /**
229  * Adds the given register file to the machine.
230  *
231  * @param unit The register file to be added.
232  * @exception ComponentAlreadyExists If a register file by the same name
233  * exists already.
234  */
235 void
238 }
239 
240 /**
241  * Adds an address space into the machine.
242  *
243  * @param as AddressSpace being added.
244  * @exception ComponentAlreadyExists If an address space by the same name
245  * already exists in the machine.
246  */
247 void
250 }
251 
252 /**
253  * Adds a bridge into the machine.
254  *
255  * This method should be called from Bridge constructor only since bridges
256  * are added to machine at construction. Do not call this method.
257  *
258  * @param bridge Bridge being added.
259  * @exception ComponentAlreadyExists If a bridge by the same name already
260  * exists in the machine.
261  */
262 void
265 }
266 
267 /**
268  * Adds an instruction template for the machine.
269  *
270  * @param instructionTemplate The instruction template to be added.
271  * @exception ComponentAlreadyExists If an instruction template by the same
272  * name already exists in the machine.
273  */
274 void
277 }
278 
279 /**
280  * Adds an OTA format for the machine.
281  *
282  * @param OperationTriggeredFormat The OTA format to be added.
283  * @exception ComponentAlreadyExists If an instruction template by the same
284  * name already exists in the machine.
285  */
286 void
289 }
290 
291 /**
292  * Adds an immediate slot to (instruction of) the machine.
293  *
294  * @param slot The immediate slot to be added.
295  * @exception ComponentAlreadyExists If an immediate slot or bus by the same
296  * name already exists in the machine.
297  */
298 void
300  // check that the name is unique among buses
301  if (busNavigator().hasItem(slot.name())) {
302  const string procName = "Machine::addImmediateSlot";
303  throw ComponentAlreadyExists(__FILE__, __LINE__, procName);
304  }
305 
307 }
308 
309 /**
310  * Sets the global control unit for the machine.
311  *
312  * @param unit The new global control unit.
313  * @exception ComponentAlreadyExists If a control unit already exists in the
314  * machine.
315  */
316 void
318  const string procName = "Machine::setGlobalControl";
319 
320  if (controlUnit_ != NULL) {
321  throw ComponentAlreadyExists(__FILE__, __LINE__, procName);
322  }
323 
324  // check that the name is unique among function units
326  if (fuNav.hasItem(unit.name())) {
327  throw ComponentAlreadyExists(__FILE__, __LINE__, procName);
328  }
329 
330  if (unit.machine() == NULL) {
331  unit.setMachine(*this);
332  } else {
333  controlUnit_ = &unit;
334  }
335 }
336 
337 /**
338  * Returns the control unit of the machine.
339  *
340  * Returns null pointer if there is no control unit in the machine.
341  *
342  * @return The control unit of the machine.
343  */
346  return controlUnit_;
347 }
348 
349 
350 /**
351  * Returns a handle to the busses in the machine.
352  *
353  * @return Handle to the busses in the machine.
354  */
357  BusNavigator navigator(busses_);
358  return navigator;
359 }
360 
361 
362 /**
363  * Returns a handle to the sockets in the machine.
364  *
365  * @return Handle to the sockets in the machine.
366  */
369  SocketNavigator navigator(sockets_);
370  return navigator;
371 }
372 
373 
374 /**
375  * Returns a handle to the function units in the machine.
376  *
377  * @return Handle to the function units in the machine.
378  */
382  return navigator;
383 }
384 
385 
386 /**
387  * Returns a handle to the address spaces in the machine.
388  *
389  * @return Handle to the address spaces in the machine.
390  */
394  return navigator;
395 }
396 
397 
398 /**
399  * Returns a handle to the bridges in the machine.
400  *
401  * @return Handle to the bridges in the machine.
402  */
405  BridgeNavigator navigator(bridges_);
406  return navigator;
407 }
408 
409 
410 /**
411  * Returns a handle to the immediate units in the machine.
412  *
413  * @return Handle to the immediate units in the machine.
414  */
418  return navigator;
419 }
420 
421 
422 /**
423  * Returns a handle to the instruction templates in the machine.
424  *
425  * @return Handle to the instruction templates in the machine.
426  */
430  return navigator;
431 }
432 
433 /**
434  * Returns a handle to the instruction templates in the machine.
435  *
436  * @return Handle to the instruction templates in the machine.
437  */
441  return navigator;
442 }
443 
444 /**
445  * Returns a handle to the register files in the machine.
446  *
447  * @return Handle to the register files in the machine.
448  */
452  return navigator;
453 }
454 
455 
456 /**
457  * Returns a handle to the immediate slots in the machine.
458  *
459  * @return Handle to the immediate slots in the machine.
460  */
464  return navigator;
465 }
466 
467 
468 /**
469  * Removes bus from the machine.
470  *
471  * The machine will stay consistent after removal.
472  *
473  * @param bus Bus to be removed.
474  * @exception InstanceNotFound If the machine does not have the given bus.
475  */
476 void
478  removeComponent(busses_, bus);
479 }
480 
481 /**
482  * Removes socket from the machine.
483  *
484  * The machine will stay consistent after removal.
485  *
486  * @param socket Socket to be removed.
487  * @exception InstanceNotFound If the machine does not have the given socket.
488  */
489 void
491  removeComponent(sockets_, socket);
492 }
493 
494 /**
495  * Removes unit from the machine.
496  *
497  * The machine will stay consistent after removal. Global control unit must
498  * be removed using unsetGlobalControl method.
499  *
500  * @param unit Unit to be removed.
501  * @exception InstanceNotFound If the machine does not have the given unit.
502  * @exception IllegalParameters If ControlUnit is tried to remove.
503  */
504 void
506  FunctionUnit* fu = dynamic_cast<FunctionUnit*>(&unit);
507  ImmediateUnit* iu = dynamic_cast<ImmediateUnit*>(&unit);
508  RegisterFile* rf = dynamic_cast<RegisterFile*>(&unit);
509 
510  if (fu != NULL) {
511  removeFunctionUnit(*fu);
512  } else if (iu != NULL) {
513  removeImmediateUnit(*iu);
514  } else if (rf != NULL) {
515  removeRegisterFile(*rf);
516  } else {
517  const string procName = "Machine::removeUnit";
518  throw IllegalParameters(__FILE__, __LINE__, procName);
519  }
520 }
521 
522 /**
523  * Removes the given function unit from the machine.
524  *
525  * @param unit The function unit to be removed.
526  * @exception InstanceNotFound If the given function unit does not belong to
527  * the machine.
528  */
529 void
532 }
533 
534 /**
535  * Removes the given immediate unit from the machine.
536  *
537  * @param unit The immediate unit to be removed.
538  * @exception InstanceNotFound If the given immediate unit does not belong to
539  * the machine.
540  */
541 void
544 }
545 
546 /**
547  * Removes the given register file from the machine.
548  *
549  * @param unit The register file to be removed.
550  * @exception InstanceNotFound If the given register file does not belong to
551  * the machine.
552  */
553 void
556 }
557 
558 /**
559  * Removes the global control unit from the machine.
560  *
561  * WARNING: The unit is not deleted. You should have a reference to it to be
562  * able to delete it later.
563  */
564 void
566  if (controlUnit_ == NULL) {
567  return;
568  } else {
569  if (controlUnit_->machine() == NULL) {
570  controlUnit_ = NULL;
571  } else {
573  }
574  }
575 }
576 
577 
578 /**
579  * Deletes the given bridge.
580  *
581  * The machine will stay consistent after deletion.
582  *
583  * @param bridge Bridge to be deleted.
584  * @exception InstanceNotFound If the machine does not have the given bridge.
585  */
586 void
588  deleteComponent(bridges_, bridge);
589 }
590 
591 /**
592  * Deletes the given instruction template.
593  *
594  * @param instrTempl The instruction template to be deleted.
595  * @exception InstanceNotFound If the machine does not have the given
596  * instruction template.
597  */
598 void
601 }
602 
603 /**
604  * Deletes the given instruction template.
605  *
606  * @param instrTempl The instruction template to be deleted.
607  * @exception InstanceNotFound If the machine does not have the given
608  * instruction template.
609  */
610 void
613 }
614 
615 /**
616  * Deletes the given address space.
617  *
618  * @param as The address space to be deleted.
619  * @exception InstanceNotFound If the machine does not have the given address
620  * space.
621  */
622 void
625 }
626 
627 /**
628  * Deletes the given immediate slot.
629  *
630  * @param slot The immediate slot to be deleted.
631  * @exception InstanceNotFound If the machine does not have the given
632  * immediate slot.
633  */
634 void
637 }
638 
639 /**
640  * Sets new position for the given bus.
641  *
642  * @param bus The bus being moved.
643  * @param newPosition The index of the new position
644  * (the first position is 0).
645  * @exception IllagalRegistration If the given bus is not registered to the
646  * machine.
647  * @exception OutOfRange If the given position is less than 0 or not smaller
648  * than the number of buses in the machine.
649  */
650 void
651 Machine::setBusPosition(const Bus& bus, int newPosition) {
652  const string procName = "Machine::setBusPosition";
653 
654  if (bus.machine() != this) {
655  throw IllegalRegistration(__FILE__, __LINE__, procName);
656  }
657 
658  if (newPosition < 0 || newPosition >= busNavigator().count()) {
659  throw OutOfRange(__FILE__, __LINE__, procName);
660  }
661 
662  busses_.moveToPosition(&bus, newPosition);
663 }
664 
665 /**
666  * Returns the machine tester for the machine.
667  *
668  * @return The machine tester for the machine.
669  */
672  if (doValidityChecks_) {
673  return *machineTester_;
674  } else {
675  return *dummyMachineTester_;
676  }
677 }
678 
679 
680 /**
681  * Saves the machine to ObjectState tree.
682  *
683  * @return Root of the created ObjectState tree.
684  */
687 
688  ObjectState* rootState = new ObjectState(OSNAME_MACHINE);
689 
690  saveComponentStates(busses_, rootState);
691  saveComponentStates(sockets_, rootState);
692  saveComponentStates(bridges_, rootState);
700 
701  // save global control unit
702  if (controlUnit_ != NULL) {
703  rootState->addChild(controlUnit_->saveState());
704  }
705 
706  rootState->setAttribute(
708  rootState->setAttribute(
710  rootState->setAttribute(
712  rootState->setAttribute("little-endian", littleEndian_);
713  rootState->setAttribute("bitness64", bitness64_);
714 
715 
716  return rootState;
717 }
718 
719 
720 /**
721  * Loads the state of the machine from the given ObjectState tree.
722  *
723  * @param state Root node of the ObjectState tree.
724  * @exception ObjectStateLoadingException If the given ObjectState tree is
725  * invalid.
726  */
727 void
729  string procName = "Machine::loadState";
730 
731  if (state->name() != OSNAME_MACHINE) {
732  throw ObjectStateLoadingException(__FILE__, __LINE__, procName);
733  }
734 
735  // delete all the old components
736  busses_.deleteAll();
737  sockets_.deleteAll();
738  instructionTemplates_.deleteAll();
739  registerFiles_.deleteAll();
740  immediateUnits_.deleteAll();
741  functionUnits_.deleteAll();
742  addressSpaces_.deleteAll();
743  bridges_.deleteAll();
744  immediateSlots_.deleteAll();
745  operationTriggeredFormats_.deleteAll();
746 
747  if (controlUnit_ != NULL) {
748  delete controlUnit_;
749  controlUnit_ = NULL;
750  }
751 
752  Component* toAdd = NULL;
753 
760  setFUOrdered(
764  state->hasAttribute("little-endian") &&
765  state->boolAttribute("little-endian"));
766  set64bits(
767  state->hasAttribute("bitness64") &&
768  state->boolAttribute("bitness64"));
769 
770  try {
771  // create skeletons
772  for (int i = 0; i < state->childCount(); i++) {
773  toAdd = NULL;
774  ObjectState* child = state->child(i);
775  if (child->name() == Bus::OSNAME_BUS) {
776  Bus* bus = new Bus(child);
777  toAdd = bus;
778  addBus(*bus);
779  } else if (child->name() == Socket::OSNAME_SOCKET) {
780  Socket* socket = new Socket(child);
781  toAdd = socket;
782  addSocket(*socket);
783  } else if (child->name() == Bridge::OSNAME_BRIDGE) {
784  // bridge is registered automatically
785  new Bridge(child, *this);
786  } else if (child->name() == AddressSpace::OSNAME_ADDRESS_SPACE) {
787  // address space is registered automatically and its state is
788  // loaded completely --> no need to call loadState later
789  new AddressSpace(child, *this);
790  } else if (child->name() == RegisterFile::OSNAME_REGISTER_FILE) {
791  RegisterFile* regFile = new RegisterFile(child);
792  toAdd = regFile;
793  addRegisterFile(*regFile);
794  } else if (child->name() == FunctionUnit::OSNAME_FU) {
795  FunctionUnit* fu = new FunctionUnit(child);
796  toAdd = fu;
797  addFunctionUnit(*fu);
798  } else if (child->name() ==
800  ImmediateUnit* immUnit = new ImmediateUnit(child);
801  toAdd = immUnit;
802  addImmediateUnit(*immUnit);
803  } else if (child->name() == ControlUnit::OSNAME_CONTROL_UNIT) {
804  ControlUnit* cUnit = new ControlUnit(child);
805  toAdd = cUnit;
806  setGlobalControl(*cUnit);
807  } else if (child->name() == ImmediateSlot::OSNAME_IMMEDIATE_SLOT) {
808  new ImmediateSlot(child, *this);
809  } else if (
810  child->name() !=
814  __FILE__, __LINE__, procName);
815  }
816  }
817 
818  } catch (const Exception& e) {
819  if (toAdd != NULL) {
820  delete toAdd;
821  }
822  throw ObjectStateLoadingException(__FILE__, __LINE__, procName,
823  e.errorMessage());
824  }
825 
826  // load states of each component
827  try {
828  for (int i = 0; i < state->childCount(); i++) {
829  ObjectState* child = state->child(i);
830  string name = child->stringAttribute(Component::OSKEY_NAME);
831  if (child->name() == Bus::OSNAME_BUS) {
832  BusNavigator busNav = busNavigator();
833  Bus* bus = busNav.item(name);
834  bus->loadState(child);
835  } else if (child->name() == Socket::OSNAME_SOCKET) {
836  SocketNavigator socketNav = socketNavigator();
837  Socket* socket = socketNav.item(name);
838  socket->loadState(child);
839  } else if (child->name() == Bridge::OSNAME_BRIDGE) {
840  BridgeNavigator bridgeNav = bridgeNavigator();
841  Bridge* bridge = bridgeNav.item(name);
842  bridge->loadState(child);
843  } else if (child->name() == RegisterFile::OSNAME_REGISTER_FILE) {
845  RegisterFile* rf = rfNav.item(name);
846  rf->loadState(child);
847  } else if (child->name() == FunctionUnit::OSNAME_FU) {
849  FunctionUnit* fu = fuNav.item(name);
850  fu->loadState(child);
851  } else if (child->name() ==
854  ImmediateUnit* iu = iuNav.item(name);
855  iu->loadState(child);
856  } else if (child->name() ==
858  ControlUnit* cu = controlUnit();
859  cu->loadState(child);
860  } else if (child->name() ==
862  // instruction template loads its state completely
863  new InstructionTemplate(child, *this);
864  } else if (
866  new OperationTriggeredFormat(child, *this);
867  }
868  }
869  } catch (const Exception& e) {
870  throw ObjectStateLoadingException(__FILE__, __LINE__, procName,
871  e.errorMessage());
872  }
873 
874  // create an empty instruction template if there is no instruction
875  // templates
877  if (itNav.count() == 0) {
879  }
880 }
881 
882 /**
883  * Copies state from one machine to this machine.
884  * (used for object copying).
885  *
886  * @param machine machine to copy from
887  *
888  */
889 void
891  ObjectState* state = machine.saveState();
892  loadState(state);
893  delete state;
894 }
895 
896 
897 /**
898  * Loads a Machine from the given ADF file.
899  *
900  * @param adfFileName The name of the file to load the ADF from.
901  * @return A machine instance.
902  * @exception Exception In case some error occured.
903  */
905 Machine::loadFromADF(const std::string& adfFileName) {
906  ADFSerializer serializer;
907  serializer.setSourceFile(adfFileName);
908 
909  return serializer.readMachine();
910 }
911 
912 void
913 Machine::writeToADF(const std::string& adfFileName) const {
914  ADFSerializer serializer;
915  serializer.setDestinationFile(adfFileName);
916  serializer.writeMachine(*this);
917 }
918 
919 /**
920  * Returns a hash string of the machine to determine quickly
921  * in case two machines are the same.
922  *
923  * The hash consists of a 32bit hash of the .adf xml data concat with
924  * the .adf data length as a hex string.
925  *
926  * @note The hash string is done based on the ADF XML format, thus does
927  * not account for changes that have the different XML output, but in
928  * reality are the same architecture (in the point of view of the
929  * programmer).
930  */
931 TCEString
932 Machine::hash() const {
933  ADFSerializer serializer;
934  std::string buffer;
935  serializer.setDestinationString(buffer);
936  serializer.writeMachine(*this);
937 
938  boost::hash<std::string> string_hasher;
939  size_t h = string_hasher(buffer);
940 
941  TCEString hash =
942  (Conversion::toHexString(buffer.length())).substr(2);
943 
944  hash += "_";
945  hash += (Conversion::toHexString(h)).substr(2);
946  return hash;
947 }
948 
949 /**
950  * Returns true if result value always needs to be written to GPR.
951  *
952  */
953 bool
955  return alwaysWriteResults_;
956 }
957 
958 /**
959  * Returns true if triggering make content of the register where result will
960  * be stored invalid.
961  *
962  */
963 bool
966 }
967 
968 /**
969  * Returns true if sequential order of FUs in ADF file is significant.
970  *
971  * In certain architectures (Cell SPU) the "relative order" of the function
972  * units matters when it comes to accessing same register by multiple operations
973  * in the same cycle.
974  *
975  */
976 bool
978  return fuOrdered_;
979 }
980 
981 /**
982  * Sets whether or not result must always be written to register.
983  */
984 void
986  alwaysWriteResults_ = result;
987 }
988 
989 /**
990  * Sets whether triggering invalidates register where result will be stored.
991  */
992 void
994  triggerInvalidatesResults_ = trigger;
995 }
996 
997 /* *
998  * Sets whether or not order of FUs in ADF file is significant.
999  *
1000  * In certain architectures (Cell SPU) the "relative order" of the function
1001  * units matters when it comes to accessing same register by multiple operations
1002  * in the same cycle.
1003  */
1004 void
1006  fuOrdered_ = order;
1007 }
1008 
1009 /**
1010  * Saves the state of each component in the given container and add the
1011  * created ObjectStates as children of the given parent ObjectState.
1012  *
1013  * @param container The container.
1014  * @param parent The parent ObjectState.
1015  */
1016 template <typename ContainerType>
1017 void
1018 Machine::saveComponentStates(ContainerType& container, ObjectState* parent) {
1019  for (int i = 0; i < container.count(); i++) {
1020  Serializable* component = container.item(i);
1021  parent->addChild(component->saveState());
1022  }
1023 }
1024 
1025 /**
1026  * Gets the maximum latency of any operation supported by this machine.
1027  */
1028 int
1030  int maxLatency = 0;
1032  for (int i = 0; i < fuNav.count(); i++) {
1033  FunctionUnit* fu = fuNav.item(i);
1034  int fuLatency = fu->maxLatency();
1035  if (fuLatency > maxLatency) {
1036  maxLatency = fuLatency;
1037  }
1038  }
1039  return maxLatency;
1040 }
1041 
1042 /**
1043  * Tells whether any FU in the machine has given operation or not
1044  *
1045  * @param opName name of the operation.
1046  */
1047 bool
1048 Machine::hasOperation(const TCEString& opName) const {
1050  for (int i = 0; i < fuNav.count(); i++) {
1051  FunctionUnit* fu = fuNav.item(i);
1052  if (fu->hasOperation(opName)) {
1053  return true;
1054  }
1055  }
1056  if (controlUnit()->hasOperation(opName)) {
1057  return true;
1058  }
1059  return false;
1060 }
1061 
1062 bool
1066  int fCount = fNav.count();
1067  if (fCount == 0) {
1068  return false;
1069  } else if (fCount != 6) {
1070  throw InvalidData(
1071  __FILE__, __LINE__, __func__,
1072  TCEString("Only Instruction format count 6 or 0 valid") +
1073  "Given machine has " + Conversion::toString(fCount) +
1074  " formats");
1075  }
1076  const std::vector<std::string> requiredFormats = {
1077  "riscv_r_type", "riscv_i_type", "riscv_s_type",
1078  "riscv_b_type", "riscv_u_type", "riscv_j_type"};
1079 
1080  for (const std::string& f : requiredFormats) {
1081  if (!fNav.hasItem(f)) {
1082  throw InvalidData(
1083  __FILE__, __LINE__, __func__,
1084  TCEString("Missing required instruction format: ") + f);
1085  }
1086  }
1087  return true;
1088 }
1089 }
TTAMachine::Machine::functionUnits_
ComponentContainer< FunctionUnit > functionUnits_
Contains all the function units of the machine.
Definition: Machine.hh:294
TTAMachine::Machine::removeFunctionUnit
virtual void removeFunctionUnit(FunctionUnit &unit)
Definition: Machine.cc:530
TTAMachine::Machine::maximumLatency
int maximumLatency() const
Definition: Machine.cc:1029
TTAMachine::Machine::bridges_
ComponentContainer< Bridge > bridges_
Contains all the bridges of the machine.
Definition: Machine.hh:298
ObjectState::hasAttribute
bool hasAttribute(const std::string &name) const
Definition: ObjectState.cc:205
TTAMachine::Machine::sockets_
ComponentContainer< Socket > sockets_
Contains all the sockets attached to the machine.
Definition: Machine.hh:286
TTAMachine::ControlUnit::unsetMachine
virtual void unsetMachine()
Definition: ControlUnit.cc:134
TTAMachine::Machine::hasOperation
bool hasOperation(const TCEString &opName) const
Definition: Machine.cc:1048
Serializable::saveState
virtual ObjectState * saveState() const =0
TTAMachine::Machine::deleteInstructionTemplate
virtual void deleteInstructionTemplate(InstructionTemplate &instrTempl)
Definition: Machine.cc:599
TTAMachine::Component::name
virtual TCEString name() const
Definition: MachinePart.cc:125
ObjectState::stringAttribute
std::string stringAttribute(const std::string &name) const
Definition: ObjectState.cc:249
TTAMachine::Machine::deleteImmediateSlot
virtual void deleteImmediateSlot(ImmediateSlot &slot)
Definition: Machine.cc:635
TTAMachine::Machine::setBusPosition
void setBusPosition(const Bus &bus, int newPosition)
Definition: Machine.cc:651
TTAMachine::FunctionUnit::OSNAME_FU
static const std::string OSNAME_FU
ObjectState name for function unit.
Definition: FunctionUnit.hh:117
XMLSerializer::setSourceFile
void setSourceFile(const std::string &fileName)
Definition: XMLSerializer.cc:115
TTAMachine::Bridge::loadState
virtual void loadState(const ObjectState *state)
Definition: Bridge.cc:264
TTAMachine::Machine::isRISCVMachine
bool isRISCVMachine() const
Definition: Machine.cc:1063
machine
TTAMachine::Machine * machine
the architecture definition of the estimated processor
Definition: EstimatorCmdLineUI.cc:59
TTAMachine::AddressSpace
Definition: AddressSpace.hh:51
TTAMachine::Machine::OSKEY_TRIGGER_INVALIDATES_OLD_RESULTS
static const std::string OSKEY_TRIGGER_INVALIDATES_OLD_RESULTS
ObjectState attribute key for trigger-invalidates-old-results.
Definition: Machine.hh:253
ObjectStateLoadingException
Definition: Exception.hh:551
TTAMachine::Bridge
Definition: Bridge.hh:51
TTAMachine::Machine::isUniversalMachine
virtual bool isUniversalMachine() const
Definition: Machine.cc:127
Serializable
Definition: Serializable.hh:44
TTAMachine::Bus::loadState
virtual void loadState(const ObjectState *state)
Definition: Bus.cc:816
OutOfRange
Definition: Exception.hh:320
TTAMachine::Machine::OSNAME_MACHINE
static const std::string OSNAME_MACHINE
ObjectState name for Machine.
Definition: Machine.hh:249
TTAMachine::Bus
Definition: Bus.hh:53
TTAMachine::ControlUnit::saveState
virtual ObjectState * saveState() const
Definition: ControlUnit.cc:322
TTAMachine::Machine::set64bits
void set64bits(bool flag)
Definition: Machine.hh:261
TTAMachine::Machine::removeBus
virtual void removeBus(Bus &bus)
Definition: Machine.cc:477
AddressSpace.hh
TTAMachine::Machine::addComponent
void addComponent(ContainerType &container, ComponentType &toAdd)
TTAMachine::Socket::loadState
virtual void loadState(const ObjectState *state)
Definition: Socket.cc:502
ObjectState
Definition: ObjectState.hh:59
TTAMachine::Machine::addUnit
void addUnit(Unit &unit)
Definition: Machine.cc:175
TTAMachine::Machine::triggerInvalidatesResults_
bool triggerInvalidatesResults_
Definition: Machine.hh:322
ImmediateUnit.hh
TTAMachine::Machine::Machine
Machine()
Definition: Machine.cc:76
DummyMachineTester.hh
TTAMachine::Machine::addOperationTriggeredFormat
virtual void addOperationTriggeredFormat(OperationTriggeredFormat &format)
Definition: Machine.cc:287
TTAMachine::Machine::unsetGlobalControl
virtual void unsetGlobalControl()
Definition: Machine.cc:565
TTAMachine::Machine::triggerInvalidatesResults
bool triggerInvalidatesResults() const
Definition: Machine.cc:964
TTAMachine::Machine::Navigator::count
int count() const
TTAMachine::Machine::addInstructionTemplate
virtual void addInstructionTemplate(InstructionTemplate &instrTempl)
Definition: Machine.cc:275
TTAMachine::FunctionUnit::maxLatency
virtual int maxLatency() const
Definition: FunctionUnit.cc:443
Socket.hh
Conversion::toString
static std::string toString(const T &source)
TTAMachine::Machine::instructionTemplates_
ComponentContainer< InstructionTemplate > instructionTemplates_
Contains all the instruction templates of the machine.
Definition: Machine.hh:288
TTAMachine::Machine::hash
TCEString hash() const
Definition: Machine.cc:932
TTAMachine::AddressSpace::OSNAME_ADDRESS_SPACE
static const std::string OSNAME_ADDRESS_SPACE
ObjectState name for AddressSpace.
Definition: AddressSpace.hh:84
TTAMachine::Machine::loadState
virtual void loadState(const ObjectState *state)
Definition: Machine.cc:728
TTAMachine::Machine::addImmediateUnit
virtual void addImmediateUnit(ImmediateUnit &unit)
Definition: Machine.cc:224
TTAMachine::Machine::OSKEY_ALWAYS_WRITE_BACK_RESULTS
static const std::string OSKEY_ALWAYS_WRITE_BACK_RESULTS
ObjectState attribute key for always-write-back-results.
Definition: Machine.hh:251
TTAMachine::Machine::deleteAddressSpace
virtual void deleteAddressSpace(AddressSpace &as)
Definition: Machine.cc:623
TTAMachine::InstructionTemplate
Definition: InstructionTemplate.hh:49
TTAMachine::RegisterFile::loadState
virtual void loadState(const ObjectState *state)
Definition: RegisterFile.cc:433
TTAMachine::Machine::removeUnit
virtual void removeUnit(Unit &unit)
Definition: Machine.cc:505
TTAMachine::Machine::alwaysWriteResults
bool alwaysWriteResults() const
Definition: Machine.cc:954
TTAMachine::FunctionUnit
Definition: FunctionUnit.hh:55
TTAMachine::Bus::OSNAME_BUS
static const std::string OSNAME_BUS
ObjectState name for Bus ObjectState.
Definition: Bus.hh:116
DummyMachineTester
Definition: DummyMachineTester.hh:41
TTAMachine::Machine::operationTriggeredFormatNavigator
virtual OperationTriggeredFormatNavigator operationTriggeredFormatNavigator() const
Definition: Machine.cc:439
TTAMachine::Machine::addRegisterFile
virtual void addRegisterFile(RegisterFile &unit)
Definition: Machine.cc:236
TTAMachine::Machine::OSKEY_FUNCTION_UNITS_ORDERED
static const std::string OSKEY_FUNCTION_UNITS_ORDERED
ObjectState attribute key for function units ordered in order of their sequential presence in ADF.
Definition: Machine.hh:256
Segment.hh
TTAMachine::Machine::immediateUnits_
ComponentContainer< ImmediateUnit > immediateUnits_
Contains all the immediate units of the machine.
Definition: Machine.hh:292
IllegalParameters
Definition: Exception.hh:113
TTAMachine::Machine::controlUnit
virtual ControlUnit * controlUnit() const
Definition: Machine.cc:345
TTAMachine::Machine::addRegisteredComponent
void addRegisteredComponent(ContainerType &container, ComponentType &toAdd)
TTAMachine::Unit
Definition: Unit.hh:51
InvalidData
Definition: Exception.hh:149
TTAMachine::Machine::bridgeNavigator
virtual BridgeNavigator bridgeNavigator() const
Definition: Machine.cc:404
TTAMachine::Machine::immediateUnitNavigator
virtual ImmediateUnitNavigator immediateUnitNavigator() const
Definition: Machine.cc:416
TTAMachine::ControlUnit
Definition: ControlUnit.hh:50
InstructionTemplate.hh
TTAMachine::Machine::machineTester
MachineTester & machineTester() const
Definition: Machine.cc:671
ImmediateSlot.hh
TTAMachine::Machine::Navigator::hasItem
bool hasItem(const std::string &name) const
ADFSerializer
Definition: ADFSerializer.hh:49
TTAMachine::ImmediateSlot::OSNAME_IMMEDIATE_SLOT
static const std::string OSNAME_IMMEDIATE_SLOT
ObjectState name for ImmediateSlot.
Definition: ImmediateSlot.hh:60
Application.hh
XMLSerializer::setDestinationFile
void setDestinationFile(const std::string &fileName)
Definition: XMLSerializer.cc:142
__func__
#define __func__
Definition: Application.hh:67
ObjectState.hh
TTAMachine::Machine::removeComponent
void removeComponent(ContainerType &container, ComponentType &toRemove)
TTAMachine::Machine::registerFiles_
ComponentContainer< RegisterFile > registerFiles_
Contains all the register files of the machine.
Definition: Machine.hh:290
TTAMachine::Machine::functionUnitNavigator
virtual FunctionUnitNavigator functionUnitNavigator() const
Definition: Machine.cc:380
TTAMachine::OperationTriggeredFormat::OSNAME_FORMAT
static const std::string OSNAME_FORMAT
Definition: OperationTriggeredFormat.hh:72
TTAMachine::Machine::alwaysWriteResults_
bool alwaysWriteResults_
Definition: Machine.hh:319
TTAMachine::Component
Definition: MachinePart.hh:90
TTAMachine::Socket
Definition: Socket.hh:53
TTAMachine::Machine::removeImmediateUnit
virtual void removeImmediateUnit(ImmediateUnit &unit)
Definition: Machine.cc:542
TTAMachine::ImmediateUnit::OSNAME_IMMEDIATE_UNIT
static const std::string OSNAME_IMMEDIATE_UNIT
ObjectState name for ImmediateUnit.
Definition: ImmediateUnit.hh:75
TTAMachine::Machine::littleEndian_
bool littleEndian_
Definition: Machine.hh:328
Guard.hh
TTAMachine::Component::OSKEY_NAME
static const std::string OSKEY_NAME
ObjectState attribute key for the name of the component.
Definition: MachinePart.hh:137
ObjectState::child
ObjectState * child(int index) const
Definition: ObjectState.cc:471
ObjectState::addChild
void addChild(ObjectState *child)
Definition: ObjectState.cc:376
TTAMachine::ControlUnit::loadState
virtual void loadState(const ObjectState *state)
Definition: ControlUnit.cc:351
ObjectState::childCount
int childCount() const
TTAMachine::Machine::deleteBridge
virtual void deleteBridge(Bridge &bridge)
Definition: Machine.cc:587
TTAMachine::Machine::addAddressSpace
virtual void addAddressSpace(AddressSpace &as)
Definition: Machine.cc:248
TTAMachine::Machine::removeRegisterFile
virtual void removeRegisterFile(RegisterFile &unit)
Definition: Machine.cc:554
TTAMachine::Machine::saveState
virtual ObjectState * saveState() const
Definition: Machine.cc:686
TTAMachine::FunctionUnit::hasOperation
virtual bool hasOperation(const std::string &name) const
Definition: FunctionUnit.cc:330
Machine.hh
TTAMachine::RegisterFile::OSNAME_REGISTER_FILE
static const std::string OSNAME_REGISTER_FILE
ObjectState name for RegisterFile.
Definition: RegisterFile.hh:94
Exception
Definition: Exception.hh:54
TTAMachine::Machine::doValidityChecks_
bool doValidityChecks_
Tells whether to do validity checks or not.
Definition: Machine.hh:308
TTAMachine::Machine::addressSpaceNavigator
virtual AddressSpaceNavigator addressSpaceNavigator() const
Definition: Machine.cc:392
Bus.hh
TTAMachine::Machine::socketNavigator
virtual SocketNavigator socketNavigator() const
Definition: Machine.cc:368
TTAMachine::Machine::operationTriggeredFormats_
ComponentContainer< OperationTriggeredFormat > operationTriggeredFormats_
Contains all the OTA Formats of the machine.
Definition: Machine.hh:302
TTAMachine::Machine::addBus
virtual void addBus(Bus &bus)
Definition: Machine.cc:139
ObjectState::name
std::string name() const
TTAMachine::Machine::immediateSlotNavigator
virtual ImmediateSlotNavigator immediateSlotNavigator() const
Definition: Machine.cc:462
TTAMachine::Socket::OSNAME_SOCKET
static const std::string OSNAME_SOCKET
ObjectState name for socket.
Definition: Socket.hh:100
TTAMachine::OperationTriggeredFormat
Definition: OperationTriggeredFormat.hh:44
TTAMachine::Machine::writeToADF
void writeToADF(const std::string &adfFileName) const
Definition: Machine.cc:913
Exception::errorMessage
std::string errorMessage() const
Definition: Exception.cc:123
Conversion::toHexString
static std::string toHexString(T source, std::size_t digits=0, bool include0x=true)
TTAMachine::Machine::setGlobalControl
virtual void setGlobalControl(ControlUnit &unit)
Definition: Machine.cc:317
TTAMachine::Machine::EMPTY_ITEMP_NAME_
const std::string EMPTY_ITEMP_NAME_
Definition: Machine.hh:315
IllegalRegistration
Definition: Exception.hh:532
MachineTester.hh
TTAMachine::Machine::addBridge
virtual void addBridge(Bridge &bridge)
Definition: Machine.cc:263
XMLSerializer::setDestinationString
void setDestinationString(std::string &destination)
Definition: XMLSerializer.cc:156
TTAMachine::Machine::registerFileNavigator
virtual RegisterFileNavigator registerFileNavigator() const
Definition: Machine.cc:450
TTAMachine::Machine::dummyMachineTester_
DummyMachineTester * dummyMachineTester_
Dummy machine tester for the machine.
Definition: Machine.hh:312
TTAMachine::ControlUnit::setMachine
virtual void setMachine(Machine &mach)
Definition: ControlUnit.cc:119
TTAMachine::Machine::deleteComponent
void deleteComponent(ContainerType &container, ComponentType &toDelete)
ADFSerializer.hh
TTAMachine::Bridge::OSNAME_BRIDGE
static const std::string OSNAME_BRIDGE
ObjectState name for bridge.
Definition: Bridge.hh:70
TTAMachine::Machine::addFunctionUnit
virtual void addFunctionUnit(FunctionUnit &unit)
Definition: Machine.cc:202
false
find Finds info of the inner loops in the false
Definition: InnerLoopFinder.cc:81
TTAMachine::ImmediateUnit::loadState
virtual void loadState(const ObjectState *state)
Definition: ImmediateUnit.cc:261
TTAMachine::Component::machine
virtual Machine * machine() const
RegisterFile.hh
TTAMachine::Machine::addressSpaces_
ComponentContainer< AddressSpace > addressSpaces_
Contains all the address spaces of the machine.
Definition: Machine.hh:296
TTAMachine::Machine::addImmediateSlot
virtual void addImmediateSlot(ImmediateSlot &slot)
Definition: Machine.cc:299
TTAMachine::Machine::setLittleEndian
void setLittleEndian(bool flag)
Definition: Machine.hh:259
TCEString
Definition: TCEString.hh:53
ObjectState::boolAttribute
bool boolAttribute(const std::string &name) const
Definition: ObjectState.cc:338
FUPort.hh
ControlUnit.hh
TTAMachine::Machine::busNavigator
virtual BusNavigator busNavigator() const
Definition: Machine.cc:356
ComponentAlreadyExists
Definition: Exception.hh:510
ADFSerializer::writeMachine
void writeMachine(const TTAMachine::Machine &machine)
Definition: ADFSerializer.cc:259
TTAMachine::Machine::copyFromMachine
virtual void copyFromMachine(Machine &machine)
Definition: Machine.cc:890
TTAMachine::Machine::machineTester_
MachineTester * machineTester_
Machine tester for the machine.
Definition: Machine.hh:310
TTAMachine::FunctionUnit::loadState
virtual void loadState(const ObjectState *state)
Definition: FunctionUnit.cc:706
ADFSerializer::readMachine
TTAMachine::Machine * readMachine()
Definition: ADFSerializer.cc:275
TTAMachine::Machine::busses_
ComponentContainer< Bus > busses_
Contains all the busses attached to the machine.
Definition: Machine.hh:284
TTAMachine::Machine::removeSocket
virtual void removeSocket(Socket &socket)
Definition: Machine.cc:490
TTAMachine::Machine::Navigator::item
ComponentType * item(int index) const
OperationTriggeredFormat.hh
TTAMachine::Machine::isFUOrdered
bool isFUOrdered() const
Definition: Machine.cc:977
TTAMachine::RegisterFile
Definition: RegisterFile.hh:47
TTAMachine::ControlUnit::OSNAME_CONTROL_UNIT
static const std::string OSNAME_CONTROL_UNIT
ObjectState name for ControlUnit.
Definition: ControlUnit.hh:82
TTAMachine::Machine::setTriggerInvalidatesResults
void setTriggerInvalidatesResults(bool)
Definition: Machine.cc:993
TTAMachine::Machine::~Machine
virtual ~Machine()
Definition: Machine.cc:114
TTAMachine
Definition: Assembler.hh:48
TTAMachine::Machine::setFUOrdered
void setFUOrdered(bool)
Definition: Machine.cc:1005
TTAMachine::Machine::instructionTemplateNavigator
virtual InstructionTemplateNavigator instructionTemplateNavigator() const
Definition: Machine.cc:428
MachineTester
Definition: MachineTester.hh:46
TTAMachine::Machine::setAlwaysWriteResults
void setAlwaysWriteResults(bool)
Definition: Machine.cc:985
TTAMachine::Machine::immediateSlots_
ComponentContainer< ImmediateSlot > immediateSlots_
Contains all the immediate slots of the machine.
Definition: Machine.hh:300
TTAMachine::Machine::Navigator
Definition: Machine.hh:186
TTAMachine::Machine::addSocket
virtual void addSocket(Socket &socket)
Definition: Machine.cc:157
TTAMachine::Machine::controlUnit_
ControlUnit * controlUnit_
Global control unit.
Definition: Machine.hh:305
TTAMachine::ImmediateSlot
Definition: ImmediateSlot.hh:44
ObjectState::setAttribute
void setAttribute(const std::string &name, const std::string &value)
Definition: ObjectState.cc:100
Bridge.hh
TTAMachine::InstructionTemplate::OSNAME_INSTRUCTION_TEMPLATE
static const std::string OSNAME_INSTRUCTION_TEMPLATE
ObjectState name for instruction template.
Definition: InstructionTemplate.hh:90
TTAMachine::Machine::deleteOperationTriggeredFormat
virtual void deleteOperationTriggeredFormat(OperationTriggeredFormat &format)
Definition: Machine.cc:611
TTAMachine::Machine
Definition: Machine.hh:73
FunctionUnit.hh
TTAMachine::Machine::bitness64_
bool bitness64_
Definition: Machine.hh:330
TTAMachine::Machine::fuOrdered_
bool fuOrdered_
Definition: Machine.hh:326
ContainerTools.hh
TTAMachine::Machine::loadFromADF
static Machine * loadFromADF(const std::string &adfFileName)
Definition: Machine.cc:905
TTAMachine::Machine::saveComponentStates
static void saveComponentStates(ContainerType &container, ObjectState *parent)
Definition: Machine.cc:1018
TTAMachine::ImmediateUnit
Definition: ImmediateUnit.hh:50