OpenASIP  2.0
TTASimulationController.cc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2020 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 CompiledSimController.cc
26  *
27  * Definition of TTASimulationController class.
28  *
29  * @author Viljami Korhonen 2008 (viljami.korhonen-no.spam-tut.fi)
30  * @note rating: red
31  */
32 
33 #include <climits>
34 
36 #include "MemorySystem.hh"
37 #include "Machine.hh"
38 #include "IdealSRAM.hh"
39 #include "ControlUnit.hh"
40 #include "MemoryProxy.hh"
41 #include "UniversalMachine.hh"
42 #include "Program.hh"
43 #include "Procedure.hh"
44 #include "InstructionMemory.hh"
45 #include "Move.hh"
46 #include "ExecutableInstruction.hh"
47 #include "Program.hh"
48 #include "Instruction.hh"
49 #include "SimulatorFrontend.hh"
50 
51 using namespace TTAMachine;
52 using namespace TTAProgram;
53 
54 /**
55  * Constructor.
56  *
57  * @exception Exception Exceptions while building the simulation models
58  * are thrown forward.
59  */
61  SimulatorFrontend & frontend,
62  const Machine& machine,
63  const Program& program) :
64  frontend_(frontend),
65  sourceMachine_(machine), program_(program),
66  state_(STA_INITIALIZING), clockCount_(0),
67  lastExecutedInstruction_(1),
68  initialPC_(program.entryAddress().location()),
69  automaticFinishImpossible_(true),
70  firstIllegalInstructionIndex_(UINT_MAX) {
71 }
72 
73 /**
74  * Destructor.
75  */
77 }
78 
79 /**
80  * Get ready to return control to the client.
81  *
82  * Functions name is has "prepare" in its name even though it always
83  * is able to stop the simulation. The reason for this is that it does not
84  * stop the simulation in the middle of simulating a clock cycle, but after
85  * the current clock cycle is simulated.
86  *
87  * @param reason The reason why simulation should be stopped.
88  */
89 void
91  stopRequested_ = true;
92  stopReasons_.insert(reason);
93 }
94 
95 /**
96  * Returns the count of stop reasons.
97  *
98  * @return The count of stop reasons.
99  */
100 unsigned int
102  return stopReasons_.size();
103 }
104 
105 /**
106  * Returns the stop reason with the given index.
107  *
108  * @param index The wanted index.
109  * @return The stop reason at the given index.
110  * @exception OutOfRange If the given index is out of range.
111  */
113 TTASimulationController::stopReason(unsigned int index) const {
114  if (index >= stopReasonCount()) {
115  throw OutOfRange(
116  __FILE__, __LINE__, __func__, "Stop reason index out of range.");
117  }
118  StopReasonContainer::const_iterator i = stopReasons_.begin();
119  unsigned int count = 0;
120  while (i != stopReasons_.end()) {
121  if (index == count) {
122  return (*i);
123  }
124  ++count;
125  ++i;
126  }
127  // dummy to stop compiler from warning
128  throw 0;
129 }
130 
131 /**
132  * Returns the state of the simulation.
133  *
134  * @return The state of the simulation.
135  */
138  return state_;
139 }
140 
141 /**
142  * Returns the address of the last executed instruction.
143  *
144  * @return Address of the last executed instruction.
145  */
148  if (coreId == -1) {
150  } else {
151  return lastExecutedInstruction_[coreId];
152  }
153 }
154 
155 /**
156  * Returns the count of clock cycles simulated.
157  *
158  * @return Count of simulated clock cycles.
159  */
162  return clockCount_;
163 }
164 
165 /**
166  * Returns a reference to the memory system.
167  *
168  * @return A reference to the memory system.
169  */
172  return frontend().memorySystem(coreId);
173 }
174 
175 /**
176  * Returns the simulator frontend.
177  *
178  * @return A reference to the simulator frontend.
179  */
182  return frontend_;
183 }
184 
185 /**
186  * Returns true in case simulation cannot be finished automatically.
187  *
188  * In order for this method to return false, it means that while initializing
189  * the SimulationController, a *probable* ending point in the program was
190  * detected and it is possible that when running the simulation it is possible
191  * to finish it automatically at that position. If this method returns true
192  * it is *impossible* to finish simulation automatically.
193  *
194  * @return True if it's not possible to end simulation automatically.
195  */
196 bool
199 }
200 
201 /**
202  * Initializes the variables that are used in programEnded() to evaluate
203  * whether the simulated program has simulated to its end.
204  *
205  * @param program The simulated program.
206  * @param machine The simulated machine.
207  */
208 std::set<InstructionAddress>
211  const TTAMachine::Machine& machine) const {
212  std::set<InstructionAddress> exitPoints;
213 
214  /* Set return points to be all the returns from the first executed
215  procedure. When control returns from that (usually the crt0(),
216  start(), or main()), we should stop simulation. This is for
217  convenience of simulating unmodified benchmark programs without
218  having infinite loops etc. */
219 
220  // find the entry procedure
221  Address entryAddr = program.entryAddress();
222  Procedure* entryProc = NULL;
223  for(int i = 0; i < program.procedureCount(); i++) {
224  Procedure& currProc = program.procedure(i);
225 
226  if (currProc.startAddress().location() <= entryAddr.location() &&
227  currProc.endAddress().location() > entryAddr.location()) {
228  entryProc = &currProc;
229  break;
230  }
231  }
232 
233  if (entryProc == NULL)
234  throw IllegalProgram(
235  __FILE__, __LINE__, __func__,
236  "The entry point of the program does not point to a procedure.");
237 
238  // If __exit procedure exists, the first instruction in it is set
239  // as an exit point.
240  for(int i = 0; i < program.procedureCount(); i++) {
241  Procedure &currProc = program.procedure(i);
242  if (currProc.name() == "_exit" || currProc.name() == "__exit") {
243  exitPoints.insert(currProc.firstInstruction().address().location());
245  }
246  }
247 
248  const int delaySlots = machine.controlUnit()->delaySlots();
249  // check instructions of entry procedure if they are "ra ->jump.1"
250  for (int i = 0; i < entryProc->instructionCount(); ++i) {
251 
252  const Instruction& currInstr = entryProc->instructionAtIndex(i);
253 
254  // check if the instruction has a return move
255  for (int m = 0; m < currInstr.moveCount(); ++m) {
256 
257  const Move& currMove = currInstr.move(m);
258 
259  if (currMove.isReturn()) {
260  // set an exit point at the return + delay slots to allow
261  // executing the delay slot code of the final return
262  unsigned exitDelay = static_cast<unsigned>(
263  i + machine.controlUnit()->delaySlots());
264  if (exitDelay <= entryProc->endAddress().location()) {
265  exitPoints.insert(
266  entryProc->instructionAtIndex(i + delaySlots).
267  address().location());
268 
270  }
271  break; // check the next instruction
272  }
273  }
274  }
275 
276  /* In case the last instruction of the first procedure is *not*
277  a jump and it's the last procedure in the program, set it as an exit
278  point too (after executing the instruction we should stop simulation
279  because there's nothing sensible to execute next). This is to allow
280  simulating some obscure assembler programs that do not loop
281  forever but just fall through the first procedure after done.
282 
283  The detection in that case is done by comparing the PC+1 to
284  firstIllegalInstructionIndex_. */
285 
286  if (program.procedureCount() == 1) {
287  // such assembly programs are usually stored in one procedure
289  }
291  program.lastInstruction().address().location() + 1;
292 
293  return exitPoints;
294 }
295 
TTASimulationController::memorySystem
virtual MemorySystem & memorySystem(int coreId=-1)
Definition: TTASimulationController.cc:171
TTAProgram
Definition: Estimator.hh:65
TTASimulationController::lastExecutedInstruction
virtual InstructionAddress lastExecutedInstruction(int coreId=-1) const
Definition: TTASimulationController.cc:147
TTAProgram::Program
Definition: Program.hh:63
InstructionAddress
UInt32 InstructionAddress
Definition: BaseType.hh:175
TTAProgram::CodeSnippet::firstInstruction
virtual Instruction & firstInstruction() const
Definition: CodeSnippet.cc:216
TTAProgram::Instruction::move
Move & move(int i) const
Definition: Instruction.cc:193
TTASimulationController::stopReasons_
StopReasonContainer stopReasons_
The set of reasons the simulation was stopped.
Definition: TTASimulationController.hh:144
TTAProgram::Address
Definition: Address.hh:51
machine
TTAMachine::Machine * machine
the architecture definition of the estimated processor
Definition: EstimatorCmdLineUI.cc:59
TTAProgram::Move::isReturn
bool isReturn() const
Definition: Move.cc:259
TTASimulationController::TTASimulationController
TTASimulationController(SimulatorFrontend &frontend, const TTAMachine::Machine &machine, const TTAProgram::Program &program)
Definition: TTASimulationController.cc:60
TTAProgram::Instruction
Definition: Instruction.hh:57
OutOfRange
Definition: Exception.hh:320
Procedure.hh
InstructionMemory.hh
TTASimulationController.hh
TTAProgram::CodeSnippet::startAddress
virtual Address startAddress() const
Definition: CodeSnippet.cc:780
TTASimulationController::automaticFinishImpossible
virtual bool automaticFinishImpossible() const
Definition: TTASimulationController.cc:197
TTASimulationController::prepareToStop
virtual void prepareToStop(StopReason reason)
Definition: TTASimulationController.cc:90
MemorySystem.hh
TTASimulationController::stopReasonCount
virtual unsigned int stopReasonCount() const
Definition: TTASimulationController.cc:101
TTASimulationController::automaticFinishImpossible_
bool automaticFinishImpossible_
If this is true, simulation cannot be finished automatically.
Definition: TTASimulationController.hh:155
SimulatorFrontend::selectedCore
int selectedCore() const
Definition: SimulatorFrontend.hh:257
TTASimulationController::SimulationStatus
SimulationStatus
The states of simulation.
Definition: TTASimulationController.hh:72
TTASimulationController::state_
SimulationStatus state_
The current state of the simulation.
Definition: TTASimulationController.hh:147
TTASimulationController::frontend_
SimulatorFrontend & frontend_
Reference to the simulator frontend.
Definition: TTASimulationController.hh:135
UniversalMachine.hh
TTAMachine::Machine::controlUnit
virtual ControlUnit * controlUnit() const
Definition: Machine.cc:345
Instruction.hh
TTAProgram::CodeSnippet::instructionCount
virtual int instructionCount() const
Definition: CodeSnippet.cc:205
TTASimulationController::state
virtual SimulationStatus state() const
Definition: TTASimulationController.cc:137
TTASimulationController::findProgramExitPoints
virtual std::set< InstructionAddress > findProgramExitPoints(const TTAProgram::Program &program, const TTAMachine::Machine &machine) const
Definition: TTASimulationController.cc:209
IllegalProgram
Definition: Exception.hh:895
__func__
#define __func__
Definition: Application.hh:67
MemoryProxy.hh
TTASimulationController::lastExecutedInstruction_
std::vector< InstructionAddress > lastExecutedInstruction_
The address of the last executed instruction.
Definition: TTASimulationController.hh:151
TTASimulationController::stopRequested_
bool stopRequested_
Flag indicating that simulation should stop.
Definition: TTASimulationController.hh:142
StopReason
StopReason
The reasons to stop simulation.
Definition: SimulatorConstants.hh:60
TTAProgram::Address::location
InstructionAddress location() const
TTAProgram::Move
Definition: Move.hh:55
TTAMachine::ControlUnit::delaySlots
int delaySlots() const
Machine.hh
MemorySystem
Definition: MemorySystem.hh:55
SimulatorFrontend.hh
TTASimulationController::~TTASimulationController
virtual ~TTASimulationController()
Definition: TTASimulationController.cc:76
TTASimulationController::stopReason
virtual StopReason stopReason(unsigned int index) const
Definition: TTASimulationController.cc:113
TTASimulationController::frontend
virtual SimulatorFrontend & frontend()
Definition: TTASimulationController.cc:181
TTASimulationController::clockCount_
ClockCycleCount clockCount_
How many clock cycles have been simulated.
Definition: TTASimulationController.hh:149
TTASimulationController::firstIllegalInstructionIndex_
InstructionAddress firstIllegalInstructionIndex_
The index of the first illegal instruction in the instruction sequence.
Definition: TTASimulationController.hh:158
SimulatorFrontend::memorySystem
MemorySystem & memorySystem(int coreId=-1)
Definition: SimulatorFrontend.cc:2121
Program.hh
TTASimulationController::clockCount
virtual ClockCycleCount clockCount() const
Definition: TTASimulationController.cc:161
IdealSRAM.hh
ControlUnit.hh
ExecutableInstruction.hh
TTAProgram::Procedure::name
TCEString name() const
Definition: Procedure.hh:66
TTAProgram::CodeSnippet::endAddress
virtual Address endAddress() const
Definition: CodeSnippet.cc:788
TTAProgram::CodeSnippet::instructionAtIndex
virtual Instruction & instructionAtIndex(int index) const
Definition: CodeSnippet.cc:285
ClockCycleCount
CycleCount ClockCycleCount
Alias for ClockCycleCount.
Definition: SimulatorConstants.hh:57
program
find Finds info of the inner loops in the program
Definition: InnerLoopFinder.cc:80
Move.hh
TTAMachine
Definition: Assembler.hh:48
TTAProgram::Procedure
Definition: Procedure.hh:55
SimulatorFrontend
Definition: SimulatorFrontend.hh:89
TTAProgram::Instruction::moveCount
int moveCount() const
Definition: Instruction.cc:176
TTAProgram::Instruction::address
Address address() const
Definition: Instruction.cc:327
TTAMachine::Machine
Definition: Machine.hh:73