OpenASIP 2.2
Loading...
Searching...
No Matches
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"
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
60using std::string;
61using std::set;
62
63namespace TTAMachine {
64
65// initialization of static data members
66const string Machine::OSNAME_MACHINE = "machine";
68 = "always-write-back";
70 = "trigger-invalidates";
71const 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 */
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
126bool
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 */
138void
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 */
156void
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 */
174void
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 */
201void
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 */
223void
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 */
235void
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 */
247void
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 */
262void
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 */
274void
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 */
286void
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 */
298void
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 */
316void
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 */
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 */
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 */
476void
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 */
489void
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 */
504void
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) {
512 } else if (iu != NULL) {
514 } else if (rf != NULL) {
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 */
529void
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 */
541void
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 */
553void
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 */
564void
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 */
586void
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 */
598void
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 */
610void
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 */
622void
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 */
634void
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 */
650void
651Machine::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 */
727void
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
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 }
810 }
811
812 } catch (const Exception& e) {
813 if (toAdd != NULL) {
814 delete toAdd;
815 }
816 throw ObjectStateLoadingException(__FILE__, __LINE__, procName,
817 e.errorMessage());
818 }
819
820 // load states of each component
821 try {
822 for (int i = 0; i < state->childCount(); i++) {
823 ObjectState* child = state->child(i);
824 string name = child->stringAttribute(Component::OSKEY_NAME);
825 if (child->name() == Bus::OSNAME_BUS) {
826 BusNavigator busNav = busNavigator();
827 Bus* bus = busNav.item(name);
828 bus->loadState(child);
829 } else if (child->name() == Socket::OSNAME_SOCKET) {
830 SocketNavigator socketNav = socketNavigator();
831 Socket* socket = socketNav.item(name);
832 socket->loadState(child);
833 } else if (child->name() == Bridge::OSNAME_BRIDGE) {
834 BridgeNavigator bridgeNav = bridgeNavigator();
835 Bridge* bridge = bridgeNav.item(name);
836 bridge->loadState(child);
837 } else if (child->name() == RegisterFile::OSNAME_REGISTER_FILE) {
839 RegisterFile* rf = rfNav.item(name);
840 rf->loadState(child);
841 } else if (child->name() == FunctionUnit::OSNAME_FU) {
843 FunctionUnit* fu = fuNav.item(name);
844 fu->loadState(child);
845 } else if (child->name() ==
848 ImmediateUnit* iu = iuNav.item(name);
849 iu->loadState(child);
850 } else if (child->name() ==
852 ControlUnit* cu = controlUnit();
853 cu->loadState(child);
854 } else if (child->name() ==
856 // instruction template loads its state completely
857 new InstructionTemplate(child, *this);
858 } else if (
860 new OperationTriggeredFormat(child, *this);
861 }
862 }
863 } catch (const Exception& e) {
864 throw ObjectStateLoadingException(__FILE__, __LINE__, procName,
865 e.errorMessage());
866 }
867
868 // create an empty instruction template if there is no instruction
869 // templates
871 if (itNav.count() == 0) {
873 }
874}
875
876/**
877 * Copies state from one machine to this machine.
878 * (used for object copying).
879 *
880 * @param machine machine to copy from
881 *
882 */
883void
885 ObjectState* state = machine.saveState();
886 loadState(state);
887 delete state;
888}
889
890
891/**
892 * Loads a Machine from the given ADF file.
893 *
894 * @param adfFileName The name of the file to load the ADF from.
895 * @return A machine instance.
896 * @exception Exception In case some error occured.
897 */
899Machine::loadFromADF(const std::string& adfFileName) {
900 ADFSerializer serializer;
901 serializer.setSourceFile(adfFileName);
902
903 return serializer.readMachine();
904}
905
906void
907Machine::writeToADF(const std::string& adfFileName) const {
908 ADFSerializer serializer;
909 serializer.setDestinationFile(adfFileName);
910 serializer.writeMachine(*this);
911}
912
913/**
914 * Returns a hash string of the machine to determine quickly
915 * in case two machines are the same.
916 *
917 * The hash consists of a 32bit hash of the .adf xml data concat with
918 * the .adf data length as a hex string.
919 *
920 * @note The hash string is done based on the ADF XML format, thus does
921 * not account for changes that have the different XML output, but in
922 * reality are the same architecture (in the point of view of the
923 * programmer).
924 */
927 ADFSerializer serializer;
928 std::string buffer;
929 serializer.setDestinationString(buffer);
930 serializer.writeMachine(*this);
931
932 boost::hash<std::string> string_hasher;
933 size_t h = string_hasher(buffer);
934
936 (Conversion::toHexString(buffer.length())).substr(2);
937
938 hash += "_";
939 hash += (Conversion::toHexString(h)).substr(2);
940 return hash;
941}
942
943/**
944 * Returns true if result value always needs to be written to GPR.
945 *
946 */
947bool
951
952/**
953 * Returns true if triggering make content of the register where result will
954 * be stored invalid.
955 *
956 */
957bool
961
962/**
963 * Returns true if sequential order of FUs in ADF file is significant.
964 *
965 * In certain architectures (Cell SPU) the "relative order" of the function
966 * units matters when it comes to accessing same register by multiple operations
967 * in the same cycle.
968 *
969 */
970bool
972 return fuOrdered_;
973}
974
975/**
976 * Sets whether or not result must always be written to register.
977 */
978void
982
983/**
984 * Sets whether triggering invalidates register where result will be stored.
985 */
986void
990
991/* *
992 * Sets whether or not order of FUs in ADF file is significant.
993 *
994 * In certain architectures (Cell SPU) the "relative order" of the function
995 * units matters when it comes to accessing same register by multiple operations
996 * in the same cycle.
997 */
998void
1000 fuOrdered_ = order;
1001}
1002
1003/**
1004 * Saves the state of each component in the given container and add the
1005 * created ObjectStates as children of the given parent ObjectState.
1006 *
1007 * @param container The container.
1008 * @param parent The parent ObjectState.
1009 */
1010template <typename ContainerType>
1011void
1012Machine::saveComponentStates(ContainerType& container, ObjectState* parent) {
1013 for (int i = 0; i < container.count(); i++) {
1014 Serializable* component = container.item(i);
1015 parent->addChild(component->saveState());
1016 }
1017}
1018
1019/**
1020 * Gets the maximum latency of any operation supported by this machine.
1021 */
1022int
1024 int maxLatency = 0;
1026 for (int i = 0; i < fuNav.count(); i++) {
1027 FunctionUnit* fu = fuNav.item(i);
1028 int fuLatency = fu->maxLatency();
1029 if (fuLatency > maxLatency) {
1030 maxLatency = fuLatency;
1031 }
1032 }
1033 return maxLatency;
1034}
1035
1036/**
1037 * Tells whether any FU in the machine has given operation or not
1038 *
1039 * @param opName name of the operation.
1040 */
1041bool
1042Machine::hasOperation(const TCEString& opName) const {
1044 for (int i = 0; i < fuNav.count(); i++) {
1045 FunctionUnit* fu = fuNav.item(i);
1046 if (fu->hasOperation(opName)) {
1047 return true;
1048 }
1049 }
1050 if (controlUnit()->hasOperation(opName)) {
1051 return true;
1052 }
1053 return false;
1054}
1055
1056bool
1060 int fCount = fNav.count();
1061 if (fCount == 0) {
1062 return false;
1063 }
1064 const std::vector<std::string> requiredFormats = {
1065 "riscv_r_type", "riscv_i_type", "riscv_s_type",
1066 "riscv_b_type", "riscv_u_type", "riscv_j_type"};
1067
1068 for (const std::string& f : requiredFormats) {
1069 if (!fNav.hasItem(f)) {
1070 throw InvalidData(
1071 __FILE__, __LINE__, __func__,
1072 TCEString("Missing required instruction format: ") + f);
1073 }
1074 }
1075 return true;
1076}
1077}
#define __func__
TTAMachine::Machine * machine
the architecture definition of the estimated processor
find Finds info of the inner loops in the false
void writeMachine(const TTAMachine::Machine &machine)
TTAMachine::Machine * readMachine()
static std::string toHexString(T source, std::size_t digits=0, bool include0x=true)
std::string errorMessage() const
Definition Exception.cc:123
bool hasAttribute(const std::string &name) const
void setAttribute(const std::string &name, const std::string &value)
ObjectState * child(int index) const
void addChild(ObjectState *child)
std::string stringAttribute(const std::string &name) const
bool boolAttribute(const std::string &name) const
std::string name() const
int childCount() const
virtual ObjectState * saveState() const =0
static const std::string OSNAME_ADDRESS_SPACE
ObjectState name for AddressSpace.
static const std::string OSNAME_BRIDGE
ObjectState name for bridge.
Definition Bridge.hh:70
virtual void loadState(const ObjectState *state)
Definition Bridge.cc:264
virtual void loadState(const ObjectState *state)
Definition Bus.cc:816
static const std::string OSNAME_BUS
ObjectState name for Bus ObjectState.
Definition Bus.hh:116
virtual Machine * machine() const
static const std::string OSKEY_NAME
ObjectState attribute key for the name of the component.
virtual TCEString name() const
virtual ObjectState * saveState() const
static const std::string OSNAME_CONTROL_UNIT
ObjectState name for ControlUnit.
virtual void unsetMachine()
virtual void setMachine(Machine &mach)
virtual void loadState(const ObjectState *state)
virtual void loadState(const ObjectState *state)
virtual int maxLatency() const
virtual bool hasOperation(const std::string &name) const
static const std::string OSNAME_FU
ObjectState name for function unit.
static const std::string OSNAME_IMMEDIATE_SLOT
ObjectState name for ImmediateSlot.
virtual void loadState(const ObjectState *state)
static const std::string OSNAME_IMMEDIATE_UNIT
ObjectState name for ImmediateUnit.
static const std::string OSNAME_INSTRUCTION_TEMPLATE
ObjectState name for instruction template.
ComponentType * item(int index) const
bool hasItem(const std::string &name) const
bool triggerInvalidatesResults() const
Definition Machine.cc:958
ComponentContainer< RegisterFile > registerFiles_
Contains all the register files of the machine.
Definition Machine.hh:290
void setLittleEndian(bool flag)
Definition Machine.hh:259
virtual void deleteOperationTriggeredFormat(OperationTriggeredFormat &format)
Definition Machine.cc:611
virtual ImmediateSlotNavigator immediateSlotNavigator() const
Definition Machine.cc:462
virtual RegisterFileNavigator registerFileNavigator() const
Definition Machine.cc:450
virtual FunctionUnitNavigator functionUnitNavigator() const
Definition Machine.cc:380
virtual BridgeNavigator bridgeNavigator() const
Definition Machine.cc:404
virtual InstructionTemplateNavigator instructionTemplateNavigator() const
Definition Machine.cc:428
virtual void deleteInstructionTemplate(InstructionTemplate &instrTempl)
Definition Machine.cc:599
virtual SocketNavigator socketNavigator() const
Definition Machine.cc:368
static void saveComponentStates(ContainerType &container, ObjectState *parent)
Definition Machine.cc:1012
void setTriggerInvalidatesResults(bool)
Definition Machine.cc:987
const std::string EMPTY_ITEMP_NAME_
Definition Machine.hh:315
MachineTester & machineTester() const
Definition Machine.cc:671
virtual void copyFromMachine(Machine &machine)
Definition Machine.cc:884
DummyMachineTester * dummyMachineTester_
Dummy machine tester for the machine.
Definition Machine.hh:312
void deleteComponent(ContainerType &container, ComponentType &toDelete)
virtual void addInstructionTemplate(InstructionTemplate &instrTempl)
Definition Machine.cc:275
bool hasOperation(const TCEString &opName) const
Definition Machine.cc:1042
MachineTester * machineTester_
Machine tester for the machine.
Definition Machine.hh:310
virtual void removeBus(Bus &bus)
Definition Machine.cc:477
bool alwaysWriteResults() const
Definition Machine.cc:948
virtual ImmediateUnitNavigator immediateUnitNavigator() const
Definition Machine.cc:416
ComponentContainer< Bridge > bridges_
Contains all the bridges of the machine.
Definition Machine.hh:298
static const std::string OSKEY_ALWAYS_WRITE_BACK_RESULTS
ObjectState attribute key for always-write-back-results.
Definition Machine.hh:251
void addComponent(ContainerType &container, ComponentType &toAdd)
virtual BusNavigator busNavigator() const
Definition Machine.cc:356
virtual void addFunctionUnit(FunctionUnit &unit)
Definition Machine.cc:202
virtual AddressSpaceNavigator addressSpaceNavigator() const
Definition Machine.cc:392
virtual void addBus(Bus &bus)
Definition Machine.cc:139
void set64bits(bool flag)
Definition Machine.hh:261
virtual void addBridge(Bridge &bridge)
Definition Machine.cc:263
virtual ControlUnit * controlUnit() const
Definition Machine.cc:345
TCEString hash() const
Definition Machine.cc:926
ComponentContainer< ImmediateUnit > immediateUnits_
Contains all the immediate units of the machine.
Definition Machine.hh:292
ComponentContainer< ImmediateSlot > immediateSlots_
Contains all the immediate slots of the machine.
Definition Machine.hh:300
virtual bool isUniversalMachine() const
Definition Machine.cc:127
virtual void addImmediateUnit(ImmediateUnit &unit)
Definition Machine.cc:224
void writeToADF(const std::string &adfFileName) const
Definition Machine.cc:907
virtual void addRegisterFile(RegisterFile &unit)
Definition Machine.cc:236
static const std::string OSKEY_TRIGGER_INVALIDATES_OLD_RESULTS
ObjectState attribute key for trigger-invalidates-old-results.
Definition Machine.hh:253
ControlUnit * controlUnit_
Global control unit.
Definition Machine.hh:305
virtual void loadState(const ObjectState *state)
Definition Machine.cc:728
virtual void unsetGlobalControl()
Definition Machine.cc:565
virtual void deleteBridge(Bridge &bridge)
Definition Machine.cc:587
ComponentContainer< OperationTriggeredFormat > operationTriggeredFormats_
Contains all the OTA Formats of the machine.
Definition Machine.hh:302
ComponentContainer< FunctionUnit > functionUnits_
Contains all the function units of the machine.
Definition Machine.hh:294
ComponentContainer< AddressSpace > addressSpaces_
Contains all the address spaces of the machine.
Definition Machine.hh:296
void addRegisteredComponent(ContainerType &container, ComponentType &toAdd)
virtual ObjectState * saveState() const
Definition Machine.cc:686
virtual void deleteAddressSpace(AddressSpace &as)
Definition Machine.cc:623
void setBusPosition(const Bus &bus, int newPosition)
Definition Machine.cc:651
ComponentContainer< InstructionTemplate > instructionTemplates_
Contains all the instruction templates of the machine.
Definition Machine.hh:288
virtual void removeSocket(Socket &socket)
Definition Machine.cc:490
virtual ~Machine()
Definition Machine.cc:114
virtual void setGlobalControl(ControlUnit &unit)
Definition Machine.cc:317
void removeComponent(ContainerType &container, ComponentType &toRemove)
bool triggerInvalidatesResults_
Definition Machine.hh:322
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
virtual void addImmediateSlot(ImmediateSlot &slot)
Definition Machine.cc:299
virtual void removeFunctionUnit(FunctionUnit &unit)
Definition Machine.cc:530
static const std::string OSNAME_MACHINE
ObjectState name for Machine.
Definition Machine.hh:249
virtual OperationTriggeredFormatNavigator operationTriggeredFormatNavigator() const
Definition Machine.cc:439
virtual void removeUnit(Unit &unit)
Definition Machine.cc:505
bool doValidityChecks_
Tells whether to do validity checks or not.
Definition Machine.hh:308
virtual void removeImmediateUnit(ImmediateUnit &unit)
Definition Machine.cc:542
void setAlwaysWriteResults(bool)
Definition Machine.cc:979
void setFUOrdered(bool)
Definition Machine.cc:999
virtual void addOperationTriggeredFormat(OperationTriggeredFormat &format)
Definition Machine.cc:287
ComponentContainer< Socket > sockets_
Contains all the sockets attached to the machine.
Definition Machine.hh:286
ComponentContainer< Bus > busses_
Contains all the busses attached to the machine.
Definition Machine.hh:284
static Machine * loadFromADF(const std::string &adfFileName)
Definition Machine.cc:899
virtual void addAddressSpace(AddressSpace &as)
Definition Machine.cc:248
int maximumLatency() const
Definition Machine.cc:1023
virtual void addSocket(Socket &socket)
Definition Machine.cc:157
void addUnit(Unit &unit)
Definition Machine.cc:175
bool isRISCVMachine() const
Definition Machine.cc:1057
virtual void removeRegisterFile(RegisterFile &unit)
Definition Machine.cc:554
virtual void deleteImmediateSlot(ImmediateSlot &slot)
Definition Machine.cc:635
bool isFUOrdered() const
Definition Machine.cc:971
virtual void loadState(const ObjectState *state)
static const std::string OSNAME_REGISTER_FILE
ObjectState name for RegisterFile.
static const std::string OSNAME_SOCKET
ObjectState name for socket.
Definition Socket.hh:100
virtual void loadState(const ObjectState *state)
Definition Socket.cc:502
void setSourceFile(const std::string &fileName)
void setDestinationFile(const std::string &fileName)
void setDestinationString(std::string &destination)