OpenASIP 2.2
Loading...
Searching...
No Matches
InfoCommand.cc
Go to the documentation of this file.
1/*
2 Copyright (c) 2002-2017 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 InfoCommand.cc
26 *
27 * Implementation of InfoCommand class
28 *
29 * @author Pekka Jääskeläinen 2005,2017 (pjaaskel-no.spam-cs.tut.fi)
30 * @author Viljami Korhonen 2007 (viljami.korhonen-no.spam-tut.fi)
31 * @author Henry Linjamäki 2017 (henry.linjamaki-no.spam-tut.fi)
32 * @note rating: red
33 */
34
35#include <iomanip>
36#include <set>
37#include <string>
38#include <sstream>
39
40#include "CompilerWarnings.hh"
41IGNORE_CLANG_WARNING("-Wkeyword-macro")
42#include <boost/regex.hpp>
44#include "boost/tuple/tuple.hpp"
45
46#include "InfoCommand.hh"
47#include "Application.hh"
48#include "FileSystem.hh"
49#include "SimulatorFrontend.hh"
52#include "Exception.hh"
53#include "SimulatorToolbox.hh"
55#include "SimValue.hh"
56#include "Program.hh"
57#include "Procedure.hh"
58#include "Address.hh"
59#include "Instruction.hh"
60#include "Move.hh"
61#include "Terminal.hh"
62#include "MapTools.hh"
63#include "Conversion.hh"
64#include "SimulatorConstants.hh"
65#include "StateData.hh"
66#include "StringTools.hh"
67#include "StopPointManager.hh"
68#include "UniversalMachine.hh"
70#include "MachineState.hh"
71#include "RegisterFileState.hh"
72#include "Machine.hh"
73#include "FunctionUnit.hh"
74#include "DisassemblyFUPort.hh"
75#include "Bus.hh"
76#include "Segment.hh"
77#include "BusState.hh"
78#include "ControlUnit.hh"
79#include "UtilizationStats.hh"
81#include "HWOperation.hh"
83#include "RFAccessTracker.hh"
86
87using std::string;
88
89/**
90 * Implementation of "info registers".
91 */
93public:
94
95 /**
96 * Constructor.
97 */
101
102 /**
103 * Destructor.
104 */
106 }
107
108 /**
109 * Executes the "info registers" command.
110 *
111 * "info registers regfile regname" prints the value of register regname
112 * in register file regfile, where regfile is the name of a register file
113 * of the target processor, and regname is the name of a register that
114 * belongs to the specified register file. If regname is omitted,
115 * values of all registers of the specified register file are displayed.
116 *
117 * @param arguments Arguments to the command, including "info registers".
118 * @return true in case execution was successful.
119 */
120 virtual bool execute(const std::vector<DataObject>& arguments) {
121
122 if (!parent().checkProgramLoaded()) {
123 return false;
124 }
125
126 const int argumentCount = arguments.size() - 2;
127 if (!parent().checkArgumentCount(argumentCount, 1, 2)) {
128 return false;
129 }
130
131 std::string registerFile = "";
132 std::string registerName = "";
133 std::string registerString = "";
134 int registerIndex = -1;
135
136 if (argumentCount == 1) {
137 // 'ra' is treated as a special case
138 if (StringTools::ciEqual(registerString, "ra")) {
139 StateData& data =
140 parent().simulatorFrontend().state(registerString);
141
143 registerDescription(registerString, data.value()));
144 return true;
145 }
146
147 registerFile = arguments[2].stringValue();
148
149 try {
151 parent().simulatorFrontend().registerFileValue(registerFile));
152 } catch (const InstanceNotFound&) {
156 return false;
157 }
158 return true;
159
160 } else if (argumentCount == 2) {
161 // prints out the register in the given register file
162 if (!parent().checkPositiveIntegerArgument(arguments[3])) {
163 return false;
164 }
165 registerFile = arguments[2].stringValue();
166 registerIndex = arguments[3].integerValue();
167 registerName =
168 registerFile + "." + Conversion::toString(registerIndex);
169 } else {
170 abortWithError("Illegal count of arguments.");
171 }
172
173 // print a single register value
174 try {
176 parent().simulatorFrontend().registerFileValue(
177 registerFile, registerIndex));
178
179 return true;
180 } catch (const InstanceNotFound&) {
184 return false;
185 }
186 return true;
187 }
188
189 /**
190 * Helper function to get register description in correct format.
191 *
192 * @param regName The name of the register to print.
193 * @param value The current value of the register.
194 */
195 static std::string registerDescription(
196 const std::string& regName,
197 const SimValue& value) {
198 return regName + " " + value.hexValue() + " " +
200 }
201};
202
203/**
204 * Implementation of "info immediates".
205 */
207public:
208
209 /**
210 * Constructor.
211 */
215
216 /**
217 * Destructor.
218 */
220 }
221
222 /**
223 * Executes the "info immediates" command.
224 *
225 * "info immediates iunit regname" prints the value of register regname
226 * in immediate unit iunit, where regfile is the name of a register file
227 * of the target processor, and regname is the name of a register that
228 * belongs to the specified register file. If regname is omitted, values
229 * of all registers of the specified immediate unit are displayed.
230 *
231 * @param arguments Arguments to the command, including "info immediates".
232 * @return true in case execution was successful.
233 */
234 virtual bool execute(const std::vector<DataObject>& arguments) {
235
236 if (!parent().checkProgramLoaded()) {
237 return false;
238 }
239
240 const int argumentCount = arguments.size() - 2;
241
242 if (!parent().checkArgumentCount(argumentCount, 1, 2)) {
243 return false;
244 }
245
246 const std::string unitName = arguments[2].stringValue();
249 if (!navigator.hasItem(unitName)) {
253 return false;
254 }
255
256 if (argumentCount == 1) {
257 std::string output = "";
258 bool firstReg = true;
259
260 for (int i = 0; i < navigator.count(); ++i) {
261
262 if (!firstReg)
263 output += "\n";
264
266 immediateUnitRegisterValue(unitName, i);
267
268 const std::string registerName =
269 unitName + "." + Conversion::toString(i);
270
272 registerName, value);
273 firstReg = false;
274 }
275 parent().interpreter()->setResult(output);
276 return true;
277
278 } else if (argumentCount == 2) {
279 // prints out the register in the given register file
280 if (!parent().checkPositiveIntegerArgument(arguments[3])) {
281 return false;
282 }
283 int registerIndex = arguments[3].integerValue();
284 try {
286 immediateUnitRegisterValue(unitName, registerIndex);
287 parent().interpreter()->setResult(value.intValue());
288 return true;
289 } catch (const Exception& e) {
293 return false;
294 }
295 }
296 abortWithError("Shouldn't get here.");
297 return false;
298 }
299};
300
301
302/**
303 * Implementation of "info regfiles".
304 */
306public:
307 /**
308 * Constructor.
309 */
313
314 /**
315 * Destructor.
316 */
318 }
319
320 /**
321 * Executes the "info regfiles" command.
322 *
323 * "info regfiles" prints the names of all the register files in the
324 * machine.
325 *
326 * @param arguments No arguments should be given.
327 * @return Always true.
328 */
329 virtual bool execute(const std::vector<DataObject>& arguments) {
330
331 const int argumentCount = arguments.size() - 2;
332
333 if (!parent().checkArgumentCount(argumentCount, 0, 0)) {
334 return false;
335 }
336 if (!parent().checkMachineLoaded()) {
337 return false;
338 }
339 const TTAMachine::Machine& mach =
343 std::string result = "";
344 bool isFirst = true;
345 for (int i = 0; i < nav.count(); ++i) {
346 if (!isFirst)
347 result += "\n";
348 result += nav.item(i)->name();
349 isFirst = false;
350 }
351 parent().interpreter()->setResult(result);
352 return true;
353 }
354};
355
356/**
357 * Implementation of "info iunits".
358 */
360public:
361 /**
362 * Constructor.
363 */
367
368 /**
369 * Destructor.
370 */
372 }
373
374 /**
375 * Executes the "info iunits" command.
376 *
377 * "info iunits" prints the names of all the immediate units in the
378 * machine.
379 *
380 * @param arguments No arguments should be given.
381 * @return Always true.
382 */
383 virtual bool execute(const std::vector<DataObject>& arguments) {
384
385 const int argumentCount = arguments.size() - 2;
386
387 if (!parent().checkArgumentCount(argumentCount, 0, 0)) {
388 return false;
389 }
390 if (!parent().checkMachineLoaded()) {
391 return false;
392 }
393 const TTAMachine::Machine& mach =
397 std::string result = "";
398 bool isFirst = true;
399 for (int i = 0; i < nav.count(); ++i) {
400 if (!isFirst)
401 result += "\n";
402 result += nav.item(i)->name();
403 isFirst = false;
404 }
405 parent().interpreter()->setResult(result);
406 return true;
407 }
408};
409
410/**
411 * Implementation of "info busses".
412 */
414public:
415 /**
416 * Constructor.
417 */
421
422 /**
423 * Destructor.
424 */
426 }
427
428 /**
429 * Executes the "info busses" command.
430 *
431 * "info busses" prints information of the busses of the machine.
432 *
433 * @param arguments No arguments should be given.
434 * @return Always true.
435 */
436 virtual bool execute(const std::vector<DataObject>& arguments) {
437
438 const int argumentCount = arguments.size() - 2;
439
440 if (!parent().checkArgumentCount(argumentCount, 0, 1)) {
441 return false;
442 }
443 const TTAMachine::Machine& mach =
445
446 if (argumentCount == 0) {
448 mach.busNavigator();
449 std::string result = "";
450 bool isFirst = true;
451 for (int i = 0; i < nav.count(); ++i) {
452 if (!isFirst)
453 result += "\n";
454 TTAMachine::Bus* bus = nav.item(i);
455 assert(bus != NULL);
456 result += bus->name() + ": ";
457 bool isFirstSegment = true;
458 for (int j = 0; j < bus->segmentCount(); ++j) {
459 if (!isFirstSegment)
460 result += " ";
461 result += bus->segment(j)->name();
462 isFirstSegment = false;
463 }
464 isFirst = false;
465 }
466 parent().interpreter()->setResult(result);
467 return true;
468 } else if (argumentCount == 1) {
470 mach.busNavigator();
471 const std::string busName = arguments.at(2).stringValue();
472
473 if (!nav.hasItem(busName)) {
477 return false;
478 }
479
480 TTAMachine::Bus* bus = nav.item(busName);
481 assert(bus != NULL);
482 std::string result = "";
483 result += bus->name() + ": ";
484 bool isFirstSegment = true;
485 for (int j = 0; j < bus->segmentCount(); ++j) {
486 if (!isFirstSegment)
487 result += " ";
488 result += bus->segment(j)->name();
489 isFirstSegment = false;
490 }
491 parent().interpreter()->setResult(result);
492 return true;
493 }
494 return false;
495 }
496};
497
498/**
499 * Implementation of "info ports".
500 */
502public:
503 /**
504 * Constructor.
505 */
507 SimControlLanguageSubCommand(parentCommand) {
508 }
509
510 /**
511 * Destructor.
512 */
514 }
515
516 /**
517 * Executes the "info ports" command.
518 *
519 * "info ports" prints info of FU ports.
520 *
521 * @param arguments No arguments should be given.
522 * @return Always true.
523 */
524 virtual bool execute(const std::vector<DataObject>& arguments) {
525
526 const int argumentCount = arguments.size() - 2;
527
528 if (!parent().checkMachineLoaded()) {
529 return false;
530 }
531
532 if (!parent().checkArgumentCount(argumentCount, 1, 2)) {
533 return false;
534 }
535 const TTAMachine::Machine& mach =
537
538 const std::string functionUnit = arguments.at(2).stringValue();
539
542
543 TTAMachine::FunctionUnit* fu = NULL;
544 if (nav.hasItem(functionUnit)) {
545 fu = nav.item(functionUnit);
546 } else if (functionUnit == mach.controlUnit()->name()) {
547 fu = mach.controlUnit();
548 }
549
550 if (fu == NULL) {
554 return false;
555 }
556
557 if (argumentCount == 1) {
558 std::string result = "";
559 bool isFirst = true;
560 for (int i = 0; i < fu->portCount(); ++i) {
561 if (!isFirst)
562 result += "\n";
563 std::string portName = fu->port(i)->name();
564 DisassemblyFUPort portString(functionUnit, portName);
566 functionUnit, portName);
568 portString.toString(), portValue);
569 isFirst = false;
570 }
571 parent().interpreter()->setResult(result);
572 return true;
573 } else if (argumentCount == 2) {
574 const std::string portName = arguments.at(3).stringValue();
575 try {
576 // @todo printing of double values (size > 32)
578 functionUnit, portName);
579 parent().interpreter()->setResult(portValue.intValue());
580 return true;
581 } catch (const Exception& e) {
585 return false;
586 }
587 }
588 return false;
589 }
590};
591
592/**
593 * Implementation of "info segments".
594 */
596public:
597 /**
598 * Constructor.
599 */
603
604 /**
605 * Destructor.
606 */
608 }
609
610 /**
611 * Executes the "info segments" command.
612 *
613 * Prints the values of segments in the given bus.
614 *
615 * @param arguments No arguments should be given.
616 * @return Always true.
617 */
618 virtual bool execute(const std::vector<DataObject>& arguments) {
619
620 const int argumentCount = arguments.size() - 2;
621
622 if (!parent().checkArgumentCount(argumentCount, 1, 2)) {
623 return false;
624 }
625 if (!parent().checkMachineLoaded()) {
626 return false;
627 }
628 const TTAMachine::Machine& mach =
630
631 const std::string busName = arguments.at(2).stringValue();
632
634 mach.busNavigator();
635
636 if (!nav.hasItem(busName)) {
640 return false;
641 }
642
643 TTAMachine::Bus* bus = nav.item(busName);
644 assert(bus != NULL);
646
647 if (argumentCount == 1) {
648 std::string result = "";
649 BusState& busState = state.busState(busName);
650 parent().interpreter()->setResult(busState.value().intValue());
651 return true;
652 } else if (argumentCount == 2) {
654 "Segmented busses not yet supported.");
655 return false;
656 }
657 return false;
658 }
659};
660
661
662/**
663 * Implementation of "info funits".
664 */
666public:
667 /**
668 * Constructor.
669 */
673
674 /**
675 * Destructor.
676 */
678 }
679
680 /**
681 * Executes the "info funits" command.
682 *
683 * "info funits" prints the names of all the function units in the
684 * machine.
685 *
686 * @param arguments No arguments should be given.
687 * @return Always true.
688 */
689 virtual bool execute(const std::vector<DataObject>& arguments) {
690
691 const int argumentCount = arguments.size() - 2;
692
693 if (!parent().checkArgumentCount(argumentCount, 0, 0)) {
694 return false;
695 }
696 if (!parent().checkMachineLoaded()) {
697 return false;
698 }
699 const TTAMachine::Machine& mach =
703 std::string result = "";
704 bool isFirst = true;
705 for (int i = 0; i < nav.count(); ++i) {
706 if (!isFirst)
707 result += "\n";
708 result += nav.item(i)->name();
709 isFirst = false;
710 }
711 result += "\n" + mach.controlUnit()->name();
712 parent().interpreter()->setResult(result);
713 return true;
714 }
715};
716
717
718/**
719 * Implementation of "info proc".
720 */
722public:
723 /**
724 * Constructor.
725 */
727 SimControlLanguageSubCommand(parentCommand) {
728 }
729
730 /**
731 * Destructor.
732 */
734 }
735
736 /**
737 * Executes the "info proc" command.
738 *
739 * @param arguments Arguments to the command, including the command.
740 * @return true in case execution was successful.
741 */
742 virtual bool execute(const std::vector<DataObject>& arguments) {
743
744 if (!parent().checkSimulationEnded() &&
745 !parent().checkSimulationInitialized() &&
746 !parent().checkSimulationStopped() &&
747 !parent().simulatorFrontend().isSimulationRunning()) {
748
749 return false;
750 }
751
752 const int argumentCount = arguments.size() - 2;
753
754 if (!parent().checkArgumentCount(argumentCount, 1, 1)) {
755 return false;
756 }
757
758 const std::string command =
759 StringTools::stringToLower(arguments[2].stringValue());
760
761 if (command == "cycles") {
763 (boost::format("%.0f") %
764 parent().simulatorFrontend().cycleCount()).str());
765 return true;
766 } else if (command == "stats") {
767 std::stringstream result;
768
769 const ClockCycleCount totalCycles =
771
772 const UtilizationStats& stats =
774
775 result
776 << std::endl
777 << "utilizations" << std::endl
778 << "------------" << std::endl;
779
780 const int COLUMN_WIDTH = 15;
781 const TTAMachine::Machine& mach =
783 std::set<std::string> operationsOfMachine;
784
785 result
786 << std::endl << "buses:" << std::endl << std::endl;
787
789 mach.busNavigator();
790
791 for (int i = 0; i < busNav.count(); ++i) {
792 TTAMachine::Bus* bus = busNav.item(i);
793 assert(bus != NULL);
794 const ClockCycleCount writes =
795 stats.busWrites(bus->name());
796
797 result
798 << std::left << std::setw(COLUMN_WIDTH)
799 << bus->name() << " "
800 << std::left << std::setw(COLUMN_WIDTH)
801 << Conversion::toString(writes * 100.0 / totalCycles) +
802 "% (" + Conversion::toString(writes) + " writes)"
803 << std::endl;
804 }
805
806 result
807 << std::endl
808 << "sockets:" << std::endl << std::endl;
809
810 const TTAMachine::Machine::SocketNavigator& socketNav =
811 mach.socketNavigator();
812 for (int i = 0; i < socketNav.count(); ++i) {
813 TTAMachine::Socket* socket = socketNav.item(i);
814 assert(socket != NULL);
815 const ClockCycleCount writes =
816 stats.socketWrites(socket->name());
817
818 result
819 << std::left << std::setw(COLUMN_WIDTH)
820 << socket->name() << " "
821 << std::left << std::setw(COLUMN_WIDTH)
822 << Conversion::toString(writes * 100.0 / totalCycles) +
823 "% (" + Conversion::toString(writes) + " writes)"
824 << std::endl;
825 }
826
827 result
828 << std::endl
829 << "operations executed in function units:"
830 << std::endl << std::endl;
831
834 for (int i = 0; i <= fuNav.count(); ++i) {
835 TTAMachine::FunctionUnit* fu = NULL;
836 if (i < fuNav.count())
837 fu = fuNav.item(i);
838 else
839 fu = mach.controlUnit();
840 assert(fu != NULL);
841 const ClockCycleCount totalTriggersOfFU =
842 stats.triggerCount(fu->name());
843
844 result
845 << fu->name() << ":" << std::endl;
846
847 for (int j = 0; j < fu->operationCount(); ++j) {
848 const TTAMachine::HWOperation* op = fu->operation(j);
849 assert(op != NULL);
850 const std::string operationUpper =
852 operationsOfMachine.insert(operationUpper);
853 const ClockCycleCount executions =
855 fu->name(), operationUpper);
856
857 result
858 << std::left << std::setw(COLUMN_WIDTH)
859 << operationUpper << " "
860 << std::left << std::setw(COLUMN_WIDTH)
862 executions * 100.0 / totalTriggersOfFU) +
863 "% of FU total (" +
864 Conversion::toString(executions) + " executions)"
865 << std::endl;
866 }
867
868 result
869 << std::left << std::setw(COLUMN_WIDTH)
870 << "TOTAL" << " "
871 << std::left << std::setw(COLUMN_WIDTH)
873 totalTriggersOfFU * 100.0 / totalCycles) + "% (" +
874 Conversion::toString(totalTriggersOfFU) +
875 " triggers)" << std::endl << std::endl;
876 }
877
878 const TTAMachine::FunctionUnit& gcu = *mach.controlUnit();
879 for (int j = 0; j < gcu.operationCount(); ++j) {
880 const TTAMachine::HWOperation* op = gcu.operation(j);
881 assert(op != NULL);
882 const std::string operationUpper =
884 operationsOfMachine.insert(operationUpper);
885 }
886
887 result
888 << std::endl << "operations:" << std::endl << std::endl;
889
890 for (std::set<std::string>::iterator i =
891 operationsOfMachine.begin(); i !=
892 operationsOfMachine.end(); ++i) {
893 const ClockCycleCount executions =
894 stats.operationExecutions(*i);
895
896 result
897 << std::left << std::setw(COLUMN_WIDTH)
898 << *i << " " << std::left << std::setw(COLUMN_WIDTH)
899 << Conversion::toString(executions * 100.0 / totalCycles) +
900 "% (" + Conversion::toString(executions) + " executions)"
901 << std::endl;
902 }
903
904 result
905 << std::endl
906 << "FU port guard accesses:" << std::endl;
907
909 stats.FUGuardAccesses();
910
911 // loop each FU
912 for (UtilizationStats::FUOperationUtilizationIndex::iterator i =
913 fuGuardAccesses.begin(); i != fuGuardAccesses.end(); ++i) {
914
915 std::string fuName = i->first;
916
917 result
918 << std::endl
919 << fuName << ":"
920 << std::endl;
921
922 // loop each FU port in the utilization list
923 for (UtilizationStats::ComponentUtilizationIndex::iterator j =
924 i->second.begin(); j != i->second.end(); ++j) {
925 std::string fuPort = j->first;
926
927 ClockCycleCount count =
928 stats.FUGuardAccesses(fuName, fuPort);
929 result
930 << std::left << std::setw(COLUMN_WIDTH)
931 << fuPort << ": "
932 << Conversion::toString(count) << " reads"
933 << std::endl;
934 }
935 }
936
937 result
938 << std::endl
939 << "register accesses:" << std::endl
940 << std::endl;
941
944 for (int i = 0; i < rfNav.count(); ++i) {
945 TTAMachine::RegisterFile* rf = rfNav.item(i);
946 assert(rf != NULL);
947
948 result
949 << rf->name() << ":" << std::endl;
950
951 int regsUsedInFile = 0;
952 int lastReg = 0;
953 int totalReads = 0;
954 int totalWrites = 0;
955 int totalGuards = 0;
956 lastReg = rf->numberOfRegisters() - 1;
957
958 for (int reg = 0; reg <= lastReg; ++reg) {
959 ClockCycleCount reads =
960 stats.registerReads(rf->name(), reg);
961 totalReads += reads;
962 ClockCycleCount guardReads =
963 stats.guardRegisterReads(rf->name(), reg);
964 totalGuards += guardReads;
965 ClockCycleCount writes =
966 stats.registerWrites(rf->name(), reg);
967 totalWrites += writes;
968 ++regsUsedInFile;
969 result
970 << std::left << std::setw(COLUMN_WIDTH)
971 << reg << " "
972 << std::left << std::setw(COLUMN_WIDTH)
973 << Conversion::toString(reads) + " reads, "
974 << std::left << std::setw(COLUMN_WIDTH + 5)
975 << Conversion::toString(guardReads) + " guard reads, "
976 << std::left << std::setw(COLUMN_WIDTH)
977 << Conversion::toString(writes) + " writes"
978 << std::endl;
979 }
980
981 result
982 << std::left << std::setw(COLUMN_WIDTH)
983 << "TOTAL"
984 << std::left << std::setw(COLUMN_WIDTH)
985 << Conversion::toString(totalReads) + " reads, "
986 << std::left << std::setw(COLUMN_WIDTH + 5)
987 << Conversion::toString(totalGuards) + " guard reads, "
988 << std::left << std::setw(COLUMN_WIDTH)
989 << Conversion::toString(totalWrites) + " writes"
990 << std::endl;
991
992 result
993 << "TOTAL " << regsUsedInFile << " registers used"
994 << std::endl << std::endl;
995 }
996
997 result
998 << std::endl
999 << "immediate unit accesses:" << std::endl
1000 << std::endl;
1001
1004 for (int i = 0; i < iuNav.count(); ++i) {
1005 TTAMachine::ImmediateUnit* iu = iuNav.item(i);
1006 assert(iu != NULL);
1007
1008 result
1009 << iu->name() << ":" << std::endl;
1010
1011 int usedRegCount = 0;
1012 int lastReg = 0;
1013 lastReg = iu->numberOfRegisters() - 1;
1014
1015 for (int reg = 0; reg <= lastReg; ++reg) {
1016 ClockCycleCount reads =
1017 stats.registerReads(iu->name(), reg);
1018 ClockCycleCount writes =
1019 stats.registerWrites(iu->name(), reg);
1020 ++usedRegCount;
1021 result
1022 << std::left << std::setw(COLUMN_WIDTH)
1023 << reg << " "
1024 << std::left << std::setw(COLUMN_WIDTH)
1025 << Conversion::toString(reads) + " reads, "
1026 << std::left << std::setw(COLUMN_WIDTH)
1027 << Conversion::toString(writes) + " writes"
1028 << std::endl;
1029 }
1030 result
1031 << "TOTAL " << usedRegCount << " registers used"
1032 << std::endl << std::endl;
1033 }
1034
1035
1036 if (parent().simulatorFrontend().rfAccessTracing()) {
1037
1038 try {
1039 const RFAccessTracker& rfAccessTracker =
1041
1042 result
1043 << std::endl
1044 << "register file accesses" << std::endl
1045 << "----------------------" << std::endl;
1046
1047 const int COL_WIDTH = 20;
1048
1049 result
1050 << std::left << std::setw(COL_WIDTH)
1051 << "register file"
1052 << std::left << std::setw(COL_WIDTH)
1053 << "writes"
1054 << std::left << std::setw(COL_WIDTH)
1055 << "reads"
1056 << std::left << std::setw(COL_WIDTH)
1057 << "count" << std::endl;
1058
1059 RFAccessTracker::ConcurrentRFAccessIndex::
1060 const_iterator i =
1061 rfAccessTracker.accessDataBase().begin();
1062
1063 for (; i != rfAccessTracker.accessDataBase().end(); ++i) {
1064 result
1065 << std::left << std::setw(COL_WIDTH)
1066 << (*i).first.get<0>()
1067 << std::left << std::setw(COL_WIDTH)
1068 << (*i).first.get<1>()
1069 << std::left << std::setw(COL_WIDTH)
1070 << (*i).first.get<2>()
1071 << std::left << std::setw(COL_WIDTH)
1072 << (*i).second << std::endl;
1073 }
1074 } catch (const InstanceNotFound&) {
1075 }
1076 }
1077
1078 parent().interpreter()->setResult(result.str());
1079 return true;
1080
1081 } else if (command == "mapping") {
1082 const TTAMachine::Machine& mach =
1085 mach.addressSpaceNavigator();
1086 for (int i = 0; i < nav.count(); ++i) {
1087 TTAMachine::AddressSpace& space = *nav.item(i);
1088 unsigned int sizeOfSpace = space.end() - space.start();
1090 << std::left << std::setw(15)
1091 << space.name()
1092 << std::left
1093 << Conversion::toHexString(space.start(), 8)
1094 << " - "
1095 << Conversion::toHexString(space.end(), 8)
1096 << " (" << sizeOfSpace << " ";
1097 if (space.width() == 8) {
1098 parent().outputStream() << "bytes";
1099 } else {
1101 << "words of size " << space.width() << " bits";
1102 }
1103 parent().outputStream() << ")" << std::endl;
1104 }
1105 return true;
1106 } else {
1110 return false;
1111 }
1112 }
1113};
1114
1115
1116/**
1117 * Implementation of "info stats". The following sub-commands are supported:
1118 * "executed_operations", "register_reads" and "register_writes"
1119 */
1121public:
1122 /**
1123 * Constructor.
1124 */
1126 SimControlLanguageSubCommand(parentCommand) {
1127 }
1128
1129 /**
1130 * Destructor.
1131 */
1133 }
1134
1135 /**
1136 * Executes the "info stats" command.
1137 *
1138 * @param arguments Arguments to the command, including the command.
1139 * @return true in case execution was successful.
1140 */
1141 virtual bool execute(const std::vector<DataObject>& arguments) {
1142 if (!parent().checkSimulationEnded() &&
1143 !parent().checkSimulationInitialized() &&
1144 !parent().checkSimulationStopped() &&
1145 !parent().simulatorFrontend().isSimulationRunning()) {
1146 return false;
1147 }
1148
1149 const int argumentCount = arguments.size() - 2;
1150
1151 if (!parent().checkArgumentCount(argumentCount, 1, 1)) {
1152 return false;
1153 }
1154
1155 const std::string command =
1156 StringTools::stringToLower(arguments[2].stringValue());
1157
1158 const UtilizationStats& stats =
1160
1161 const TTAMachine::Machine& mach =
1163
1164 ClockCycleCount totalOperationExecutions = 0;
1165 ClockCycleCount totalRegisterReads = 0;
1166 ClockCycleCount totalRegisterWrites = 0;
1167
1169 mach.functionUnitNavigator();
1170
1172 mach.registerFileNavigator();
1173
1174 if (command == "executed_operations") {
1175 for (int i = 0; i <= fuNav.count(); ++i) {
1176 TTAMachine::FunctionUnit* fu = NULL;
1177 if (i < fuNav.count())
1178 fu = fuNav.item(i);
1179 else
1180 fu = mach.controlUnit();
1181 assert(fu != NULL);
1182
1183 for (int j = 0; j < fu->operationCount(); ++j) {
1184 const TTAMachine::HWOperation* op = fu->operation(j);
1185 assert (op != NULL);
1186 totalOperationExecutions += stats.operationExecutions(
1187 fu->name(), StringTools::stringToUpper(op->name()));
1188 }
1189 }
1191 static_cast<double>(totalOperationExecutions));
1192 return true;
1193 } else if (command == "register_reads") {
1194 for (int i = 0; i < rfNav.count(); ++i) {
1195 TTAMachine::RegisterFile* rf = rfNav.item(i);
1196 assert(rf != NULL);
1197
1198 int lastReg = 0;
1199 lastReg = rf->numberOfRegisters() - 1;
1200 for (int reg = 0; reg <= lastReg; ++reg) {
1201 totalRegisterReads += stats.registerReads(rf->name(), reg);
1202 }
1203 }
1205 static_cast<double>(totalRegisterReads));
1206 return true;
1207
1208 } else if (command == "register_writes") {
1209 for (int i = 0; i < rfNav.count(); ++i) {
1210 TTAMachine::RegisterFile* rf = rfNav.item(i);
1211 assert(rf != NULL);
1212
1213 int lastReg = 0;
1214 lastReg = rf->numberOfRegisters() - 1;
1215 for (int reg = 0; reg <= lastReg; ++reg) {
1216 totalRegisterWrites += stats.registerWrites(rf->name(), reg);
1217 }
1218 }
1220 static_cast<double>(totalRegisterWrites));
1221 return true;
1222
1223 } else {
1227 return false;
1228 }
1229 }
1230};
1231
1232
1233/**
1234 * Implementation of "info program".
1235 */
1237public:
1238 /**
1239 * Constructor.
1240 */
1242 SimControlLanguageSubCommand(parentCommand) {
1243 }
1244
1245 /**
1246 * Destructor.
1247 */
1249 }
1250
1251 /**
1252 * Executes the "info program" command.
1253 *
1254 * Displays information about the status of the program: whether it is
1255 * loaded or running, why it stopped.
1256 *
1257 * @param arguments Arguments to the command, including the command.
1258 * @return true in case execution was successful.
1259 */
1260 virtual bool execute(const std::vector<DataObject>& arguments) {
1261 const int argumentCount = arguments.size() - 2;
1262
1263 if (argumentCount == 0) {
1264
1265 if (parent().simulatorFrontend().isSimulationStopped()) {
1266 parent().outputStream()
1270 << std::endl;
1272 } else if (parent().simulatorFrontend().hasSimulationEnded()) {
1273 parent().outputStream()
1275 Texts::TXT_STATUS_FINISHED).str() << std::endl;
1276 } else if (parent().simulatorFrontend().isSimulationRunning()) {
1278 "It should not be possible to do this while "
1279 "simulation is running!");
1280 } else if (parent().simulatorFrontend().isSimulationInitialized()) {
1282 Texts::TXT_STATUS_INITIALIZED).str() << std::endl;
1283 } else {
1285 Texts::TXT_STATUS_NOT_INITIALIZED).str() << std::endl;
1286 }
1287 return true;
1288
1289 } else if (argumentCount == 3) {
1290
1291 if (!parent().simulatorFrontend().isProgramLoaded()) {
1295 return false;
1296 }
1297
1298 const std::string command =
1299 StringTools::stringToLower(arguments[2].stringValue());
1300
1301 if (command == "is_instruction_reference") {
1302 try {
1303 const int addr = arguments[3].integerValue();
1304 const int move = arguments[4].integerValue();
1305 if (parent().simulatorFrontend().program().instructionAt(addr).
1306 move(move).source().isInstructionAddress()) {
1307 parent().interpreter()->setResult("1");
1308 return true;
1309 } else {
1310 parent().interpreter()->setResult("0");
1311 return true;
1312 }
1313 } catch (const NumberFormatException& e) {
1314 string msg = "Instruction address and move index parameters "
1315 "must be integers.";
1316 parent().interpreter()->setError(msg);
1317 return false;
1318 } catch (const KeyNotFound & e) {
1319 string msg = "Instruction address not found.";
1320 parent().interpreter()->setError(msg);
1321 return false;
1322 } catch (const OutOfRange& e) {
1323 string msg = "Move slot not found.";
1324 parent().interpreter()->setError(msg);
1325 return false;
1326 } catch (const Exception& e) {
1328 "Unexpected exception in 'info program "
1329 "is_instruction_reference' command!");
1330 }
1331 } else {
1335 return false;
1336 }
1337 } else {
1338 if (!(parent().checkArgumentCount(argumentCount, 0, 0) ||
1339 parent().checkArgumentCount(argumentCount, 3, 3))) {
1340 return false;
1341 }
1342 }
1343 // should not end up here
1344 return false;
1345 }
1346};
1347
1348/**
1349 * Implementation of "info breakpoints".
1350 */
1352public:
1353 /**
1354 * Constructor.
1355 */
1359
1360 /**
1361 * Destructor.
1362 */
1364 }
1365
1366 /**
1367 * Executes the "info breakpoints" command.
1368 *
1369 * Prints a table of all breakpoints. Each breakpoint is printed in
1370 * a separate line. If argument is given, only the breakpoint with
1371 * handle num is printed.
1372 *
1373 * @param arguments Arguments to the command, including the command.
1374 * @return true in case execution was successful.
1375 */
1376 virtual bool execute(const std::vector<DataObject>& arguments) {
1377 const int argumentCount = arguments.size() - 2;
1378 if (!parent().checkArgumentCount(argumentCount, 0, 1)) {
1379 return false;
1380 }
1381
1382 if (argumentCount == 1 &&
1383 !parent().checkPositiveIntegerArgument(arguments[2])) {
1384 return false;
1385 }
1386
1387 if (!parent().checkSimulationEnded() &&
1388 !parent().checkSimulationStopped() &&
1389 !parent().checkSimulationInitialized()) {
1390 return false;
1391 }
1392
1393 if (argumentCount == 1) {
1394 unsigned int breakpointHandle =
1395 static_cast<unsigned int>(arguments[2].integerValue());
1396 return parent().printBreakpointInfo(breakpointHandle);
1397 } else {
1398 StopPointManager& bpManager =
1400 for (unsigned int i = 0; i < bpManager.stopPointCount(); ++i) {
1402 }
1403 return true;
1404 }
1405 }
1406};
1407
1408
1409
1410/**
1411 * Constructor.
1412 *
1413 * Sets the name of the command to the base class.
1414 */
1415InfoCommand::InfoCommand(bool isCompiledSimulation) :
1417 isCompiledSimulation_(isCompiledSimulation) {
1418
1419 if (!isCompiledSimulation_) {
1420 subCommands_["breakpoints"] = new InfoBreakpointsCommand(*this);
1421 subCommands_["busses"] = new InfoBussesCommand(*this);
1422 subCommands_["segments"] = new InfoSegmentsCommand(*this);
1423 }
1424
1425 subCommands_["stats"] = new InfoStatsCommand(*this);
1426 subCommands_["registers"] = new InfoRegistersCommand(*this);
1427 subCommands_["proc"] = new InfoProcCommand(*this);
1428 subCommands_["program"] = new InfoProgramCommand(*this);
1429 subCommands_["watches"] = new InfoBreakpointsCommand(*this);
1430 subCommands_["regfiles"] = new InfoRegFilesCommand(*this);
1431 subCommands_["iunits"] = new InfoIunitsCommand(*this);
1432 subCommands_["funits"] = new InfoFunitsCommand(*this);
1433 subCommands_["ports"] = new InfoPortsCommand(*this);
1434 subCommands_["immediates"] = new InfoImmediatesCommand(*this);
1435}
1436
1437/**
1438 * Destructor.
1439 */
1443
1444/**
1445 * Executes the "info" command.
1446 *
1447 * Provides various information of the simulation.
1448 *
1449 * @param arguments Subcommand and possible arguments to the subcommand.
1450 * @return Always true if arguments are valid.
1451 */
1452bool
1453InfoCommand::execute(const std::vector<DataObject>& arguments) {
1454 assert(interpreter() != NULL);
1455
1456 // "info" as such does not do anything, a subcommand is required.
1457 if (!checkArgumentCount(arguments.size() - 1, 1, INT_MAX)) {
1458 return false;
1459 }
1460
1461 SubCommandMap::iterator subCommandPosition =
1462 subCommands_.find(
1463 StringTools::stringToLower(arguments.at(1).stringValue()));
1464 if (subCommandPosition == subCommands_.end()) {
1468 return false;
1469 }
1470
1471 assert((*subCommandPosition).second != NULL);
1472 SimControlLanguageSubCommand& subCommand = *((*subCommandPosition).second);
1473
1474 return subCommand.execute(arguments);
1475}
1476
1477/**
1478 * Returns the help text for this command.
1479 *
1480 * Help text is searched from SimulatorTextGenerator.
1481 *
1482 * @return The help text.
1483 */
1484std::string
#define abortWithError(message)
#define assert(condition)
#define POP_CLANG_DIAGS
#define IGNORE_CLANG_WARNING(X)
find Finds info of the inner loops in the program
CycleCount ClockCycleCount
Alias for ClockCycleCount.
static std::string toHexString(T source, std::size_t digits=0, bool include0x=true)
static std::string toString(const T &source)
bool checkArgumentCount(int argumentCount, int minimum, int maximum)
ScriptInterpreter * interpreter() const
virtual std::string toString() const
virtual ~InfoBreakpointsCommand()
InfoBreakpointsCommand(SimControlLanguageCommand &parentCommand)
virtual bool execute(const std::vector< DataObject > &arguments)
virtual ~InfoBussesCommand()
virtual bool execute(const std::vector< DataObject > &arguments)
InfoBussesCommand(SimControlLanguageCommand &parentCommand)
InfoCommand(bool isCompiledSimulation=false)
virtual std::string helpText() const
bool isCompiledSimulation_
Is it a compiled simulation?
virtual bool execute(const std::vector< DataObject > &arguments)
SubCommandMap subCommands_
storage for subcommands
virtual ~InfoCommand()
InfoFunitsCommand(SimControlLanguageCommand &parentCommand)
virtual ~InfoFunitsCommand()
virtual bool execute(const std::vector< DataObject > &arguments)
virtual bool execute(const std::vector< DataObject > &arguments)
virtual ~InfoImmediatesCommand()
InfoImmediatesCommand(SimControlLanguageCommand &parentCommand)
InfoIunitsCommand(SimControlLanguageCommand &parentCommand)
virtual bool execute(const std::vector< DataObject > &arguments)
virtual ~InfoIunitsCommand()
virtual bool execute(const std::vector< DataObject > &arguments)
InfoPortsCommand(SimControlLanguageCommand &parentCommand)
virtual ~InfoPortsCommand()
virtual bool execute(const std::vector< DataObject > &arguments)
virtual ~InfoProcCommand()
InfoProcCommand(SimControlLanguageCommand &parentCommand)
virtual bool execute(const std::vector< DataObject > &arguments)
virtual ~InfoProgramCommand()
InfoProgramCommand(SimControlLanguageCommand &parentCommand)
virtual ~InfoRegFilesCommand()
InfoRegFilesCommand(SimControlLanguageCommand &parentCommand)
virtual bool execute(const std::vector< DataObject > &arguments)
virtual bool execute(const std::vector< DataObject > &arguments)
InfoRegistersCommand(SimControlLanguageCommand &parentCommand)
virtual ~InfoRegistersCommand()
static std::string registerDescription(const std::string &regName, const SimValue &value)
virtual ~InfoSegmentsCommand()
virtual bool execute(const std::vector< DataObject > &arguments)
InfoSegmentsCommand(SimControlLanguageCommand &parentCommand)
InfoStatsCommand(SimControlLanguageCommand &parentCommand)
virtual ~InfoStatsCommand()
virtual bool execute(const std::vector< DataObject > &arguments)
BusState & busState(const std::string &name)
static void deleteAllValues(MapType &aMap)
const ConcurrentRFAccessIndex & accessDataBase() const
virtual const SimValue & value() const =0
virtual const SimValue & value() const
virtual void setError(bool state)
virtual void setResult(DataObject *result)
virtual bool printBreakpointInfo(unsigned int breakpointHandle)
virtual std::ostream & outputStream()
virtual bool execute(const std::vector< DataObject > &arguments)=0
virtual SimControlLanguageCommand & parent()
int intValue() const
Definition SimValue.cc:895
TCEString hexValue(bool noHexIdentifier=false) const
Definition SimValue.cc:1150
SLongWord sLongWordValue() const
Definition SimValue.cc:997
const TTAMachine::Machine & machine() const
const UtilizationStats & utilizationStatistics(int core=-1)
ClockCycleCount cycleCount() const
MachineState & machineState(int core=-1)
StopPointManager & stopPointManager()
const RFAccessTracker & rfAccessTracker() const
StateData & state(std::string searchString)
virtual SimValue FUPortValue(const std::string &fuName, const std::string &portName)
InstructionAddress programCounter() const
static SimulatorTextGenerator & textGenerator()
unsigned int stopPointCount()
unsigned int stopPointHandle(unsigned int index)
static std::string stringToUpper(const std::string &source)
static std::string stringToLower(const std::string &source)
static bool ciEqual(const std::string &a, const std::string &b)
virtual ULongWord end() const
virtual int width() const
virtual ULongWord start() const
virtual int numberOfRegisters() const
virtual Segment * segment(int index) const
Definition Bus.cc:329
virtual int segmentCount() const
Definition Bus.cc:385
virtual TCEString name() const
virtual HWOperation * operation(const std::string &name) const
virtual int operationCount() const
virtual BaseFUPort * port(const std::string &name) const
const std::string & name() const
ComponentType * item(int index) const
bool hasItem(const std::string &name) const
virtual RegisterFileNavigator registerFileNavigator() const
Definition Machine.cc:450
virtual FunctionUnitNavigator functionUnitNavigator() const
Definition Machine.cc:380
virtual SocketNavigator socketNavigator() const
Definition Machine.cc:368
virtual ImmediateUnitNavigator immediateUnitNavigator() const
Definition Machine.cc:416
virtual BusNavigator busNavigator() const
Definition Machine.cc:356
virtual AddressSpaceNavigator addressSpaceNavigator() const
Definition Machine.cc:392
virtual ControlUnit * controlUnit() const
Definition Machine.cc:345
virtual std::string name() const
Definition Port.cc:141
std::string name() const
virtual int portCount() const
Definition Unit.cc:135
virtual boost::format text(int textId)
std::map< std::string, ComponentUtilizationIndex > FUOperationUtilizationIndex
Index for connecting function unit and operations implemented in them to utilization counts.
ClockCycleCount busWrites(const std::string &busName) const
ClockCycleCount operationExecutions(const std::string &operationName) const
ClockCycleCount triggerCount(const std::string &fuName) const
ClockCycleCount guardRegisterReads(const std::string &rfName, int registerIndex) const
ClockCycleCount registerReads(const std::string &rfName, int registerIndex) const
ClockCycleCount FUGuardAccesses(const std::string &fuName, const std::string &fuPort) const
ClockCycleCount registerWrites(const std::string &rfName, int registerIndex) const
ClockCycleCount socketWrites(const std::string &socketName) const
@ TXT_STATUS_INITIALIZED
Status string of initialized simulation (program loaded).
@ TXT_STATUS_STOPPED
Status string of stopped simulation.
@ TXT_STATUS_NOT_INITIALIZED
Status string of non-initialized simulation (program not loaded).
@ TXT_INTERP_HELP_INFO
Help text for command "info" of the CLI.
@ TXT_STATUS_FINISHED
Status string of a finished simulation.
@ TXT_UNKNOWN_SUBCOMMAND