OpenASIP 2.2
Loading...
Searching...
No Matches
MachineImplementation.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 MachineImplementation.cc
26 *
27 * Implementation of MachineImplementation class.
28 *
29 * @author Lasse Laasonen 2005 (lasse.laasonen-no.spam-tut.fi)
30 * @note rating: red
31 */
32
33#include <string>
34#include <vector>
35
38#include "SequenceTools.hh"
39#include "FileSystem.hh"
40#include "IDFSerializer.hh"
41#include "ObjectState.hh"
42
43using std::string;
44using std::vector;
45
46namespace IDF {
47
49 "mach_impl";
50const std::string MachineImplementation::OSKEY_SOURCE_IDF = "source_idf";
52 "ic_dec_plugin";
54 "ic_dec_name";
56 "ic_dec_file";
58 "ic_dec_parameter";
60 "ic_dec_parameter_name";
62 "ic_dec_parameter_value";
64 "ic_dec_hdb";
65
67 "decompressor_file";
68const std::string MachineImplementation::OSNAME_FU_GENERATED = "fu_generated";
70 "fu_impls";
72 "rf_impls";
74 "iu_impls";
76 "bus_impls";
78 "socket_impls";
79
80
81/**
82 * The constructor.
83 */
85 icDecoderPluginName_(""), icDecoderPluginFile_(""), icDecoderHDB_(""),
86 decompressorFile_(""), sourceIDF_("") {
87}
88
89/**
90 * The constructor.
91 *
92 * Loads the state of the object from the given ObjectState tree.
93 *
94 * @param state The ObjectState tree.
95 * @exception ObjectStateLoadingException If the given ObjectState tree is
96 * invalid.
97 */
99 : icDecoderPluginName_(""),
100 icDecoderPluginFile_(""),
101 icDecoderHDB_(""),
102 decompressorFile_(""),
103 sourceIDF_("") {
104 loadState(state);
105}
106
107/**
108 * The destructor.
109 */
113
114
115/**
116 * Returns the path to the source IDF file.
117 *
118 * @return The source IDF.
119 */
120std::string
124
125
126/**
127 * Returns the name of the IC/decoder plugin.
128 *
129 * @return The name of the IC/decoder plugin.
130 */
131std::string
135
136/**
137 * Returns true in case IC/decoder name is set.
138 *
139 * @return True in case IC/decoder name is set.
140 */
141bool
145
146/**
147 * Returns the absolute path to the IC/decoder plugin file given in IDF.
148 *
149 * @return The absolute path to the IC/decoder plugin file.
150 * @exception FileNotFound If the file is not found in search paths.
151 */
152std::string
154 vector<string> paths = Environment::icDecoderPluginPaths();
155 paths.insert(paths.begin(), FileSystem::directoryOfPath(sourceIDF_));
156 TCEString expandedPath(icDecoderPluginFile_);
157 expandedPath.replaceString("tce:", "");
158 expandedPath = FileSystem::expandTilde(expandedPath);
159 return FileSystem::findFileInSearchPaths(paths, expandedPath);
160}
161
162/**
163 * Returns true in case IC/decoder file is set.
164 *
165 * @return True in case IC/decoder file is set.
166 */
167bool
171
172/**
173 * Returns the absolute path to the IC/decoder HDB file.
174 *
175 * @return the absolute path to the IC/decoder HDB file.
176 * @exception FileNotFound If the file is not found in search paths.
177 */
178std::string
180 vector<string> paths = Environment::hdbPaths();
181 paths.insert(paths.begin(), FileSystem::directoryOfPath(sourceIDF_));
182 TCEString expandedPath(icDecoderHDB_);
183 expandedPath.replaceString("tce:", "");
184 return FileSystem::findFileInSearchPaths(paths, expandedPath);
185}
186
187/**
188 * Returns true in case IC/decoder HDB file is set.
189 *
190 * @return True in case IC/decoder HDB file is set.
191 */
192bool
196
197
198/**
199 * Returns the absolute path to the the decompressor definition file.
200 *
201 * @return The absolute path to the decompressor definition file.
202 * @exception FileNotFound If the file is not found in search paths.
203 */
204std::string
206 vector<string> paths = Environment::decompressorPaths();
207 paths.insert(paths.begin(), FileSystem::directoryOfPath(sourceIDF_));
208 TCEString expandedPath(decompressorFile_);
209 expandedPath.replaceString("tce:", "");
210 return FileSystem::findFileInSearchPaths(paths, expandedPath);
211}
212
213/**
214 * Tells whether the decompressor definition file is given in IDF.
215 *
216 * @return True if the file is given, otherwise false.
217 */
218bool
222
223
224/**
225 * Tells whether there is an implementation for the given FU defined.
226 *
227 * @param unitName Name of the FU.
228 * @return True if there is an implementation, otherwise false.
229 */
230bool
232 const std::string& unitName) const {
233
234 return findImplementation(fuImplementations_, unitName) != NULL;
235}
236
237
238/**
239 * Tells whether there is an implementation for the given RF defined.
240 *
241 * @param unitName Name of the RF.
242 * @return True if there is an implementation, otherwise false.
243 */
244bool
246 const std::string& unitName) const {
247
248 return findImplementation(rfImplementations_, unitName) != NULL;
249}
250
251
252/**
253 * Tells whether there is an implementation for the given IU defined.
254 *
255 * @param unitName Name of the IU.
256 * @return True if there is an implementation, otherwise false.
257 */
258bool
260 const std::string& unitName) const {
261
262 return findImplementation(iuImplementations_, unitName) != NULL;
263}
264
265/**
266 * Tells whether there is an implementation for the given bus defined.
267 *
268 * @param busName Name of the bus.
269 * @return True if there is an implementation, otherwise false.
270 */
271bool
273 const std::string& busName) const {
274
275 return findImplementation(busImplementations_, busName) != NULL;
276}
277
278
279/**
280 * Tells whether there is an implementation for the given socket defined.
281 *
282 * @param socketName Name of the IU.
283 * @return True if there is an implementation, otherwise false.
284 */
285bool
287 const std::string& socketName) const {
288
289 return findImplementation(socketImplementations_, socketName) != NULL;
290}
291
292
293/**
294 * Returns the number of FU implementations.
295 *
296 * @return The number of FU implementations.
297 */
298int
302
303
304/**
305 * Returns the number of RF implementations.
306 *
307 * @return The number of RF implementations.
308 */
309int
313
314
315/**
316 * Returns the number of IU implementations.
317 *
318 * @return The number of IU implementations.
319 */
320int
324
325/**
326 * Returns the number of bus implementations.
327 *
328 * @return The number of bus implementations.
329 */
330int
334
335/**
336 * Returns the number of socket implementations.
337 *
338 * @return The number of socket implementations.
339 */
340int
344
345
346/**
347 * Returns the implementation data of the given FU.
348 *
349 * @param fu Name of the FU.
350 * @return The implementation data.
351 * @exception InstanceNotFound If there is no implementation defined for
352 * the given FU.
353 */
355MachineImplementation::fuImplementation(const std::string& fu) const {
358 if (impl == NULL) {
359 const string procName = "MachineImplementation::fuImplementation";
360 throw InstanceNotFound(
361 __FILE__, __LINE__, procName,
362 "No implementation data found for function unit " + fu + ".");
363 } else {
364 return *impl;
365 }
366}
367
368/**
369 * Returns the implementation data of the given RF.
370 *
371 * @param rf Name of the RF.
372 * @return The implementation data.
373 * @exception InstanceNotFound If there is no implementation defined for
374 * the given RF.
375 */
377MachineImplementation::rfImplementation(const std::string& rf) const {
380 if (impl == NULL) {
381 const string procName = "MachineImplementation::rfImplementation";
382 throw InstanceNotFound(
383 __FILE__, __LINE__, procName,
384 "No implementation data found for register file " + rf + ".");
385 } else {
386 return *impl;
387 }
388}
389
390/**
391 * Returns the implementation data of the given IU.
392 *
393 * @param iu Name of the IU.
394 * @return The implementation data.
395 * @exception InstanceNotFound If there is no implementation defined for
396 * the given IU.
397 */
399MachineImplementation::iuImplementation(const std::string& iu) const {
402 if (impl == NULL) {
403 throw InstanceNotFound(
404 __FILE__, __LINE__, __func__,
405 "No implementation data found for immediate unit " + iu + ".");
406 } else {
407 return *impl;
408 }
409}
410
411/**
412 * Returns the implementation data of the given bus.
413 *
414 * @param bus Name of the bus.
415 * @return The implementation data.
416 * @exception InstanceNotFound If there is no implementation defined for
417 * the given bus.
418 */
420MachineImplementation::busImplementation(const std::string& bus) const {
423 if (impl == NULL) {
424 throw InstanceNotFound(
425 __FILE__, __LINE__, __func__,
426 "No implementation data found for bus " + bus + ".");
427 } else {
428 return *impl;
429 }
430}
431
432/**
433 * Returns the implementation data of the given socket.
434 *
435 * @param socket Name of the socket.
436 * @return The implementation data.
437 * @exception InstanceNotFound If there is no implementation defined for
438 * the given socket.
439 */
441MachineImplementation::socketImplementation(const std::string& socket) const {
443 socketImplementations_, socket);
444 if (impl == NULL) {
445 throw InstanceNotFound(
446 __FILE__, __LINE__, __func__,
447 "No implementation data found for socket " + socket + ".");
448 } else {
449 return *impl;
450 }
451}
452
453/**
454 * Returns the FU implementation at the given position.
455 *
456 * @param index The position index.
457 * @return The implementation data.
458 * @exception OutOfRange If the index is smaller than 0 or not smaller than
459 * the number of FU implementations.
460 */
466
467/**
468 * Returns the RF implementation at the given position.
469 *
470 * @param index The position index.
471 * @return The implementation data.
472 * @exception OutOfRange If the index is smaller than 0 or not smaller than
473 * the number of RF implementations.
474 */
480
481/**
482 * Returns the IU implementation at the given position.
483 *
484 * @param index The position index.
485 * @return The implementation data.
486 * @exception OutOfRange If the index is smaller than 0 or not smaller than
487 * the number of IU implementations.
488 */
494
495/**
496 * Returns the bus implementation at the given position.
497 *
498 * @param index The position index.
499 * @return The implementation data.
500 * @exception OutOfRange If the index is smaller than 0 or not smaller than
501 * the number of bus implementations.
502 */
508
509/**
510 * Returns the socket implementation at the given position.
511 *
512 * @param index The position index.
513 * @return The implementation data.
514 * @exception OutOfRange If the index is smaller than 0 or not smaller than
515 * the number of socket implementations.
516 */
522
523/**
524 * Adds the given FU implementation.
525 *
526 * @param implementation The implementation to add.
527 * @exception ObjectAlreadyExists If there is an implementation for the same
528 * FU already.
529 * @exception InvalidData If the given implementation is registered to
530 * another MachineImplementation instance.
531 */
532void
535 if (hasFUImplementation(implementation->unitName())) {
536 const string procName = "MachineImplementation::addFUImplementation";
537 throw ObjectAlreadyExists(__FILE__, __LINE__, procName);
538 } else {
540 implementation->setParent(*this);
541 }
542}
543
544/**
545 * Adds the given RF implementation.
546 *
547 * @param implementation The implementation to add.
548 * @exception ObjectAlreadyExists If there is an implementation for the same
549 * RF already.
550 * @exception InvalidData If the given implementation is registered to
551 * another MachineImplementation instance.
552 */
553void
556 if (hasRFImplementation(implementation->unitName())) {
557 const string procName = "MachineImplementation::addRFImplementation";
558 throw ObjectAlreadyExists(__FILE__, __LINE__, procName);
559 } else {
561 implementation->setParent(*this);
562 }
563}
564
565/**
566 * Adds the given IU implementation.
567 *
568 * @param implementation The implementation to add.
569 * @exception ObjectAlreadyExists If there is an implementation for the same
570 * IU already.
571 * @exception InvalidData If the given implementation is registered to
572 * another MachineImplementation instance.
573 */
574void
577 if (hasIUImplementation(implementation->unitName())) {
578 const string procName = "MachineImplementation::addRFImplementation";
579 throw ObjectAlreadyExists(__FILE__, __LINE__, procName);
580 } else {
582 implementation->setParent(*this);
583 }
584}
585
586/**
587 * Adds the given bus implementation.
588 *
589 * @param implementation The implementation to add.
590 * @exception ObjectAlreadyExists If there is an implementation for the same
591 * bus already.
592 * @exception InvalidData If the given implementation is registered to
593 * another MachineImplementation instance.
594 */
595void
598 if (hasBusImplementation(implementation->unitName())) {
599 throw ObjectAlreadyExists(__FILE__, __LINE__, __func__);
600 } else {
602 implementation->setParent(*this);
603 }
604}
605
606/**
607 * Adds the given socket implementation.
608 *
609 * @param implementation The implementation to add.
610 * @exception ObjectAlreadyExists If there is an implementation for the same
611 * socket already.
612 * @exception InvalidData If the given implementation is registered to
613 * another MachineImplementation instance.
614 */
615void
618 if (hasSocketImplementation(implementation->unitName())) {
619 throw ObjectAlreadyExists(__FILE__, __LINE__, __func__);
620 } else {
622 implementation->setParent(*this);
623 }
624}
625
626/**
627 * Removes the FU implementation with given name.
628 *
629 * @param unitName Name of the implementation to remove.
630 * @exception InstanceNotFound If there is no implementation defined for
631 * the given FU.
632 */
633void
635 bool removed = false;
636 for (ImplementationTable::iterator iter = fuImplementations_.begin();
637 iter != fuImplementations_.end(); iter++) {
638
640 if (implementation->unitName() == unitName) {
641 fuImplementations_.erase(iter);
642 removed = true;
643 break;
644 }
645 }
646 if (!removed) {
647 throw InstanceNotFound(__FILE__, __LINE__, __func__);
648 }
649}
650
651/**
652 * Removes the RF implementation with given name.
653 *
654 * @param unitName Name of the implementation to remove.
655 * @exception InstanceNotFound If there is no implementation defined for
656 * the given RF.
657 */
658void
660 bool removed = false;
661 for (ImplementationTable::iterator iter = rfImplementations_.begin();
662 iter != rfImplementations_.end(); iter++) {
663
665 if (implementation->unitName() == unitName) {
666 rfImplementations_.erase(iter);
667 removed = true;
668 break;
669 }
670 }
671 if (!removed) {
672 throw InstanceNotFound(__FILE__, __LINE__, __func__);
673 }
674}
675
676/**
677 * Removes the IU implementation with given name.
678 *
679 * @param unitName Name of the implementation to remove.
680 * @exception InstanceNotFound If there is no implementation defined for
681 * the given IU.
682 */
683void
685 bool removed = false;
686 for (ImplementationTable::iterator iter = iuImplementations_.begin();
687 iter != iuImplementations_.end(); iter++) {
688
690 if (implementation->unitName() == unitName) {
691 iuImplementations_.erase(iter);
692 removed = true;
693 break;
694 }
695 }
696 if (!removed) {
697 throw InstanceNotFound(__FILE__, __LINE__, __func__);
698 }
699}
700
701/**
702 * Removes the bus implementation with given name.
703 *
704 * @param unitName Name of the implementation to remove.
705 * @exception InstanceNotFound If there is no implementation defined for
706 * the given bus.
707 */
708void
710 bool removed = false;
711 for (
712 ImplementationTable::iterator iter = busImplementations_.begin();
713 iter != busImplementations_.end(); iter++) {
714
716 if (implementation->unitName() == unitName) {
717 busImplementations_.erase(iter);
718 removed = true;
719 break;
720 }
721 }
722 if (!removed) {
723 throw InstanceNotFound(__FILE__, __LINE__, __func__);
724 }
725}
726
727/**
728 * Removes the socket implementation with given name.
729 *
730 * @param unitName Name of the implementation to remove.
731 * @exception InstanceNotFound If there is no implementation defined for
732 * the given socket.
733 */
734void
736 bool removed = false;
737 for (
738 ImplementationTable::iterator iter =
739 socketImplementations_.begin();
740 iter != socketImplementations_.end(); iter++) {
741
743 if (implementation->unitName() == unitName) {
744 socketImplementations_.erase(iter);
745 removed = true;
746 break;
747 }
748 }
749 if (!removed) {
750 throw InstanceNotFound(__FILE__, __LINE__, __func__);
751 }
752}
753
754/**
755 * Loads the state of the object from the given ObjectState tree.
756 *
757 * @param state The given ObjectState tree.
758 * @exception ObjectStateLoadingException If the given ObjectState tree is
759 * invalid.
760 */
761void
763 const string procName = "MachineImplementation::loadState";
764
765 if (state->name() != OSNAME_MACHINE_IMPLEMENTATION) {
766 throw ObjectStateLoadingException(__FILE__, __LINE__, procName);
767 }
768
769 clearState();
770
771
778 if (icdecState->hasAttribute(OSKEY_IC_DECODER_HDB)) {
780 }
781
782 // Load ic/decoder plugin parameters.
783 for (int i = 0; i < icdecState->childCount(); i++) {
784 ObjectState* parameterState = icdecState->child(i);
785 if (parameterState->name() != OSNAME_IC_DECODER_PARAMETER) {
787 __FILE__, __LINE__, procName);
788 }
789 std::string name = parameterState->stringAttribute(
791
792 std::string value = parameterState->stringAttribute(
794
795 Parameter parameter = { name, value };
796 icDecoderParameters_.push_back(parameter);
797 }
798 }
799
802 }
803
804 ObjectState* fuGenerate = state->childByName(OSNAME_FU_GENERATED);
805
806 for (int i = 0; i < fuGenerate->childCount(); i++) {
807 ObjectState* child = fuGenerate->child(i);
808 FUGenerated newfug;
809 newfug.loadState(child);
810 fuGenerated_.emplace_back(newfug);
811 }
812
813 try {
815 ObjectState* fuImplementations = state->childByName(
817 ObjectState* rfImplementations = state->childByName(
819 ObjectState* iuImplementations = state->childByName(
821 ObjectState* busImplementations = state->childByName(
823 ObjectState* socketImplementations = state->childByName(
825
826 for (int i = 0; i < fuImplementations->childCount(); i++) {
827 ObjectState* child = fuImplementations->child(i);
829 }
830
831 for (int i = 0; i < rfImplementations->childCount(); i++) {
832 ObjectState* child = rfImplementations->child(i);
834 }
835
836 for (int i = 0; i < iuImplementations->childCount(); i++) {
837 ObjectState* child = iuImplementations->child(i);
839 }
840 for (int i = 0; i < busImplementations->childCount(); i++) {
841 ObjectState* child = busImplementations->child(i);
843 }
844
845 for (int i = 0; i < socketImplementations->childCount(); i++) {
846 ObjectState* child = socketImplementations->child(i);
848 }
849
850 } catch (const Exception& exception) {
852 __FILE__, __LINE__, procName, exception.errorMessage());
853 }
854}
855
856/**
857 * Saves the state of the object to an ObjectState tree.
858 *
859 * @return The newly created ObjectState tree.
860 */
863
866
867 // add ic&decoder data
871 icdecState->setAttribute(
873 }
875 icdecState->setAttribute(
877 }
878 if (hasICDecoderHDB()) {
879 icdecState->setAttribute(
881 }
882
883 std::vector<Parameter>::const_iterator iter =
884 icDecoderParameters_.begin();
885
886 // add ic&decoder parameters
887 for (; iter != icDecoderParameters_.end(); iter++) {
888 ObjectState* parameterState =
890 parameterState->setAttribute(
891 OSKEY_IC_DECODER_PARAMETER_NAME, (*iter).name);
892 parameterState->setAttribute(
893 OSKEY_IC_DECODER_PARAMETER_VALUE, (*iter).value);
894 icdecState->addChild(parameterState);
895 }
896 state->addChild(icdecState);
897 }
898
899 // add decompressor file data
900 if (hasDecompressorFile()) {
902 }
903
904 // add Generated FUs.
905 ObjectState* fuGenerated = new ObjectState(OSNAME_FU_GENERATED);
906 state->addChild(fuGenerated);
907 for (const auto fug : fuGenerated_) {
908 fuGenerated->addChild(fug.saveState());
909 }
910
911 // add FU implementations
912 ObjectState* fuImplementations = new ObjectState(
914 state->addChild(fuImplementations);
915 for (int i = 0; i < fuImplementationCount(); i++) {
917 fuImplementations->addChild(impl.saveState());
918 }
919
920 // add RF implementations
921 ObjectState* rfImplementations = new ObjectState(
923 state->addChild(rfImplementations);
924 for (int i = 0; i < rfImplementationCount(); i++) {
926 rfImplementations->addChild(impl.saveState());
927 }
928
929 // add IU implementations
930 ObjectState* iuImplementations = new ObjectState(
932 state->addChild(iuImplementations);
933 for (int i = 0; i < iuImplementationCount(); i++) {
935 iuImplementations->addChild(impl.saveState());
936 }
937
938 // add bus implementations
939 ObjectState* busImplementations = new ObjectState(
941 state->addChild(busImplementations);
942 for (int i = 0; i < busImplementationCount(); i++) {
944 busImplementations->addChild(impl.saveState());
945 }
946
947 // add socket implementations
948 ObjectState* socketImplementations = new ObjectState(
950 state->addChild(socketImplementations);
951 for (int i = 0; i < socketImplementationCount(); i++) {
953 socketImplementations->addChild(impl.saveState());
954 }
955
956 return state;
957}
958
959/**
960 * Changes file paths in machine implementation to relative file paths.
961 *
962 * Tries to find relative file paths under provided search paths.
963 *
964 * @param sPaths Search paths, used for finding relative paths.
965 */
966void
968 const std::vector<std::string>& sPaths) {
969
970 // ic&decoder files
973 string filePath = icDecoderPluginFile_;
974 string relPath;
975 if (FileSystem::makeRelativePath(sPaths, filePath, relPath)) {
976 icDecoderPluginFile_ = relPath;
979 filePath, relPath)) {
980 icDecoderPluginFile_ = std::string("tce:") + relPath;
981 }
982 }
983 if (hasICDecoderHDB()) {
984 string filePath = icDecoderHDB_;
985 string relPath;
986 if (FileSystem::makeRelativePath(sPaths, filePath, relPath)) {
987 icDecoderHDB_ = relPath;
989 Environment::decompressorPaths(true), filePath, relPath)) {
990 icDecoderHDB_ = std::string("tce:") + relPath;
991 }
992 }
993 }
994
995 // decompressor file
996 if (hasDecompressorFile()) {
997 string filePath = decompressorFile_;
998 string relPath;
999 if (FileSystem::makeRelativePath(sPaths, filePath, relPath)) {
1000 decompressorFile_ = relPath;
1002 Environment::decompressorPaths(), filePath, relPath)) {
1003 decompressorFile_ = std::string("tce:") + relPath;
1004 }
1005 }
1006
1007 // FU files
1008 for (int i = 0; i < fuImplementationCount(); i++) {
1010 makeHDBPathRelative(sPaths, impl);
1011 }
1012
1013 // RF files
1014 for (int i = 0; i < rfImplementationCount(); i++) {
1016 makeHDBPathRelative(sPaths, impl);
1017 }
1018
1019 // IU files
1020 for (int i = 0; i < iuImplementationCount(); i++) {
1022 makeHDBPathRelative(sPaths, impl);
1023 }
1024
1025 // bus files
1026 for (int i = 0; i < busImplementationCount(); i++) {
1028 makeHDBPathRelative(sPaths, impl);
1029 }
1030
1031 // socket files
1032 for (int i = 0; i < socketImplementationCount(); i++) {
1034 makeHDBPathRelative(sPaths, impl);
1035 }
1036
1037 // Generated FUs and their operations.
1038 for (auto&& fug : FUGenerations()) {
1039 for (auto&& op : fug.operations()) {
1040 std::string& hdb = op.hdb;
1041 std::string rel;
1042 if (FileSystem::makeRelativePath(sPaths, hdb, rel)) {
1043 hdb = rel;
1045 Environment::hdbPaths(true), hdb, rel)) {
1046 hdb = "tce:" + rel;
1047 }
1048 }
1049 }
1050}
1051
1052
1053/**
1054 * Checks that every file defined in IDF exists.
1055 *
1056 * If a file can't be found under current working directory or absolute
1057 * path, it is searched under default search paths. If the file is found
1058 * under a default search path, the original file path will be replaced with
1059 * the found path.
1060 *
1061 * @param missingFiles Amount of missing files is returned using this.
1062 * @param alternativeFiles Amount of alt. files found for missing files.
1063 * @return True if every file was found locally or from absolute paths.
1064 */
1065bool
1067 size_t& missingFiles,
1068 size_t& alternativeFiles) {
1069
1070 missingFiles_.clear();
1071 alternativeFiles_.clear();
1072
1073 // local search paths (current working directory)
1074 vector<string> localPaths;
1075 localPaths.push_back(FileSystem::currentWorkingDir());
1076
1077 // default search paths for different implementation files
1078 vector<string> defSearchPaths;
1079
1080 // file that will be searched under search paths
1081 TCEString filePath;
1082
1083 // ic&decoder files
1084 if (hasICDecoderPluginName()) {
1085 if (hasICDecoderPluginFile()) {
1086 defSearchPaths = Environment::icDecoderPluginPaths();
1087 filePath = icDecoderPluginFile_;
1088
1089 if (isLibraryImplFile(filePath, filePath)) {
1090 icDecoderPluginFile_ = filePath;
1091 // try to find file under local or default search paths
1092 } else if (checkImplFile(localPaths, defSearchPaths, filePath)) {
1093 // found under default search paths, fix the path
1094 icDecoderPluginFile_ = filePath;
1095 }
1096 }
1097
1098 if (hasICDecoderHDB()) {
1099 defSearchPaths = Environment::hdbPaths();
1100 filePath = icDecoderHDB_;
1101
1102 if (isLibraryImplFile(filePath, filePath)) {
1103 icDecoderHDB_ = filePath;
1104 // try to find file under local or default search paths
1105 } else if (checkImplFile(localPaths, defSearchPaths, filePath)) {
1106 icDecoderHDB_ = filePath;
1107 }
1108 }
1109 }
1110
1111 // decompressor file
1112 if (hasDecompressorFile()) {
1113 defSearchPaths = Environment::decompressorPaths();
1114 filePath = decompressorFile_;
1115
1116 if (isLibraryImplFile(filePath, filePath)) {
1117 decompressorFile_ = filePath;
1118 // try to find file under local or default search paths
1119 } else if (checkImplFile(localPaths, defSearchPaths, filePath)) {
1120 decompressorFile_ = filePath;
1121 }
1122 }
1123
1124 // HDB files
1125 defSearchPaths = Environment::hdbPaths();
1126
1127 // FU files
1128 for (int i = 0; i < fuImplementationCount(); i++) {
1130 filePath = impl.hdbFileOriginal();
1131
1132 if (isLibraryImplFile(filePath, filePath)) {
1133 impl.setHDBFile(filePath);
1134 // try to find file under local or default search paths
1135 } else if (checkImplFile(localPaths, defSearchPaths, filePath)) {
1136 impl.setHDBFile(filePath);
1137 }
1138 }
1139
1140 // RF files
1141 for (int i = 0; i < rfImplementationCount(); i++) {
1143 filePath = impl.hdbFileOriginal();
1144
1145 if (isLibraryImplFile(filePath, filePath)) {
1146 impl.setHDBFile(filePath);
1147 // try to find file under local or default search paths
1148 } else if (checkImplFile(localPaths, defSearchPaths, filePath)) {
1149 impl.setHDBFile(filePath);
1150 }
1151 }
1152
1153 // IU files
1154 for (int i = 0; i < iuImplementationCount(); i++) {
1156 filePath = impl.hdbFileOriginal();
1157
1158 if (isLibraryImplFile(filePath, filePath)) {
1159 impl.setHDBFile(filePath);
1160 // try to find file under local or default search paths
1161 } else if (checkImplFile(localPaths, defSearchPaths, filePath)) {
1162 impl.setHDBFile(filePath);
1163 }
1164 }
1165
1166 // bus files
1167 for (int i = 0; i < busImplementationCount(); i++) {
1169 filePath = impl.hdbFileOriginal();
1170
1171 if (isLibraryImplFile(filePath, filePath)) {
1172 impl.setHDBFile(filePath);
1173 // try to find file under local or default search paths
1174 } else if (checkImplFile(localPaths, defSearchPaths, filePath)) {
1175 impl.setHDBFile(filePath);
1176 }
1177 }
1178
1179 // socket files
1180 for (int i = 0; i < socketImplementationCount(); i++) {
1182 filePath = impl.hdbFileOriginal();
1183
1184 if (isLibraryImplFile(filePath, filePath)) {
1185 impl.setHDBFile(filePath);
1186 // try to find file under local or default search paths
1187 } else if (checkImplFile(localPaths, defSearchPaths, filePath)) {
1188 impl.setHDBFile(filePath);
1189 }
1190 }
1191
1192 // check amount of missing files and alternative files that were found
1193
1194 missingFiles = missingFiles_.size();
1195 alternativeFiles = 0;
1196 for (size_t i = 0; i < alternativeFiles_.size(); ++i) {
1197 if (alternativeFiles_.at(i) != "") {
1198 ++alternativeFiles;
1199 }
1200 }
1201
1202 // were all the files found under local paths or from absolute paths?
1203 if (missingFiles_.size() == 0) {
1204 return true;
1205 }
1206
1207 return false;
1208}
1209
1210/**
1211 * Tries to find a file under provided search paths.
1212 *
1213 * If the file cannot be found under primary search paths, it is searched
1214 * under secondary paths. If an alternative file path is found under
1215 * secondary paths, it is returned using the string reference parameter.
1216 *
1217 * @param primarySearchPaths Paths where the file is searched first.
1218 * @param secondarySearchPaths Paths where the file is searched after.
1219 * @param file Path to file, might be relative of absolute. The alternative
1220 * file path is returned in this.
1221 * @return True if alternative path was placed in the reference parameter.
1222 */
1223bool
1225 const std::vector<std::string>& primarySearchPaths,
1226 const std::vector<std::string>& secondarySearchPaths,
1227 std::string& file) {
1228
1229 if (file == "") {
1230 return false;
1231 }
1232
1233 // Remove tce file specifier.
1234 if (TCEString(file).startsWith("tce:")) {
1235 file = TCEString(file).replaceString("tce:", "");
1236 }
1237
1238 // return if the file path has already been processed as a missing file
1239 for (unsigned int i = 0; i < missingFiles_.size(); ++i) {
1240 if (file.compare(missingFiles_.at(i)) == 0) {
1241 if (alternativeFiles_.at(i) != "") {
1242 file = alternativeFiles_.at(i);
1243 return true;
1244 } else {
1245 return false;
1246 }
1247 }
1248 }
1249
1250 // first search: primary search paths
1251 try {
1252 FileSystem::findFileInSearchPaths(primarySearchPaths, file);
1253 return false;
1254 } catch (Exception& e) {
1255 // file was not found
1256 }
1257
1258 // second search: secondary search paths (with the plain file name)
1259 try {
1260 string alternativePath = FileSystem::findFileInSearchPaths(
1261 secondarySearchPaths, FileSystem::fileOfPath(file));
1262
1263 // file was not found, but alternative file path was found
1264 missingFiles_.push_back(file);
1265 alternativeFiles_.push_back(alternativePath);
1266
1267 file = alternativePath;
1268 return true;
1269 } catch (Exception& e) {
1270 // file was not found, and no alternative path was found either
1271 missingFiles_.push_back(file);
1272 alternativeFiles_.push_back("");
1273 return false;
1274 }
1275}
1276
1277/**
1278 * Tries to find a relative path for an HDB file.
1279 *
1280 * If a relative path is found under any of the search paths, the first
1281 * match is saved. In case the HDB file path is invalid, the path field is
1282 * left empty.
1283 *
1284 * @param searchPaths Search for relative paths is done under these paths.
1285 * @param implem Object containing a file path, which points to an HDB file.
1286 */
1287void
1289 const std::vector<std::string>& searchPaths,
1290 UnitImplementationLocation& implem) const {
1291
1292 try {
1293 string filePath = implem.hdbFile();
1294 string relPath;
1295 if (FileSystem::makeRelativePath(searchPaths, filePath, relPath)) {
1296 implem.setHDBFile(relPath);
1298 filePath, relPath)) {
1299 implem.setHDBFile(std::string("tce:") + relPath);
1300 }
1301 } catch (FileNotFound& e) {
1302 implem.setHDBFile("");
1303 }
1304}
1305
1306/**
1307 * Finds implementation for the given unit from the given table.
1308 *
1309 * @param table The table to search from.
1310 * @param unitName Name of the unit.
1311 * @return The correct UnitImplementationLocation instance or NULL if no
1312 * implementation is found.
1313 */
1316 const ImplementationTable& table,
1317 const std::string& unitName) const {
1318
1319 for (ImplementationTable::const_iterator iter = table.begin();
1320 iter != table.end(); iter++) {
1322 if (implementation->unitName() == unitName) {
1323 return implementation;
1324 }
1325 }
1326
1327 return NULL;
1328}
1329
1330
1331/**
1332 * Ensures that the given index is valid for getting an instance from the
1333 * given implementation table.
1334 *
1335 * @param index The index.
1336 * @param table The table.
1337 * @exception OutOfRange If the given index is not valid.
1338 */
1339void
1341 int index, const ImplementationTable& table) const {
1342 if (index < 0 || static_cast<size_t>(index) >= table.size()) {
1343 const string procName = "MachineImplementation::ensureIndexValidity";
1344 throw OutOfRange(__FILE__, __LINE__, procName);
1345 }
1346}
1347
1348/**
1349 * Clears the state of the object.
1350 */
1351void
1366
1367/**
1368 * Returns number of ic&decoder plugin parameters defined.
1369 */
1370unsigned
1374
1375/**
1376 * Returns name of the ic/decoder parameter with the given index.
1377 *
1378 * @param param Index of the parameter.
1379 * @return Name of the parameter.
1380 */
1381std::string
1383 if (param >= icDecoderParameters_.size()) {
1384 const string procName =
1385 "MachineImplementation::icDecoderParameterName";
1386 throw OutOfRange(__FILE__, __LINE__, procName);
1387
1388 }
1389 return icDecoderParameters_[param].name;
1390}
1391
1392/**
1393 * Returns value of the ic/decoder parameter with the given index.
1394 *
1395 * @param param Index of the parameter.
1396 * @return Value of the parameter.
1397 */
1398std::string
1400 if (param >= icDecoderParameters_.size()) {
1401 const string procName = "MachineImplementation::icDecoderParamterName";
1402 throw OutOfRange(__FILE__, __LINE__, procName);
1403
1404 }
1405 return icDecoderParameters_[param].value;
1406}
1407
1408/**
1409 * Returns value of the ic/decoder parameter with the given name.
1410 *
1411 * @param name Name of the parameter.
1412 * @return Value of the parameter.
1413 */
1414std::string
1416
1417 std::vector<Parameter>::const_iterator iter =
1418 icDecoderParameters_.begin();
1419
1420 for (; iter != icDecoderParameters_.end(); iter++) {
1421 if ((*iter).name == name) {
1422 return (*iter).value;
1423 }
1424 }
1425
1426 // Parameter value not defined.
1427 return "";
1428}
1429
1430/**
1431 * Sets value of an ic/decoder parameter.
1432 *
1433 * @param name Name of the parameter.
1434 * @param value Value of the parameter.
1435 */
1436void
1438 const std::string& name, const std::string& value) {
1439
1440 std::vector<Parameter>::iterator iter =
1441 icDecoderParameters_.begin();
1442
1443 // Check if the parameter already exists.
1444 for (; iter != icDecoderParameters_.end(); iter++) {
1445 if ((*iter).name == name) {
1446 (*iter).value = value;
1447 return;
1448 }
1449 }
1450
1451 // New parameter.
1452 Parameter parameter = { name, value };
1453 icDecoderParameters_.push_back(parameter);
1454}
1455
1456/**
1457 * Sets the ic/decoder plugin name.
1458 *
1459 * @param name Name of the ic/decoder plugin.
1460 */
1461void
1463 icDecoderPluginName_ = name;
1464
1465}
1466
1467
1468/**
1469 * Sets the ic/decoder plugin file.
1470 *
1471 * @param file Full path of the ic/decoder plugin file.
1472 */
1473void
1475 vector<string> paths = Environment::icDecoderPluginPaths();
1476 paths.insert(paths.begin(), FileSystem::directoryOfPath(sourceIDF_));
1477 string expandedPath = FileSystem::expandTilde(file);
1479 FileSystem::findFileInSearchPaths(paths, expandedPath);
1480}
1481
1482/**
1483 * Sets the ic/decoder HDB file.
1484 *
1485 * @param file Full path of the ic/decoder HDB file.
1486 */
1487void
1489 vector<string> paths = Environment::hdbPaths();
1490 paths.insert(paths.begin(), FileSystem::directoryOfPath(sourceIDF_));
1491 string expandedPath = FileSystem::expandTilde(file);
1493 FileSystem::findFileInSearchPaths(paths, expandedPath);
1494}
1495
1496/**
1497 * Sets the decompressor block file.
1498 *
1499 * @param file Full path to the decompressor block file.
1500 */
1501void
1503 vector<string> paths = Environment::decompressorPaths();
1504 paths.insert(paths.begin(), FileSystem::directoryOfPath(sourceIDF_));
1506}
1507
1508/**
1509 * Clears the ic/decoder parameters.
1510 */
1511void
1515
1516/**
1517 * Loads a MachineImplementation from the given IDF file.
1518 *
1519 * @param idfFileName The name of the file to load the IDF from.
1520 * @return A machine implementation instance.
1521 * @exception Exception In case some error occured.
1522 */
1524MachineImplementation::loadFromIDF(const std::string& idfFileName) {
1525 IDFSerializer serializer;
1526 serializer.setSourceFile(idfFileName);
1527
1528 return serializer.readMachineImplementation();
1529}
1530
1531/**
1532 * Returns true if the given file is a library file of TCE.
1533 *
1534 * If the file is a TCE library file, its absolute absolute path returned via
1535 * reference.
1536 *
1537 * @param path The file path that is relative or absolute.
1538 * @param resolvedPath The resolved absolute path.
1539 * @return True, if the file is TCE library file. Otherwise, false.
1540 */
1541bool
1543 const std::string& path,
1544 std::string& resolvedPath) {
1545
1546 TCEString toSearched(path);
1547 toSearched.replaceString("tce:", "");
1548
1549 std::vector<std::string> defaultPaths;
1550 std::vector<std::string> tmp = Environment::hdbPaths(true);
1551 defaultPaths.insert(defaultPaths.end(), tmp.begin(), tmp.end());
1553 defaultPaths.insert(defaultPaths.end(), tmp.begin(), tmp.end());
1555 defaultPaths.insert(defaultPaths.end(), tmp.begin(), tmp.end());
1556
1557 try {
1558 resolvedPath = FileSystem::findFileInSearchPaths(
1559 defaultPaths, toSearched);
1560 return true;
1561 } catch (Exception& e) {
1562 // file was not found
1563 }
1564
1565 return false;
1566}
1567
1568/**
1569 * Return all FUs to generate.
1570 */
1571const std::vector<FUGenerated>&
1575
1576/**
1577 * Return all FUs to generate.
1578 */
1579std::vector<FUGenerated>&
1583
1584/**
1585 * Return true if fu is to be generated.
1586 *
1587 * @param name Name of the FU Generation to check.
1588 */
1589bool
1590MachineImplementation::hasFUGeneration(const std::string& name) const {
1591 for (const auto fug : fuGenerated_) {
1592 if (fug.name() == name) {
1593 return true;
1594 }
1595 }
1596 return false;
1597}
1598
1599/**
1600 * Remove fu from generation list.
1601 *
1602 * @param name Name of the FU Generation to remove.
1603 */
1604void
1606 fuGenerated_.erase(
1607 std::remove_if(
1608 fuGenerated_.begin(), fuGenerated_.end(),
1609 [name](FUGenerated& fu) { return fu.name() == name; }),
1610 fuGenerated_.end());
1611}
1612
1613/**
1614 * Add fu to generation list.
1615 *
1616 * @param fug FU Generation to add.
1617 */
1618void
1620 fuGenerated_.emplace_back(fug);
1621}
1622}
1623
#define __func__
IDF::MachineImplementation * implementation
the implementation definition of the estimated processor
static std::vector< std::string > icDecoderPluginPaths(bool libraryPathsOnly=false)
static std::vector< std::string > hdbPaths(bool libraryPathsOnly=false)
static std::vector< std::string > decompressorPaths(bool libraryPathsOnly=false)
std::string errorMessage() const
Definition Exception.cc:123
static std::string fileOfPath(const std::string pathName)
static std::string directoryOfPath(const std::string fileName)
Definition FileSystem.cc:79
static std::string currentWorkingDir()
static std::string findFileInSearchPaths(const std::vector< std::string > &searchPaths, const std::string &file)
static bool makeRelativePath(const std::vector< std::string > &searchPaths, const std::string &basePath, std::string &toRelPath)
static std::string expandTilde(const std::string &stringWithTilde)
void loadState(const ObjectState *state) override
MachineImplementation * readMachineImplementation()
BusImplementationLocation & busImplementation(const std::string &bus) const
std::vector< std::string > missingFiles_
Implementation files defined in IDF which cannot be located.
ImplementationTable iuImplementations_
IU implementations.
void removeFuGeneration(const std::string &name)
void addSocketImplementation(SocketImplementationLocation *implementation)
std::string icDecoderPluginName() const
void setICDecoderParameter(const std::string &name, const std::string &value)
void removeFUImplementation(const std::string &unitName)
static const std::string OSKEY_DECOMPRESSOR_FILE
ObjectState attribute key for the name of the decompressor file.
void addBusImplementation(BusImplementationLocation *implementation)
void setICDecoderHDB(const std::string &file)
void setICDecoderPluginFile(const std::string &file)
static const std::string OSNAME_IC_DECODER_PLUGIN
ObjectState name for the name of the IC/decoder plugin file.
void addIUImplementation(RFImplementationLocation *implementation)
static const std::string OSKEY_IC_DECODER_HDB
ObjectState attribute name for ic&decoder HDB.
void addRFImplementation(RFImplementationLocation *implementation)
SocketImplementationLocation & socketImplementation(const std::string &socket) const
std::vector< Parameter > icDecoderParameters_
IC/decoder plugin parameters.
RFImplementationLocation & iuImplementation(const std::string &iu) const
static const std::string OSKEY_SOURCE_IDF
ObjectState attribute name for the source IDF.
ImplementationTable socketImplementations_
SOCKET implementations.
RFImplementationLocation & rfImplementation(const std::string &rf) const
UnitImplementationLocation * findImplementation(const ImplementationTable &table, const std::string &unitName) const
ImplementationTable busImplementations_
BUS implementations.
static const std::string OSNAME_IU_IMPLEMENTATIONS
ObjectState name for IU implementation container.
std::string decompressorFile_
Name of the decompressor block file.
bool checkImplFiles(size_t &missingFiles, size_t &alternativeFiles)
std::string icDecoderPluginName_
Name of the IC/decoder plugin.
std::string icDecoderPluginFile_
Name of the IC/decoder plugin file.
bool hasIUImplementation(const std::string &unitName) const
void makeImplFilesRelative(const std::vector< std::string > &sPaths)
FUImplementationLocation & fuImplementation(const std::string &fu) const
std::string sourceIDF_
Absolute path to the source IDF file.
static const std::string OSKEY_IC_DECODER_NAME
ObjectState attribute name for ic&decoder name.
virtual void loadState(const ObjectState *state)
void removeIUImplementation(const std::string &unitName)
void setDecompressorFile(const std::string &file)
bool hasFUGeneration(const std::string &name) const
static const std::string OSNAME_MACHINE_IMPLEMENTATION
ObjectState name for machine implementation.
ImplementationTable fuImplementations_
FU implementations.
ImplementationTable rfImplementations_
RF implementations.
void makeHDBPathRelative(const std::vector< std::string > &searchPaths, UnitImplementationLocation &implem) const
std::string icDecoderPluginFile() const
static const std::string OSNAME_BUS_IMPLEMENTATIONS
ObjectState name for bus implementation container.
bool hasRFImplementation(const std::string &unitName) const
std::string icDecoderHDB_
Name of the HDB of the IC/decoder plugin.
std::vector< UnitImplementationLocation * > ImplementationTable
Vector type for UnitImplementationLocation.
std::string icDecoderParameterValue(const std::string &name) const
static MachineImplementation * loadFromIDF(const std::string &idfFileName)
std::vector< FUGenerated > fuGenerated_
Generated FUs.
std::string icDecoderParameterName(unsigned param) const
bool checkImplFile(const std::vector< std::string > &primarySearchPaths, const std::vector< std::string > &secondarySearchPaths, std::string &file)
static const std::string OSNAME_FU_GENERATED
ObjectState name for FU generations container.
void ensureIndexValidity(int index, const ImplementationTable &table) const
const std::vector< FUGenerated > & FUGenerations() const
void removeRFImplementation(const std::string &unitName)
static const std::string OSKEY_IC_DECODER_FILE
ObjectState attribute name for ic&decoder file.
void addFUImplementation(FUImplementationLocation *implementation)
virtual ObjectState * saveState() const
void removeSocketImplementation(const std::string &unitName)
static const std::string OSNAME_IC_DECODER_PARAMETER
ObjectState attribute name for ic&decoder parameter.
bool hasBusImplementation(const std::string &busName) const
void removeBusImplementation(const std::string &unitName)
static const std::string OSNAME_SOCKET_IMPLEMENTATIONS
ObjectState name for socket implementation container.
static const std::string OSKEY_IC_DECODER_PARAMETER_NAME
ObjectState attribute name for ic&decoder parameter name.
bool hasSocketImplementation(const std::string &socketName) const
static const std::string OSNAME_RF_IMPLEMENTATIONS
ObjectState name for RF implementation container.
std::vector< std::string > alternativeFiles_
Possible alternative file paths for missing implementation files.
void setICDecoderPluginName(const std::string &name)
static const std::string OSNAME_FU_IMPLEMENTATIONS
ObjectState name for FU implementation container.
static const std::string OSKEY_IC_DECODER_PARAMETER_VALUE
ObjectState attribute name for ic&decoder parameter value.
bool hasFUImplementation(const std::string &unitName) const
void addFuGeneration(const FUGenerated &fug)
virtual void setHDBFile(std::string file)
bool hasAttribute(const std::string &name) const
ObjectState * childByName(const std::string &name) const
void setAttribute(const std::string &name, const std::string &value)
bool hasChild(const std::string &name) const
ObjectState * child(int index) const
void addChild(ObjectState *child)
std::string stringAttribute(const std::string &name) const
std::string name() const
int childCount() const
static void deleteAllItems(SequenceType &aSequence)
TCEString & replaceString(const std::string &old, const std::string &newString)
Definition TCEString.cc:94
void setSourceFile(const std::string &fileName)