OpenASIP 2.2
Loading...
Searching...
No Matches
SimulationController.cc
Go to the documentation of this file.
1/*
2 Copyright (c) 2002-2015 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 SimulationController.cc
26 *
27 * Definition of SimulationController class.
28 *
29 * @author Jussi Nykänen 2005 (nykanen-no.spam-cs.tut.fi)
30 * @author Pekka Jääskeläinen 2005-2015 (pjaaskel-no.spam-cs.tut.fi)
31 * @note rating: red
32 */
33
34#include <climits>
35
37#include "Machine.hh"
38#include "MachineState.hh"
39#include "StateLocator.hh"
41#include "SimProgramBuilder.hh"
42#include "Program.hh"
43#include "InstructionMemory.hh"
44#include "GCUState.hh"
46#include "Exception.hh"
47#include "UniversalMachine.hh"
49#include "IdealSRAM.hh"
50#include "DirectAccessMemory.hh"
51#include "Memory.hh"
52#include "MemorySystem.hh"
53#include "FunctionUnit.hh"
54#include "Section.hh"
55#include "DataSection.hh"
56#include "ASpaceElement.hh"
57#include "Instruction.hh"
58#include "Procedure.hh"
60#include "Move.hh"
61#include "Terminal.hh"
62#include "ControlUnit.hh"
63#include "StringTools.hh"
65#include "Operation.hh"
68#include "SimulatorFrontend.hh"
69#include "MemoryProxy.hh"
71#include "RegisterFileState.hh"
72#include "MathTools.hh"
73
74using namespace TTAMachine;
75using namespace TTAProgram;
76
77/**
78 * Constructor.
79 *
80 * @param machine Machine to be simulated.
81 * @param memSys Memory system.
82 * @param fuResourceConflictDetection Should the model detect FU resource
83 * conflicts.
84 * @exception Exception Exceptions while building the simulation models
85 * are thrown forward.
86 */
88 SimulatorFrontend& frontend,
89 const Machine& machine,
90 const Program& program,
91 bool fuResourceConflictDetection,
92 bool detailedSimulation) :
94 tmpExecutedInstructions_(1) {
95
96 if (fuResourceConflictDetection)
98
99 for (int i = 0; i < 1; ++i) {
101 MachineStateBuilder builder(detailedSimulation);
103
104 if (fuResourceConflictDetection) {
105 machineState = builder.build(
107 } else {
109 }
110 // set the real time clock source to be the simulation
111 // cycle counter
112 for (int i = 0; i < machineState->FUStateCount(); ++i) {
113 FUState& fuState = machineState->fuState(i);
115 }
116 machineStates_.push_back(machineState);
117 }
119
120 SimProgramBuilder programBuilder;
121 for (int i = 0; i < 1; ++i) {
123 programBuilder.build(program, *machineStates_[i]);
125 }
126
128 reset();
129}
130
131/**
132 * Destructor.
133 */
140
141/**
142 * Returns a reference to the currently selected machine state model.
143 */
146 if (core == -1) core = frontend_.selectedCore();
147 return *machineStates_.at(core);
148}
149
150/**
151 * Simulates a cycle.
152 *
153 * @return false in case there are no more instructions to execute,
154 * that is, the simulation ended sucessfully, true in case there are
155 * more instructions to execute.
156 */
157bool
159
161
162 // The number of cores that have reached the exit function,
163 // use this to stop automatically after all of them have
164 // called it.
165 unsigned finishedCoreCount = 0;
166 bool finished = false;
167 for (int core = 0; core < 1; ++core) {
169
170 if (machineState->isFinished()) {
171 ++finishedCoreCount;
172 continue;
173 }
174
176 const InstructionAddress& pc = gcu.programCounter();
177
179 try {
181
182 ExecutableInstruction* instruction =
183 &(instructionMemories_[core]->instructionAt(pc));
184
185 instruction->execute();
186
187 tmpExecutedInstructions_[core] = pc;
188
190
191 if (!gcu.isIdle()) {
192 gcu.endClock();
193 }
194
197
198 ++gcu.programCounter();
199 if (!gcu.isIdle())
200 gcu.advanceClock();
201
204
205 // check if the instruction was a return point from the program or
206 // the next executed instruction would be sequentially over the
207 // instruction space (PC+1 would overflow out of the program)
208 if (instruction->isExitPoint() ||
211 ++finishedCoreCount;
212 }
213 } catch (const Exception& e) {
214 frontend_.selectCore(core);
217 e.errorMessage());
219 return false;
220 }
221 }
222
223 if (finishedCoreCount == 1)
224 finished = true;
225
226 // assume all cores have identical memory systems, thus it's enough
227 // to advance the simulation clock only once for the first core's
228 // memory system's shared memory instance
230
231 // detect FU pipeline resource conflicts
232 size_t conflictDetectorVectorSize = conflictDetectorVector_.size();
233 for (std::size_t i = 0; i < conflictDetectorVectorSize; ++i) {
234 FUResourceConflictDetector& detector =
236 if (!detector.isIdle())
237 detector.advanceClock();
238 }
239
241
243
244 ++clockCount_;
245
246 if (finished) {
248 stopRequested_ = true;
249 return false;
250 }
251
254 return true;
255}
256
257/**
258 * Advance simulation by a given amout of cycles.
259 *
260 * @param count The number of cycles the simulation is advanced.
261 * @exception SimulationExecutionError If a runtime error occurs in
262 * the simulated program.
263 */
264void
267 stopReasons_.clear();
269 stopRequested_ = false;
270
271 double counter = 0;
272 while (counter < count && !stopRequested_) {
274 ++counter;
275 }
276
277 if (counter == count) {
279 }
280
281 if (state_ != STA_FINISHED)
283
286}
287
288/**
289 * Advance simulation by a given amout of steps and skip procedure
290 * calls.
291 *
292 * @param count Number of steps to simulate.
293 * @exception SimulationExecutionError If a runtime error occurs in
294 * the simulated program.
295 */
296void
298 stopRequested_ = false;
299 stopReasons_.clear();
301
302 bool inCalledProcedure = false;
303 const Procedure& procedureWhereStartedStepping =
304 dynamic_cast<const Procedure&>(
306
307 int counter = 0;
308 while (!stopRequested_ && counter < count) {
309
310 // simulate cycles until we come back to the procedure we started
311 // simulating from or until the program ends
312 do {
313 const bool programEnded = !simulateCycle();
314
315 if (programEnded) {
317 } else {
318 const Procedure& currentProcedure =
319 dynamic_cast<const Procedure&>(
321 inCalledProcedure =
322 (&procedureWhereStartedStepping != &currentProcedure);
323 }
324 } while (inCalledProcedure && !stopRequested_);
325 ++counter;
326 }
327
328 if (counter == count && !inCalledProcedure) {
330 }
331
332 if (state_ != STA_FINISHED)
334
337}
338
339/**
340 * Advance simulation until a condition for stopping is enabled.
341 *
342 * @exception SimulationExecutionError If a runtime error occurs in
343 * the simulated program.
344 */
345void
360
361/**
362 * Advance simulation until given address is reached.
363 *
364 * @param address The instruction address to reach.
365 * @exception SimulationExecutionError If a runtime error occurs in
366 * the simulated program.
367 */
368void
370 stopRequested_ = false;
371 stopReasons_.clear();
373
374 while (!stopRequested_) {
376
377 if (state_ == STA_FINISHED)
378 return;
379
380 if (selectedMachineState().gcuState().programCounter() == address) {
385 return;
386 }
387 }
388
389 if (state_ != STA_FINISHED) {
391 }
392
395}
396
397void
401
402 std::set<InstructionAddress> exitPoints_ =
404
405 for (std::set<InstructionAddress>::iterator it = exitPoints_.begin();
406 it != exitPoints_.end(); ++it) {
407 for (std::size_t i = 0; i < instructionMemories_.size(); ++i) {
408 instructionMemories_[i]->instructionAt(*it).setExitPoint(true);
409 }
410 }
411}
412
413/**
414 * Resets the simulation so it can be started from the beginning.
415 *
416 * Resets the program counter to its initial value, and also clears the
417 * instrution execution counts and states of possible FU resource conflict
418 * detectors.
419 */
420void
422
424 stopRequested_ = false;
425 clockCount_ = 0;
427
428 for (int core = 0; core < 1; ++core) {
429 machineStates_.at(core)->gcuState().programCounter() = initialPC_;
430 machineStates_.at(core)->setFinished(false);
431 machineStates_.at(core)->resetAllFUs();
432 instructionMemories_.at(core)->resetExecutionCounts();
433 }
434
435 for (std::size_t vec = 0; vec < conflictDetectorVector_.size(); ++vec) {
436 conflictDetectorVector_.at(vec)->reset();
437 }
438}
439
440/**
441 * Returns the program counter value of the currently selected core.
442 */
445 return machineStates_.at(frontend_.selectedCore())->gcuState().programCounter();
446}
447
448/**
449 * Returns a string containing the value(s) of the register file
450 *
451 * @param rfName name of the register file to search for
452 * @param registerIndex index of the register. if -1, all registers are listed
453 * @return A string containing the value(s) of the register file
454 * @exception InstanceNotFound If the register cannot be found.
455 */
456std::string
458 const std::string& rfName, int registerIndex) {
459
460 std::string stringValue("");
461
462 if (registerIndex >= 0) {
463 stringValue += frontend_.findRegister(rfName, registerIndex).value().
464 hexValue();
465 } else {
468 RegisterFile& rf = *navigator.item(rfName);
469
470 bool firstReg = true;
471 for (int i = 0; i < rf.numberOfRegisters(); ++i) {
472 if (!firstReg)
473 stringValue += "\n";
474 const std::string registerName =
475 rfName + "." + Conversion::toString(i);
476
477 SimValue value = frontend_.findRegister(rfName, i).value();
478 stringValue += registerName + " " + value.hexValue();
479
480 firstReg = false;
481 }
482 }
483
484 return stringValue;
485}
486
487/**
488 * Returns the current value of a IU register
489 *
490 * @param iuName name of the immediate unit
491 * @param index index of the register
492 * @return Current value of a IU register
493 */
496 const std::string& iuName, int index) {
497
498 return (selectedMachineState().longImmediateUnitState(iuName)).
499 registerValue(index);
500}
501
502/**
503 * Returns the current value of a FU port
504 *
505 * @param fuName name of the function unit
506 * @param portName name of the FU port
507 * @return Current value of a FU port
508 */
511 const std::string& fuName, const std::string& portName) {
512
513 return (selectedMachineState().portState(portName, fuName)).value();
514}
515
516/**
517 * Builds the FU resource conflict detectors for each FU in the machine.
518 *
519 * Uses the "lazy FSA" detection model.
520 */
521void
524
525
526 for (int core = 0; core < 1; ++core) {
529
531
532 for (int i = 0; i < nav.count(); ++i) {
533 const TTAMachine::FunctionUnit& fu = *nav.item(i);
534 FUResourceConflictDetector* detector =
536 fuConflictDetectors_[core][fu.name()] = detector;
537 conflictDetectorVector_.push_back(detector);
538 }
539 }
540}
541
544 if (core == -1) core = frontend_.selectedCore();
545 return *instructionMemories_.at(core);
546}
547
552
#define assert(condition)
Word UIntWord
Definition BaseType.hh:144
UInt32 InstructionAddress
Definition BaseType.hh:175
TTAMachine::Machine * machine
the architecture definition of the estimated processor
std::map< std::string, FUResourceConflictDetector * > FUConflictDetectorIndex
find Finds info of the inner loops in the program
@ SRE_AFTER_UNTIL
Stopped after running to the wanted.
@ SRE_AFTER_STEPPING
Stopped after stepping the given count.
@ SRE_RUNTIME_ERROR
A fatal runtime error occured in the simulated program.
static std::string toString(const T &source)
std::string errorMessage() const
Definition Exception.cc:123
bool isExitPoint() const
virtual OperationContext & context()
Definition FUState.cc:376
virtual void endClock()
Definition FUState.cc:122
bool isIdle()
virtual void advanceClock()
Definition GCUState.cc:98
InstructionAddress & programCounter()
void handleEvent(int event)
MachineState * build(const TTAMachine::Machine &machine, MemorySystem &memSys)
void advanceClockOfAllLongImmediateUnitStates()
bool isFinished() const
FUState & fuState(const std::string &name)
void endClockOfAllFUStates()
int FUStateCount() const
void advanceClockOfAllFUStates()
void advanceClockOfAllGuardStates()
void clearBuses()
GCUState & gcuState()
void setFinished(bool finished=true)
void advanceClockOfSharedMemories()
void advanceClockOfLocalMemories()
void setCycleCountVariable(CycleCount &cycleCount)
virtual const SimValue & value() const =0
static void deleteAllItems(SequenceType &aSequence)
InstructionMemory * build(const TTAProgram::Program &prog, MachineState &state)
TCEString hexValue(bool noHexIdentifier=false) const
Definition SimValue.cc:1150
std::vector< FUResourceConflictDetector * > conflictDetectorVector_
Resource conflict detectors in a more quickly traversed container.
void findExitPoints(const TTAProgram::Program &program, const TTAMachine::Machine &machine)
MachineStateContainer machineStates_
The machine state models for the simulated cores.
InstructionMemory & selectedInstructionMemory()
virtual void runUntil(UIntWord address)
virtual SimValue immediateUnitRegisterValue(const std::string &iuName, int index=-1)
std::vector< InstructionAddress > tmpExecutedInstructions_
Temporary place for lastExecuted Instruction.
virtual void next(int count=1)
virtual void step(double count=1)
virtual const InstructionMemory & instructionMemory(int core=-1) const
MachineState & selectedMachineState()
virtual std::string registerFileValue(const std::string &rfName, int registerIndex=-1)
virtual InstructionAddress programCounter() const
std::vector< InstructionMemory * > instructionMemories_
The instruction memory models of cores.
virtual MachineState & machineState(int core=-1)
void buildFUResourceConflictDetectors(const TTAMachine::Machine &machine)
SimulationController(SimulatorFrontend &frontend, const TTAMachine::Machine &machine, const TTAProgram::Program &program, bool fuResourceConflictDetection=true, bool detailedSimulation=false)
MultiCoreFUConflictDetectorIndex fuConflictDetectors_
The FU resource conflict detectors used to detect conflicts during simulation.
virtual SimValue FUPortValue(const std::string &fuName, const std::string &portName)
@ SE_NEW_INSTRUCTION
Generated before executing a new instructon.
@ SE_CYCLE_END
Generated before advancing the simulator clock at the end of a simulation cycle.
@ SE_SIMULATION_STOPPED
Generated after simulation has stopped, temporarily or permantently, and control is being returned to...
SimulationEventHandler & eventHandler()
void reportSimulatedProgramError(RuntimeErrorSeverity severity, const std::string &description)
@ RES_FATAL
Fatal runtime error, there is a serious error in the simulated program, thus it makes no sense to go ...
void selectCore(int core)
StateData & findRegister(const std::string &rfName, int registerIndex)
MemorySystem & memorySystem(int coreId=-1)
virtual int numberOfRegisters() const
virtual TCEString name() const
ComponentType * item(int index) const
virtual RegisterFileNavigator registerFileNavigator() const
Definition Machine.cc:450
virtual FunctionUnitNavigator functionUnitNavigator() const
Definition Machine.cc:380
CodeSnippet & parent() const
Instruction & instructionAt(InstructionAddress address) const
Definition Program.cc:374
InstructionAddress initialPC_
The address of the first executed instruction.
StopReasonContainer stopReasons_
The set of reasons the simulation was stopped.
const TTAMachine::Machine & sourceMachine_
The simulated Machine Object Model.
std::vector< InstructionAddress > lastExecutedInstruction_
The address of the last executed instruction.
bool stopRequested_
Flag indicating that simulation should stop.
virtual void prepareToStop(StopReason reason)
@ STA_FINISHED
Simulation ended after executing the last instruction.
@ STA_INITIALIZING
Simulation is being initialized.
@ STA_RUNNING
A run command (run, stepi, until...) given.
@ STA_STOPPED
Simulation stopped for some reason.
@ STA_INITIALIZED
Simulation initialized and ready to run.
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.
const TTAProgram::Program & program_
Program object model of the simulated program.
SimulationStatus state_
The current state of the simulation.
ClockCycleCount clockCount_
How many clock cycles have been simulated.
SimulatorFrontend & frontend_
Reference to the simulator frontend.
virtual MemorySystem & memorySystem(int coreId=-1)