OpenASIP 2.2
Loading...
Searching...
No Matches
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"
47#include "Program.hh"
48#include "Instruction.hh"
49#include "SimulatorFrontend.hh"
50
51using namespace TTAMachine;
52using 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 */
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 */
89void
94
95/**
96 * Returns the count of stop reasons.
97 *
98 * @return The count of stop reasons.
99 */
100unsigned int
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 */
113TTASimulationController::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 */
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 */
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 */
196bool
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 */
208std::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>(
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
#define __func__
UInt32 InstructionAddress
Definition BaseType.hh:175
TTAMachine::Machine * machine
the architecture definition of the estimated processor
find Finds info of the inner loops in the program
CycleCount ClockCycleCount
Alias for ClockCycleCount.
StopReason
The reasons to stop simulation.
MemorySystem & memorySystem(int coreId=-1)
virtual ControlUnit * controlUnit() const
Definition Machine.cc:345
InstructionAddress location() const
virtual Address endAddress() const
virtual Instruction & firstInstruction() const
virtual int instructionCount() const
virtual Address startAddress() const
virtual Instruction & instructionAtIndex(int index) const
Move & move(int i) const
Address address() const
bool isReturn() const
Definition Move.cc:259
TCEString name() const
Definition Procedure.hh:66
StopReasonContainer stopReasons_
The set of reasons the simulation was stopped.
virtual StopReason stopReason(unsigned int index) const
virtual bool automaticFinishImpossible() const
std::vector< InstructionAddress > lastExecutedInstruction_
The address of the last executed instruction.
TTASimulationController(SimulatorFrontend &frontend, const TTAMachine::Machine &machine, const TTAProgram::Program &program)
virtual unsigned int stopReasonCount() const
bool stopRequested_
Flag indicating that simulation should stop.
virtual SimulationStatus state() const
virtual void prepareToStop(StopReason reason)
SimulationStatus
The states of simulation.
virtual SimulatorFrontend & frontend()
virtual std::set< InstructionAddress > findProgramExitPoints(const TTAProgram::Program &program, const TTAMachine::Machine &machine) const
InstructionAddress firstIllegalInstructionIndex_
The index of the first illegal instruction in the instruction sequence.
virtual InstructionAddress lastExecutedInstruction(int coreId=-1) const
SimulationStatus state_
The current state of the simulation.
virtual ClockCycleCount clockCount() const
bool automaticFinishImpossible_
If this is true, simulation cannot be finished automatically.
ClockCycleCount clockCount_
How many clock cycles have been simulated.
SimulatorFrontend & frontend_
Reference to the simulator frontend.
virtual MemorySystem & memorySystem(int coreId=-1)