OpenASIP 2.2
Loading...
Searching...
No Matches
Classes | Public Types | Public Member Functions | Static Public Member Functions | Private Types | Private Member Functions | Static Private Member Functions | Private Attributes | List of all members
CompiledSimCodeGenerator Class Reference

#include <CompiledSimCodeGenerator.hh>

Collaboration diagram for CompiledSimCodeGenerator:
Collaboration graph

Classes

struct  DelayedAssignment
 

Public Types

typedef std::set< std::string > StringSet
 A type for std::string sets.
 
typedef std::map< InstructionAddress, InstructionAddressAddressMap
 A type for storing address-to-address combinations.
 

Public Member Functions

 CompiledSimCodeGenerator (const TTAMachine::Machine &machine, const TTAProgram::Program &program, const TTASimulationController &controller, bool fuResourceConflictDetection, bool handleCycleEnd, bool dynamicCompilation, bool basicBlockPerFile=false, bool functionPerFile=true, const TCEString &globalSymbolPrefix="")
 
virtual ~CompiledSimCodeGenerator ()
 
virtual void generateToDirectory (const std::string &dirName)
 
virtual StringSet createdFiles () const
 
virtual AddressMap basicBlocks () const
 
virtual ProcedureBBRelations procedureBBRelations () const
 

Static Public Member Functions

static TCETools::CIStringSet supportedMemoryOperations ()
 

Private Types

typedef std::multimap< std::string, std::string > OperationSymbolDeclarations
 A type for operation symbol declarations: 1=op.name 2=op.symbol.
 
typedef std::multimap< int, DelayedAssignmentDelayedAssignments
 FU Result writes.
 
typedef std::map< std::string, int > FUResultWrites
 
typedef std::map< std::string, int > SimValueSymbolDeclarations
 Type for SimValue symbol declarations: string=symbolname, int=width.
 
typedef std::map< std::string, int > GuardPipeline
 

Private Member Functions

 CompiledSimCodeGenerator (const CompiledSimCodeGenerator &)
 Copying not allowed.
 
CompiledSimCodeGeneratoroperator= (const CompiledSimCodeGenerator &)
 Assignment not allowed.
 
void generateConstructorParameters ()
 
void generateHeaderAndMainCode ()
 
void generateConstructorCode ()
 
void generateSimulationCode ()
 
void findBasicBlocks () const
 
void generateProcedureCode (const TTAProgram::Procedure &procedure)
 
void generateShutdownCode (InstructionAddress address)
 
void generateFUOutputUpdater ()
 
void generateSimulationGetter ()
 
std::string generateHaltCode (const std::string &message="")
 
void generateAdvanceClockCode ()
 
void updateDeclaredSymbolsList ()
 
void updateSymbolsMap ()
 
void generateSymbolDeclarations ()
 
void generateJumpTableCode ()
 
void generateMakefile ()
 
void addDeclaredSymbol (const std::string &name, int width)
 
void addUsedRFSymbols ()
 
std::string handleJump (const TTAMachine::HWOperation &op)
 
std::string handleOperation (const TTAMachine::HWOperation &op)
 
std::string handleOperationWithoutDag (const TTAMachine::HWOperation &op)
 
std::string detectConflicts (const TTAMachine::HWOperation &op)
 
std::string generateGuardRead (const TTAProgram::Move &move)
 
std::string generateGuardCondition (const TTAProgram::Move &move)
 
void generateInstruction (const TTAProgram::Instruction &instruction)
 
std::string generateTriggerCode (const TTAMachine::HWOperation &op)
 
std::string generateStoreTrigger (const TTAMachine::HWOperation &op)
 
std::string generateLoadTrigger (const TTAMachine::HWOperation &op)
 
bool handleRegisterWrite (const std::string &regSymbolName, std::ostream &stream)
 
std::string guardPipelineTopSymbol (const TTAMachine::RegisterGuard &guard)
 
void generateGuardPipelineVariables (std::ostream &stream)
 
void generateGuardPipelineAdvance (std::ostream &stream)
 
std::string generateAddFUResult (const TTAMachine::FUPort &resultPort, const std::string &value, int latency)
 
std::string generateFUResultRead (const std::string &destination, const std::string &resultSymbol)
 
int maxLatency () const
 
std::vector< TTAMachine::Port * > fuOutputPorts (const TTAMachine::FunctionUnit &fu) const
 

Static Private Member Functions

static bool isStoreOperation (const std::string &opName)
 
static bool isLoadOperation (const std::string &opName)
 

Private Attributes

const TTAMachine::Machinemachine_
 The machine used for simulation.
 
const TTAProgram::Programprogram_
 The simulated program.
 
const TTASimulationControllersimController_
 The simulator frontend.
 
const TTAMachine::ControlUnitgcu_
 GCU.
 
bool handleCycleEnd_
 Should we let frontend handle each cycle end.
 
bool dynamicCompilation_
 Is this a dynamic compiled simulation?
 
bool basicBlockPerFile_
 Should the generator generate only one basic block per code file.
 
bool functionPerFile_
 Should the generator start with a new file after function end.
 
SimValueSymbolDeclarations declaredSymbols_
 A list of all symbols that are declared after the program code is ready.
 
StringSet declaredFunctions_
 A set of all the declared functions.
 
StringSet createdFiles_
 A list of the code files created during the process.
 
OperationSymbolDeclarations usedOperations_
 A list of used operations.
 
int instructionNumber_
 Absolute instruction # being processed.
 
int instructionCounter_
 Istruction counter for checking how many instructions to put per file.
 
int moveCounter_
 How many moves have we been through with?
 
bool isProcedureBegin_
 Are we at the beginning of a new procedure?
 
const TTAProgram::ProcedurecurrentProcedure_
 Pointer to the current Procedure being processed.
 
InstructionAddress lastInstructionOfBB_
 last instruction of the current basic block
 
std::string lastGuardBool_
 name of the last used guard variable
 
std::map< std::string, std::string > usedGuardSymbols_
 Temporary list of the used guard bool symbols per instruction.
 
std::set< InstructionAddressexitPoints_
 Program exit point addresses.
 
AddressMap bbStarts_
 The basic block map referred by start of the block as a key.
 
AddressMap bbEnds_
 The basic block map referred by end of the block as a key.
 
ProcedureBBRelations procedureBBRelations_
 Basic blocks relations to procedures and vice versa.
 
DelayedAssignments delayedFUResultWrites_
 Delayed FU Result assignments.
 
FUResultWrites lastFUWrites_
 Last known FU result writes.
 
OperationPool operationPool_
 The operation pool.
 
std::string targetDirectory_
 Directory where to write the source files of the engine.
 
std::string className_
 Name of the class to be created.
 
std::string headerFile_
 Header filename.
 
std::string mainFile_
 Main source filename. This includes the constructor and the simulateCycle().
 
std::fstream currentFile_
 Current file being processed.
 
std::string currentFileName_
 Name of the current file being processed.
 
std::ostream * os_
 Current output stream i.e. the above file.
 
CompiledSimSymbolGenerator symbolGen_
 The symbol generator.
 
ConflictDetectionCodeGenerator conflictDetectionGenerator_
 Conflict detection code generator.
 
unsigned maxInstructionsPerFile_
 Maximum number of instructions per engine source code file, computed from the instruction width (bus count) to control simulation engine code size explosion with wider simulated machines.
 
unsigned maxInstructionsPerSimulationFunction_
 Max for each simulation function.
 
GuardPipeline guardPipeline_
 
bool needGuardPipeline_
 
TCEString globalSymbolSuffix_
 

Detailed Description

A class that generates C/C++ code from the given POM and MOM

Used for the compiled simulation

Definition at line 99 of file CompiledSimCodeGenerator.hh.

Member Typedef Documentation

◆ AddressMap

A type for storing address-to-address combinations.

Definition at line 104 of file CompiledSimCodeGenerator.hh.

◆ DelayedAssignments

FU Result writes.

Definition at line 148 of file CompiledSimCodeGenerator.hh.

◆ FUResultWrites

typedef std::map<std::string, int> CompiledSimCodeGenerator::FUResultWrites
private

Definition at line 149 of file CompiledSimCodeGenerator.hh.

◆ GuardPipeline

typedef std::map<std::string, int> CompiledSimCodeGenerator::GuardPipeline
private

Definition at line 300 of file CompiledSimCodeGenerator.hh.

◆ OperationSymbolDeclarations

typedef std::multimap<std::string, std::string> CompiledSimCodeGenerator::OperationSymbolDeclarations
private

A type for operation symbol declarations: 1=op.name 2=op.symbol.

Definition at line 145 of file CompiledSimCodeGenerator.hh.

◆ SimValueSymbolDeclarations

typedef std::map<std::string, int> CompiledSimCodeGenerator::SimValueSymbolDeclarations
private

Type for SimValue symbol declarations: string=symbolname, int=width.

Definition at line 226 of file CompiledSimCodeGenerator.hh.

◆ StringSet

typedef std::set<std::string> CompiledSimCodeGenerator::StringSet

A type for std::string sets.

Definition at line 102 of file CompiledSimCodeGenerator.hh.

Constructor & Destructor Documentation

◆ CompiledSimCodeGenerator() [1/2]

CompiledSimCodeGenerator::CompiledSimCodeGenerator ( const TTAMachine::Machine machine,
const TTAProgram::Program program,
const TTASimulationController controller,
bool  fuResourceConflictDetection,
bool  handleCycleEnd,
bool  dynamicCompilation,
bool  basicBlockPerFile = false,
bool  functionPerFile = true,
const TCEString globalSymbolSuffix = "" 
)

The constructor

Gets the settings for compiled simulation code generation.

Parameters
machineThe machine to run the simulation on
programThe simulated program
controllerCompiled Simulation controller
fuResourceConflictDetectionis the conflict detection on?
handleCycleEndshould we let frontend handle each cycle end
basicBlockPerFileShould we generate only one BB per code file?

Definition at line 160 of file CompiledSimCodeGenerator.cc.

169 :
172 handleCycleEnd_(handleCycleEnd),
173 dynamicCompilation_(dynamicCompilation),
174 basicBlockPerFile_(basicBlockPerFile),
175 functionPerFile_(functionPerFile),
177 moveCounter_(0),
180 className_(TCEString("CompiledSimulationEngine_") + globalSymbolSuffix),
181 os_(NULL), symbolGen_(globalSymbolSuffix),
183 machine_, symbolGen_, fuResourceConflictDetection),
184 needGuardPipeline_(false), globalSymbolSuffix_(globalSymbolSuffix) {
185
186 // this should result in roughly 100K-400K .cpp files
188 // roughly 300-600 c++ lines per simulation function
190
191// Create the guardpipeline.
192
194 needGuardPipeline_ = true;
195
196 int ggLatency = machine.controlUnit()->globalGuardLatency();
197
200
201 for (int i = 0; i < busNav.count(); i++) {
202 const TTAMachine::Bus* bus = busNav.item(i);
203 for (int j = 0; j < bus->guardCount(); j++) {
204 Guard* guard = bus->guard(j);
205 RegisterGuard* rg = dynamic_cast<RegisterGuard*>(guard);
206 if (rg != NULL) {
207 const RegisterFile* rf = rg->registerFile();
208 int rgLat = rg->registerFile()->guardLatency();
209 string symbolName =
211 guardPipeline_[symbolName] = ggLatency + rgLat + 1;
212 }
213 }
214 }
215 }
216}
TTAMachine::Machine * machine
the architecture definition of the estimated processor
find Finds info of the inner loops in the program
bool basicBlockPerFile_
Should the generator generate only one basic block per code file.
bool functionPerFile_
Should the generator start with a new file after function end.
const TTAProgram::Program & program_
The simulated program.
const TTAProgram::Procedure * currentProcedure_
Pointer to the current Procedure being processed.
const TTAMachine::ControlUnit & gcu_
GCU.
const TTASimulationController & simController_
The simulator frontend.
bool handleCycleEnd_
Should we let frontend handle each cycle end.
ConflictDetectionCodeGenerator conflictDetectionGenerator_
Conflict detection code generator.
const TTAMachine::Machine & machine_
The machine used for simulation.
bool dynamicCompilation_
Is this a dynamic compiled simulation?
InstructionAddress lastInstructionOfBB_
last instruction of the current basic block
unsigned maxInstructionsPerSimulationFunction_
Max for each simulation function.
std::string className_
Name of the class to be created.
int instructionNumber_
Absolute instruction # being processed.
int instructionCounter_
Istruction counter for checking how many instructions to put per file.
unsigned maxInstructionsPerFile_
Maximum number of instructions per engine source code file, computed from the instruction width (bus ...
CompiledSimSymbolGenerator symbolGen_
The symbol generator.
int moveCounter_
How many moves have we been through with?
bool isProcedureBegin_
Are we at the beginning of a new procedure?
std::ostream * os_
Current output stream i.e. the above file.
std::string registerSymbol(const TTAProgram::Terminal &terminal) const
static int longestGuardLatency(const TTAMachine::Machine &mach)
Guard * guard(int index) const
Definition Bus.cc:456
int guardCount() const
Definition Bus.cc:441
int globalGuardLatency() const
ComponentType * item(int index) const
virtual BusNavigator busNavigator() const
Definition Machine.cc:356
virtual ControlUnit * controlUnit() const
Definition Machine.cc:345
virtual int guardLatency() const
const RegisterFile * registerFile() const

References TTAMachine::Machine::busNavigator(), TTAMachine::Machine::controlUnit(), TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::ControlUnit::globalGuardLatency(), TTAMachine::Bus::guard(), TTAMachine::Bus::guardCount(), TTAMachine::RegisterFile::guardLatency(), guardPipeline_, TTAMachine::Machine::Navigator< ComponentType >::item(), MachineInfo::longestGuardLatency(), machine, maxInstructionsPerFile_, maxInstructionsPerSimulationFunction_, needGuardPipeline_, TTAMachine::RegisterGuard::registerFile(), TTAMachine::RegisterGuard::registerIndex(), CompiledSimSymbolGenerator::registerSymbol(), and symbolGen_.

Here is the call graph for this function:

◆ ~CompiledSimCodeGenerator()

CompiledSimCodeGenerator::~CompiledSimCodeGenerator ( )
virtual

The destructor

Definition at line 221 of file CompiledSimCodeGenerator.cc.

221 {
222}

◆ CompiledSimCodeGenerator() [2/2]

CompiledSimCodeGenerator::CompiledSimCodeGenerator ( const CompiledSimCodeGenerator )
private

Copying not allowed.

Member Function Documentation

◆ addDeclaredSymbol()

void CompiledSimCodeGenerator::addDeclaredSymbol ( const std::string &  name,
int  width 
)
private

Adds a new declared symbol to the map

Parameters
namename of the symbol
widthSimValue width

Definition at line 909 of file CompiledSimCodeGenerator.cc.

909 {
910 declaredSymbols_[name] = width;
911}
SimValueSymbolDeclarations declaredSymbols_
A list of all symbols that are declared after the program code is ready.

References declaredSymbols_.

Referenced by generateHeaderAndMainCode().

◆ addUsedRFSymbols()

void CompiledSimCodeGenerator::addUsedRFSymbols ( )
private

◆ basicBlocks()

CompiledSimCodeGenerator::AddressMap CompiledSimCodeGenerator::basicBlocks ( ) const
virtual

Returns a list of basic blocks of the program

Returns
a list of basic blocks of the program

Definition at line 317 of file CompiledSimCodeGenerator.cc.

317 {
318 if (bbStarts_.empty()) {
320 }
321 return bbEnds_;
322}
AddressMap bbEnds_
The basic block map referred by end of the block as a key.
AddressMap bbStarts_
The basic block map referred by start of the block as a key.

References bbEnds_, bbStarts_, and findBasicBlocks().

Referenced by CompiledSimController::reset().

Here is the call graph for this function:

◆ createdFiles()

CompiledSimCodeGenerator::StringSet CompiledSimCodeGenerator::createdFiles ( ) const
virtual

Returns a list of the created .cpp filenames

Returns
a list of the created .cpp filenames

Definition at line 307 of file CompiledSimCodeGenerator.cc.

307 {
308 return createdFiles_;
309}
StringSet createdFiles_
A list of the code files created during the process.

References createdFiles_.

◆ detectConflicts()

std::string CompiledSimCodeGenerator::detectConflicts ( const TTAMachine::HWOperation op)
private

◆ findBasicBlocks()

void CompiledSimCodeGenerator::findBasicBlocks ( ) const
private

Finds all basic blocks of the program and stores them in two std::maps

Big basic blocks are split to smaller ones to reduce the engine compilation memory consumption.

Definition at line 621 of file CompiledSimCodeGenerator.cc.

621 {
622 for (int i = 0; i < program_.procedureCount(); ++i) {
624 for (int i = 0; i < cfg.nodeCount(); ++i) {
625 BasicBlockNode& node = cfg.node(i);
626 if (!node.isNormalBB()) continue;
627
628 InstructionAddress blockStart = node.originalStartAddress();
629 const InstructionAddress end = node.originalEndAddress();
630
631 if (end - blockStart > maxInstructionsPerSimulationFunction_) {
632 // split the real basic block to smaller ones in case
633 // there are too many instructions (huge basic blocks might
634 // explode the engine compiler memory consumption)
635 InstructionAddress blockEnd = blockStart;
636#if 0
638 << "splitting a bb " << blockStart << " to " << end
639 << " with size " << end - blockStart << std::endl;
640#endif
641 for (; blockStart < end; blockStart = blockEnd + 1) {
642 blockEnd =
643 std::min(
645 end);
646
647 // we must ensure that the branch and its delay slots
648 // end up in the same block due to the way guard
649 // reads are handled as local variables in the simulation
650 // func
651 if (blockEnd + machine_.controlUnit()->delaySlots() >= end) {
652 blockEnd = end;
653 }
654
655 bbEnds_[blockEnd] = blockStart;
656 bbStarts_[blockStart] = blockEnd;
657#if 0
659 << "small block: " << blockStart << " to "
660 << blockEnd << std::endl;
661#endif
662 }
663 // the "leftover" block:
664
665
666 blockStart = blockEnd + 1;
667 if (blockStart <= end) {
668#if 0
670 << "leftover block: " << blockStart << " to "
671 << end << std::endl;
672#endif
673 bbEnds_[end] = blockStart;
674 bbStarts_[blockStart] = end;
675 }
676 } else {
677 bbEnds_[end] = blockStart;
678 bbStarts_[blockStart] = end;
679 }
680 }
681 }
682}
UInt32 InstructionAddress
Definition BaseType.hh:175
static std::ostream & logStream()
bool isNormalBB() const
InstructionAddress originalEndAddress() const
InstructionAddress originalStartAddress() const
Procedure & procedure(int index) const
Definition Program.cc:622
int procedureCount() const
Definition Program.cc:610

References bbEnds_, bbStarts_, TTAMachine::Machine::controlUnit(), TTAMachine::ControlUnit::delaySlots(), BasicBlockNode::isNormalBB(), Application::logStream(), machine_, maxInstructionsPerSimulationFunction_, BoostGraph< GraphNode, GraphEdge >::node(), BoostGraph< GraphNode, GraphEdge >::nodeCount(), BasicBlockNode::originalEndAddress(), BasicBlockNode::originalStartAddress(), TTAProgram::Program::procedure(), TTAProgram::Program::procedureCount(), and program_.

Referenced by basicBlocks(), and generateSimulationCode().

Here is the call graph for this function:

◆ fuOutputPorts()

std::vector< TTAMachine::Port * > CompiledSimCodeGenerator::fuOutputPorts ( const TTAMachine::FunctionUnit fu) const
private

Returns the output ports of a function unit

Parameters
fuThe function unit
Returns
A vector of output ports of a function unit

Definition at line 1788 of file CompiledSimCodeGenerator.cc.

1789 {
1790 std::vector<TTAMachine::Port*> ports;
1791 for (int i = 0; i < fu.portCount(); ++i) {
1792 if (fu.port(i)->isOutput()) {
1793 ports.push_back(fu.port(i));
1794 }
1795 }
1796 return ports;
1797}
virtual BaseFUPort * port(const std::string &name) const
virtual bool isOutput() const
Definition Port.cc:308
virtual int portCount() const
Definition Unit.cc:135

References TTAMachine::Port::isOutput(), TTAMachine::FunctionUnit::port(), and TTAMachine::Unit::portCount().

Referenced by generateFUOutputUpdater(), generateHeaderAndMainCode(), and updateDeclaredSymbolsList().

Here is the call graph for this function:

◆ generateAddFUResult()

std::string CompiledSimCodeGenerator::generateAddFUResult ( const TTAMachine::FUPort resultPort,
const std::string &  value,
int  latency 
)
private

Generates code for adding a result to FU's output port

Handles static latency simulation in case it is possible, otherwise reverts back to older dynamic model.

The case this function tracks is the following:

1) Instruction address > basic block start + latency 2) Trigger not inside a guard 3) Result must be ready in the same basic block 4) No overlapping writes of any kind

Parameters
resultPortFU result port to set the value to
valuevalue to set as a result
latencylatency of the operation
Returns
the generated code for putting the results.

Definition at line 1682 of file CompiledSimCodeGenerator.cc.

1685 {
1686
1687 std::stringstream ss;
1688 const FunctionUnit& fu = *resultPort.parentUnit();
1689 const int writeTime = instructionNumber_ + latency;
1690
1691 AddressMap::iterator bbEnd = bbEnds_.lower_bound(instructionNumber_);
1692
1693 const bool resultInSameBasicBlock = bbEnd->first ==
1694 bbEnds_.lower_bound(writeTime)->first;
1695
1696 const int bbStart = bbEnd->second;
1697 bool staticSimulationPossible = false;
1698 const std::string destination = symbolGen_.portSymbol(resultPort);
1699
1700 int lastWrite = 0;
1701 if (lastFUWrites_.find(destination) != lastFUWrites_.end()) {
1702 lastWrite = lastFUWrites_[destination];
1703 }
1704
1705 // If no more pending results are coming outside or inside the basic block,
1706 // no guard of any kind and result will be ready in the same basic block,
1707 // then static latency simulation can be done.
1708 if ((writeTime >= bbStart + fu.maxLatency())
1709 && lastGuardBool_.empty() && resultInSameBasicBlock
1710 && (writeTime > lastWrite)) {
1711 staticSimulationPossible = true;
1712
1713 for (int i = instructionNumber_ + 1; i < writeTime
1714 && staticSimulationPossible; ++i) {
1715
1717 for (int j = 0; j < instr.moveCount(); ++j) {
1718 if ((instr.move(j).isTriggering() && fu.name()
1719 == instr.move(j).destination().functionUnit().name()) ||
1720 (instr.move(j).source().isGPR() &&
1721 instr.move(j).source().port().name()==resultPort.name())) {
1722 staticSimulationPossible = false;
1723 break;
1724 }
1725 }
1726 }
1727 }
1728
1729 if (staticSimulationPossible) { // Add a new delayed assignment
1730 DelayedAssignment assignment = { value, destination,
1731 symbolGen_.FUResultSymbol(resultPort) };
1732 delayedFUResultWrites_.insert(std::make_pair(writeTime, assignment));
1733 } else { // revert to old dynamic FU result model
1734 ss << "engine.addFUResult(" << symbolGen_.FUResultSymbol(resultPort)
1735 << ", " << "engine.cycleCount_, " << value << ", " << latency << ");";
1736 if (writeTime > lastWrite) {
1737 lastFUWrites_[destination] = writeTime;
1738 }
1739 }
1740
1741 return ss.str();
1742}
DelayedAssignments delayedFUResultWrites_
Delayed FU Result assignments.
std::string lastGuardBool_
name of the last used guard variable
FUResultWrites lastFUWrites_
Last known FU result writes.
std::string portSymbol(const TTAMachine::Port &port) const
std::string FUResultSymbol(const TTAMachine::Port &port) const
FunctionUnit * parentUnit() const
Definition BaseFUPort.cc:96
virtual TCEString name() const
virtual int maxLatency() const
virtual std::string name() const
Definition Port.cc:141
Move & move(int i) const
Terminal & source() const
Definition Move.cc:302
bool isTriggering() const
Definition Move.cc:284
Terminal & destination() const
Definition Move.cc:323
Instruction & instructionAt(InstructionAddress address) const
Definition Program.cc:374
virtual const TTAMachine::FunctionUnit & functionUnit() const
Definition Terminal.cc:251
virtual bool isGPR() const
Definition Terminal.cc:107
virtual const TTAMachine::Port & port() const
Definition Terminal.cc:378

References bbEnds_, delayedFUResultWrites_, TTAProgram::Move::destination(), TTAProgram::Terminal::functionUnit(), CompiledSimSymbolGenerator::FUResultSymbol(), TTAProgram::Program::instructionAt(), instructionNumber_, TTAProgram::Terminal::isGPR(), TTAProgram::Move::isTriggering(), lastFUWrites_, lastGuardBool_, TTAMachine::FunctionUnit::maxLatency(), TTAProgram::Instruction::move(), TTAProgram::Instruction::moveCount(), TTAMachine::Component::name(), TTAMachine::Port::name(), TTAMachine::BaseFUPort::parentUnit(), TTAProgram::Terminal::port(), CompiledSimSymbolGenerator::portSymbol(), program_, TTAProgram::Move::source(), and symbolGen_.

Referenced by generateLoadTrigger(), generateTriggerCode(), and handleOperationWithoutDag().

Here is the call graph for this function:

◆ generateAdvanceClockCode()

void CompiledSimCodeGenerator::generateAdvanceClockCode ( )
private

Generates code for advancing clocks of various items per cycle

Definition at line 783 of file CompiledSimCodeGenerator.cc.

783 {
784 *os_ << endl << "void inline advanceClocks() {" << endl;
785 if (needGuardPipeline_) {
787 }
789
790 *os_ << endl << "}" << endl;
791}
void generateGuardPipelineAdvance(std::ostream &stream)

References ConflictDetectionCodeGenerator::advanceClockCode(), conflictDetectionGenerator_, generateGuardPipelineAdvance(), needGuardPipeline_, and os_.

Referenced by generateHeaderAndMainCode().

Here is the call graph for this function:

◆ generateConstructorCode()

void CompiledSimCodeGenerator::generateConstructorCode ( )
private

Generates code for the class constructor in the main .cpp file.

Definition at line 513 of file CompiledSimCodeGenerator.cc.

513 {
514
515 const string DS = FileSystem::DIRECTORY_SEPARATOR;
516 currentFile_.open((targetDirectory_ + DS + mainFile_).c_str(), fstream::out);
517 createdFiles_.insert(mainFile_);
518 os_ = &currentFile_;
519
521
522 *os_ << "#include \"" << headerFile_ << "\"" << endl << endl;
523
524 // generate forward declarations for simulate functions
525 for (AddressMap::const_iterator it = bbStarts_.begin();
526 it != bbStarts_.end(); ++it) {
527 *os_ << "\t" << "extern \"C\" EXPORT void "
528 << symbolGen_.basicBlockSymbol(it->first)
529 << "(void*);" << endl;
530 }
531
532 *os_ << "EXPORT " << className_ << "::";
533
535
536 *os_ << " : " << endl
537 << "CompiledSimulation(machine, entryAddress, lastInstruction, "
538 << "frontend, controller, memorySystem, dynamicCompilation, "
539 << "procedureBBRelations),"
540 << endl;
541
544
547 for (int i = 0; i < fus.count(); i++) {
548 const FunctionUnit& fu = *fus.item(i);
549 std::string context = symbolGen_.operationContextSymbol(fu);
550
551 *os_ << "\t" << context << ".setCycleCountVariable(cycleCount_);"
552 << endl;
553 // Create a state for each operation
554 for (int j = 0; j < fu.operationCount(); ++j) {
555 std::string operation = symbolGen_.operationSymbol(
556 fu.operation(j)->name(), fu);
557
558 *os_ << "\t" << operation << ".createState(" << context << ");"
559 << endl;
560 }
561
562 // Set a Memory for the context
563 if (fu.addressSpace() != NULL) {
564 *os_ << "\t" << context << ".setMemory(&"
565 << symbolGen_.DAMemorySymbol(fu) << ");" << endl;
566 }
567 }
568
570
572 << "}" << endl << endl;
573
574 // generate simulateCycle() method
575 *os_ << "// Simulation code:" << endl
576 << "EXPORT void " << className_ << "::simulateCycle() {"
577 << endl << endl;
578
579 // Create a jump dispatcher for accessing each basic block start
580 *os_ << "\t// jump dispatcher" << endl
581 << "\tjumpTargetFunc_ = getSimulateFunction(jumpTarget_);" << endl
582 << "\t(jumpTargetFunc_)(this);" << endl << endl;
583
585 << "}" << endl << endl;
586
589}
#define DS
std::fstream currentFile_
Current file being processed.
std::string mainFile_
Main source filename. This includes the constructor and the simulateCycle().
std::string headerFile_
Header filename.
std::string targetDirectory_
Directory where to write the source files of the engine.
std::string basicBlockSymbol(InstructionAddress startAddress) const
std::string DAMemorySymbol(const TTAMachine::FunctionUnit &fu) const
std::string operationSymbol(const std::string &operationName, const TTAMachine::FunctionUnit &fu) const
std::string operationContextSymbol(const TTAMachine::FunctionUnit &fu) const
static const std::string DIRECTORY_SEPARATOR
virtual AddressSpace * addressSpace() const
virtual HWOperation * operation(const std::string &name) const
virtual int operationCount() const
const std::string & name() const
virtual FunctionUnitNavigator functionUnitNavigator() const
Definition Machine.cc:380

References TTAMachine::FunctionUnit::addressSpace(), CompiledSimSymbolGenerator::basicBlockSymbol(), bbStarts_, className_, conflictDetectionGenerator_, TTAMachine::Machine::Navigator< ComponentType >::count(), createdFiles_, currentFile_, CompiledSimSymbolGenerator::DAMemorySymbol(), FileSystem::DIRECTORY_SEPARATOR, CompiledSimSymbolGenerator::disablePrefix(), DS, ConflictDetectionCodeGenerator::extraInitialization(), TTAMachine::Machine::functionUnitNavigator(), generateConstructorParameters(), generateFUOutputUpdater(), generateJumpTableCode(), generateSimulationGetter(), headerFile_, TTAMachine::Machine::Navigator< ComponentType >::item(), machine_, mainFile_, TTAMachine::HWOperation::name(), ConflictDetectionCodeGenerator::notifyOfConflicts(), TTAMachine::FunctionUnit::operation(), CompiledSimSymbolGenerator::operationContextSymbol(), TTAMachine::FunctionUnit::operationCount(), CompiledSimSymbolGenerator::operationSymbol(), os_, symbolGen_, targetDirectory_, updateDeclaredSymbolsList(), and updateSymbolsMap().

Referenced by generateHeaderAndMainCode().

Here is the call graph for this function:

◆ generateConstructorParameters()

void CompiledSimCodeGenerator::generateConstructorParameters ( )
private

Generates the parameter list for the constructor.

Definition at line 497 of file CompiledSimCodeGenerator.cc.

497 {
498 *os_ << className_
499 << "(const TTAMachine::Machine& machine," << endl
500 << "InstructionAddress entryAddress," << endl
501 << "InstructionAddress lastInstruction," << endl
502 << "SimulatorFrontend& frontend," << endl
503 << "CompiledSimController& controller," << endl
504 << "MemorySystem& memorySystem," << endl
505 << "bool dynamicCompilation,"
506 << "ProcedureBBRelations& procedureBBRelations)";
507}

References className_, and os_.

Referenced by generateConstructorCode(), and generateHeaderAndMainCode().

◆ generateFUOutputUpdater()

void CompiledSimCodeGenerator::generateFUOutputUpdater ( )
private

Generates a function that is used to update all FU outputs from the "result buffer".

Definition at line 721 of file CompiledSimCodeGenerator.cc.

721 {
722 // use C-style functions only! (C++ name mangling complicates stuff)
723 *os_ << "/* Updates all FU outputs to correct the visible machine state */" << endl
724 << "extern \"C\" EXPORT void updateFUOutputs_"
725 << globalSymbolSuffix_ << "("
726 << className_ << "& engine) {" << endl;
727
729 for (int i = 0; i < fus.count(); ++i) {
730 const FunctionUnit& fu = *fus.item(i);
731 std::vector<Port*> outPorts = fuOutputPorts(fu);
732 for (size_t j = 0; j < outPorts.size(); ++j) {
733 symbolGen_.enablePrefix("engine.");
734 *os_ << "\t" << generateFUResultRead(
735 symbolGen_.portSymbol(*outPorts.at(j)),
736 symbolGen_.FUResultSymbol(*outPorts.at(j)));
737 }
738 }
739
740 *os_
741 << "}" << endl
742 << endl;
743}
std::string generateFUResultRead(const std::string &destination, const std::string &resultSymbol)
std::vector< TTAMachine::Port * > fuOutputPorts(const TTAMachine::FunctionUnit &fu) const
void enablePrefix(const std::string &prefix)

References className_, TTAMachine::Machine::Navigator< ComponentType >::count(), CompiledSimSymbolGenerator::enablePrefix(), TTAMachine::Machine::functionUnitNavigator(), fuOutputPorts(), CompiledSimSymbolGenerator::FUResultSymbol(), generateFUResultRead(), globalSymbolSuffix_, TTAMachine::Machine::Navigator< ComponentType >::item(), machine_, os_, CompiledSimSymbolGenerator::portSymbol(), and symbolGen_.

Referenced by generateConstructorCode().

Here is the call graph for this function:

◆ generateFUResultRead()

std::string CompiledSimCodeGenerator::generateFUResultRead ( const std::string &  destination,
const std::string &  resultSymbol 
)
private

Generates code for reading FU results from result symbol to result port

Parameters
destinationdestination port symbol
resultSymbolresults symbol
Returns
generated code for getting the result

Definition at line 1752 of file CompiledSimCodeGenerator.cc.

1754 {
1755 std::stringstream ss;
1756
1757 ss << "engine.FUResult(" << destination << ", " << resultSymbol
1758 << ", engine.cycleCount_);" << endl;
1759
1760 return ss.str();
1761}

Referenced by generateFUOutputUpdater(), and generateInstruction().

◆ generateGuardCondition()

string CompiledSimCodeGenerator::generateGuardCondition ( const TTAProgram::Move move)
private

Generates the condition simulation code for a guarded move.

Parameters
moveguarded move
Returns
a std::string containing generated code for the guard check

Definition at line 1089 of file CompiledSimCodeGenerator.cc.

1090 {
1091
1092 std::stringstream ss;
1093 string guardSymbolName;
1094
1095 const TTAMachine::Guard& guard = move.guard().guard();
1096
1097 // Find out the guard type
1098 if (dynamic_cast<const RegisterGuard*>(&guard) != NULL) {
1099 const RegisterGuard& rg = dynamic_cast<const RegisterGuard&>(guard);
1100 const RegisterFile& rf = *rg.registerFile();
1101 guardSymbolName = symbolGen_.registerSymbol(rf, rg.registerIndex());
1102 } else if (dynamic_cast<const PortGuard*>(&guard) != NULL) {
1103 const PortGuard& pg = dynamic_cast<const PortGuard&>(guard);
1104 guardSymbolName = symbolGen_.portSymbol(*pg.port());
1105 } else {
1106 ss << endl << "#error unknown guard type!" << endl;
1107 }
1108
1109 lastGuardBool_ = "";
1110
1111 // Make sure to create only one bool per guard read and store the symbol
1112 if (usedGuardSymbols_.find(guardSymbolName) == usedGuardSymbols_.end()) {
1114 usedGuardSymbols_[guardSymbolName] = lastGuardBool_;
1115 } else {
1116 lastGuardBool_ = usedGuardSymbols_[guardSymbolName];
1117 }
1118
1119 // Handle inverted guards
1120 ss << endl << "if (";
1121 if (guard.isInverted()) {
1123 }
1124 ss << lastGuardBool_ << ") { ";
1125
1126 return ss.str();
1127}
std::map< std::string, std::string > usedGuardSymbols_
Temporary list of the used guard bool symbols per instruction.
virtual bool isInverted() const
FUPort * port() const
const TTAMachine::Guard & guard() const
Definition MoveGuard.cc:86
MoveGuard & guard() const
Definition Move.cc:345

References TTAProgram::Move::guard(), TTAProgram::MoveGuard::guard(), CompiledSimSymbolGenerator::guardBoolSymbol(), TTAMachine::Guard::isInverted(), lastGuardBool_, TTAMachine::PortGuard::port(), CompiledSimSymbolGenerator::portSymbol(), TTAMachine::RegisterGuard::registerFile(), TTAMachine::RegisterGuard::registerIndex(), CompiledSimSymbolGenerator::registerSymbol(), symbolGen_, and usedGuardSymbols_.

Referenced by generateInstruction().

Here is the call graph for this function:

◆ generateGuardPipelineAdvance()

void CompiledSimCodeGenerator::generateGuardPipelineAdvance ( std::ostream &  stream)
private

Definition at line 1799 of file CompiledSimCodeGenerator.cc.

1800 {
1801 for (GuardPipeline::iterator i = guardPipeline_.begin();
1802 i != guardPipeline_.end(); i++) {
1803 const std::string& regName = i->first;
1804 for (int j = i->second -1 ; j > 0; j--) {
1805 stream << "guard_pipeline_" << regName << "_" << j << " = "
1806 << "guard_pipeline_" << regName << "_" << j -1
1807 << ";" << std::endl;
1808 }
1809 }
1810}

References guardPipeline_.

Referenced by generateAdvanceClockCode().

◆ generateGuardPipelineVariables()

void CompiledSimCodeGenerator::generateGuardPipelineVariables ( std::ostream &  stream)
private

Definition at line 1812 of file CompiledSimCodeGenerator.cc.

1813 {
1814 for (GuardPipeline::iterator i = guardPipeline_.begin();
1815 i != guardPipeline_.end(); i++) {
1816 const std::string& regName = i->first;
1817 for (int j = 0; j < i->second ; j++) {
1818 stream << "bool guard_pipeline_" + regName << "_" << j <<
1819 ";" << std::endl;
1820 }
1821 }
1822}

References guardPipeline_.

Referenced by generateHeaderAndMainCode().

◆ generateGuardRead()

string CompiledSimCodeGenerator::generateGuardRead ( const TTAProgram::Move move)
private

Generates code for reading a guard value before an instruction with moves guarded with the value is simulated.

Parameters
moveguarded move
Returns
a std::string containing generated code for the guard check

Definition at line 1035 of file CompiledSimCodeGenerator.cc.

1036 {
1037
1038 std::stringstream ss;
1039 string guardSymbolName;
1040
1041 const TTAMachine::Guard& guard = move.guard().guard();
1042
1043 const TTAMachine::RegisterGuard* rg =
1044 dynamic_cast<const RegisterGuard*>(&guard);
1045 // Find out the guard type
1046 if (rg != NULL) {
1047 const RegisterGuard& rg = dynamic_cast<const RegisterGuard&>(guard);
1048 const RegisterFile& rf = *rg.registerFile();
1049 guardSymbolName = symbolGen_.registerSymbol(rf, rg.registerIndex());
1050 } else if (dynamic_cast<const PortGuard*>(&guard) != NULL) {
1051 const PortGuard& pg = dynamic_cast<const PortGuard&>(guard);
1052 guardSymbolName = symbolGen_.portSymbol(*pg.port());
1053 } else {
1054 ss << endl << "#error unknown guard type!" << endl;
1055 }
1056
1057 lastGuardBool_ = "";
1058
1059 // Make sure to create only one bool per guard read and store the symbol
1060 if (usedGuardSymbols_.find(guardSymbolName) == usedGuardSymbols_.end()) {
1061
1062 // read from the guard pipeline? then use the pipeline ar directly
1063 if (needGuardPipeline_ && rg != NULL) {
1064 std::string guardSym = guardPipelineTopSymbol(*rg);
1065 lastGuardBool_ = usedGuardSymbols_[guardSymbolName] = guardSym;
1066 } else {
1068 usedGuardSymbols_[guardSymbolName] = lastGuardBool_;
1069
1070 // red from the register.
1071 ss << "const bool " << lastGuardBool_ <<
1072 " = !(MathTools::fastZeroExtendTo("
1073 << guardSymbolName << ".uIntWordValue(), " <<
1074 guardSymbolName << ".width()) == 0u);";
1075 }
1076 } else {
1077 lastGuardBool_ = usedGuardSymbols_[guardSymbolName];
1078 }
1079 return ss.str();
1080}
std::string guardPipelineTopSymbol(const TTAMachine::RegisterGuard &guard)

References TTAProgram::Move::guard(), TTAProgram::MoveGuard::guard(), CompiledSimSymbolGenerator::guardBoolSymbol(), guardPipelineTopSymbol(), lastGuardBool_, needGuardPipeline_, TTAMachine::PortGuard::port(), CompiledSimSymbolGenerator::portSymbol(), TTAMachine::RegisterGuard::registerFile(), TTAMachine::RegisterGuard::registerIndex(), CompiledSimSymbolGenerator::registerSymbol(), symbolGen_, and usedGuardSymbols_.

Referenced by generateInstruction().

Here is the call graph for this function:

◆ generateHaltCode()

string CompiledSimCodeGenerator::generateHaltCode ( const std::string &  message = "")
private

Generates code for halting the simulation

Parameters
messageReason for the halt
Returns
generated code for halting the simulation

Definition at line 775 of file CompiledSimCodeGenerator.cc.

775 {
776 return std::string("\thaltSimulation(__FILE__, __LINE__, __FUNCTION__, \""
777 + message + "\");\n");
778}

◆ generateHeaderAndMainCode()

void CompiledSimCodeGenerator::generateHeaderAndMainCode ( )
private

Creates a header file to be used for all the .cpp files and the main source file which includes the constructor and the main simulation loop.

Initializes all variables required by the simulation

Sets up new SimValue variables for all the FUs, registers, FU pipeline stages and so on. Variables are created as member variables.

Definition at line 345 of file CompiledSimCodeGenerator.cc.

345 {
346
347 // Open a new file for the header
348 const string DS = FileSystem::DIRECTORY_SEPARATOR;
350 currentFile_.open(currentFileName_.c_str(), fstream::out);
351 os_ = &currentFile_;
352
354
355 // Generate includes
356 *os_ << "// " << className_ << " Generated automatically by ttasim" << endl
357 << "#ifndef _AUTO_GENERATED_COMPILED_SIMULATION_H_" << endl
358 << "#define _AUTO_GENERATED_COMPILED_SIMULATION_H_" << endl
359 << "#include \"SimValue.hh\"" << endl
360 << "#include \"DirectAccessMemory.hh\"" << endl
361 << "#include \"OSAL.hh\"" << endl
362 << "#include \"Operation.hh\"" << endl
363 << "#include \"OperationPool.hh\"" << endl
364 << "#include \"OperationContext.hh\"" << endl
365 << "#include \"CompiledSimulation.hh\"" << endl
366 << "#include \"BaseType.hh\"" << endl
367 << "#include \"MathTools.hh\"" << endl
369 << endl;
370
371 // Open up class declaration and define some extra member variables
372 *os_ << "class " << className_ << ";" << endl << endl;
373 *os_ << "class " << className_ << " : public CompiledSimulation {" << endl
374 << "public:" << endl;
375
376 // Declare all FUs
378 for (int i = 0; i < fus.count(); ++i) {
379 const FunctionUnit& fu = *fus.item(i);
380
381 // FU Ports
382 for (int j = 0; j < fu.operationPortCount(); ++j) {
383 const FUPort& port = *fu.operationPort(j);
385 }
386
387 // Conflict detectors
390 }
391
392 // Operation contexts
393 *os_ << "\t" << "OperationContext "
394 << symbolGen_.operationContextSymbol(fu) << ";" << endl;
395
396 // Address spaces
397 if (fu.addressSpace() != NULL) {
398 *os_ << "\t" << "DirectAccessMemory& "
399 << symbolGen_.DAMemorySymbol(*fus.item(i)) << ";"
400 << endl;
401 }
402
403 // All operations of the FU
404 for (int j = 0; j < fu.operationCount(); ++j) {
405 string opName = fu.operation(j)->name();
406 *os_ << "\t" << "Operation& "
407 << symbolGen_.operationSymbol(opName, fu) << ";" << endl;
408
409 usedOperations_.insert(
410 std::make_pair(opName, symbolGen_.operationSymbol(opName, fu)));
411 }
412
413 // FU output results
414 std::vector<Port*> outPorts = fuOutputPorts(fu);
415 for (size_t j = 0; j < outPorts.size(); ++j) {
416 *os_ << "\t" << "FUResultType "
417 << symbolGen_.FUResultSymbol(*outPorts.at(j))
418 << ";" << endl;
419 }
420 }
421 *os_ << endl;
422
423 // GCU
425 if (gcu) {
426 for (int i = 0; i < gcu->specialRegisterPortCount(); ++i) {
429 }
430 for (int i = 0; i < gcu->operationPortCount(); ++i) {
431 FUPort& port = *gcu->operationPort(i);
433 }
434 }
435
436 // Declare all IUs
439 for (int i = 0; i < ius.count(); ++i) {
440 const ImmediateUnit& iu = *ius.item(i);
441 for (int j = 0; j < iu.numberOfRegisters(); ++j) {
443 iu.width());
444 }
445 }
446
447 // Register files
450 for (int i = 0; i < rfs.count(); ++i) {
451 const RegisterFile& rf = *rfs.item(i);
452 for (int j = 0; j < rf.numberOfRegisters(); ++j) {
454 rf.width());
455 }
456 }
457
458 // Buses
460 for (int i = 0; i < buses.count(); ++i) {
461 const Bus& bus = *buses.item(i);
463 }
464
465 // guard pipeline
466 if (needGuardPipeline_) {
468 }
469
472 *os_ << ";" << endl;
473
475
476 // Generate dummy destructor
477 *os_ << "EXPORT virtual ~" << className_ << "() { }" << endl << endl;
478 *os_ << "EXPORT virtual void simulateCycle();" << endl << endl << "}; // end class" << endl;
479
480 *os_ << "extern \"C\" EXPORT void updateFUOutputs_"
481 << globalSymbolSuffix_ << "(" << className_ << "&);" << endl;
482
483 *os_ << endl << endl << "#endif // include once" << endl << endl;
484
485 // header written
486 currentFile_.close();
487 currentFileName_.clear();
488 os_ = NULL;
489
491}
std::string currentFileName_
Name of the current file being processed.
void generateGuardPipelineVariables(std::ostream &stream)
OperationSymbolDeclarations usedOperations_
A list of used operations.
void addDeclaredSymbol(const std::string &name, int width)
std::string busSymbol(const TTAMachine::Bus &bus) const
std::string immediateRegisterSymbol(const TTAProgram::Terminal &terminal) const
std::string symbolDeclaration(const TTAMachine::FunctionUnit &fu)
virtual int width() const
virtual int numberOfRegisters() const
virtual int width() const
int width() const
Definition Bus.cc:149
SpecialRegisterPort * specialRegisterPort(int index) const
int specialRegisterPortCount() const
virtual FUPort * operationPort(const std::string &name) const
virtual int operationPortCount() const
virtual RegisterFileNavigator registerFileNavigator() const
Definition Machine.cc:450
virtual ImmediateUnitNavigator immediateUnitNavigator() const
Definition Machine.cc:416

References addDeclaredSymbol(), TTAMachine::FunctionUnit::addressSpace(), TTAMachine::Machine::busNavigator(), CompiledSimSymbolGenerator::busSymbol(), className_, ConflictDetectionCodeGenerator::conflictDetectionEnabled(), conflictDetectionGenerator_, TTAMachine::Machine::controlUnit(), TTAMachine::Machine::Navigator< ComponentType >::count(), currentFile_, currentFileName_, CompiledSimSymbolGenerator::DAMemorySymbol(), FileSystem::DIRECTORY_SEPARATOR, CompiledSimSymbolGenerator::disablePrefix(), DS, TTAMachine::Machine::functionUnitNavigator(), fuOutputPorts(), CompiledSimSymbolGenerator::FUResultSymbol(), generateAdvanceClockCode(), generateConstructorCode(), generateConstructorParameters(), generateGuardPipelineVariables(), generateSymbolDeclarations(), globalSymbolSuffix_, headerFile_, CompiledSimSymbolGenerator::immediateRegisterSymbol(), TTAMachine::Machine::immediateUnitNavigator(), ConflictDetectionCodeGenerator::includes(), TTAMachine::Machine::Navigator< ComponentType >::item(), machine_, TTAMachine::HWOperation::name(), needGuardPipeline_, TTAMachine::BaseRegisterFile::numberOfRegisters(), TTAMachine::FunctionUnit::operation(), CompiledSimSymbolGenerator::operationContextSymbol(), TTAMachine::FunctionUnit::operationCount(), TTAMachine::FunctionUnit::operationPort(), TTAMachine::FunctionUnit::operationPortCount(), CompiledSimSymbolGenerator::operationSymbol(), os_, CompiledSimSymbolGenerator::portSymbol(), TTAMachine::Machine::registerFileNavigator(), CompiledSimSymbolGenerator::registerSymbol(), TTAMachine::ControlUnit::specialRegisterPort(), TTAMachine::ControlUnit::specialRegisterPortCount(), ConflictDetectionCodeGenerator::symbolDeclaration(), symbolGen_, targetDirectory_, usedOperations_, TTAMachine::BaseFUPort::width(), TTAMachine::BaseRegisterFile::width(), and TTAMachine::Bus::width().

Referenced by generateToDirectory().

Here is the call graph for this function:

◆ generateInstruction()

void CompiledSimCodeGenerator::generateInstruction ( const TTAProgram::Instruction instruction)
private

Generates simulation code of the given instruction

Parameters
instructioninstruction to generate the code from

Definition at line 1136 of file CompiledSimCodeGenerator.cc.

1136 {
1137
1138 InstructionAddress address = instruction.address().location();
1139 usedGuardSymbols_.clear();
1140
1141 // Are we at the start of a new basic block?
1142 if (bbStarts_.find(address) != bbStarts_.end()) {
1143 // Should we start with a new file?
1147
1148 if (currentFile_.is_open()) {
1149 currentFile_.close();
1150 }
1151
1152 // Generate a new file to begin to work with
1153 const string DS = FileSystem::DIRECTORY_SEPARATOR;
1155 + symbolGen_.basicBlockSymbol(address) + ".cpp";
1156 currentFile_.open(currentFileName_.c_str(), fstream::out);
1158 os_ = &currentFile_;
1159 *os_ << "// " << className_
1160 << " Generated automatically by ttasim" << endl
1161 << "#include \"" << headerFile_ << "\"" << endl << endl;
1162 }
1163
1164 lastInstructionOfBB_ = bbStarts_.find(address)->second;
1166
1167 // Save basic block<->procedure related information
1168 InstructionAddress procedureStart = currentProcedure_->
1169 startAddress().location();
1170 procedureBBRelations_.procedureStart[address] = procedureStart;
1172 procedureBBRelations_.basicBlockStarts.insert(std::make_pair(
1173 procedureStart, address));
1174
1175 // Start a new C++ function for the basic block
1176 if (isProcedureBegin_) {
1177 *os_ << "/* Procedure " << currentProcedure_->name()
1178 << " */" << endl;
1179 }
1180 *os_ << endl << "extern \"C\" EXPORT void "
1181 << symbolGen_.basicBlockSymbol(address)
1182 << "(void* eng) {" << endl;
1183 *os_ << className_ << "& engine = *(" << className_ << "*)eng;" << endl;
1184 symbolGen_.enablePrefix("engine.");
1185 lastFUWrites_.clear();
1186
1187 // initialize jump target to next BB.
1188 int bbEndAddr = -1;
1189 for (int addr = address; bbEndAddr == -1; addr++) {
1190 if (AssocTools::containsKey(bbEnds_, addr)) {
1191 bbEndAddr = addr;
1192 }
1193 }
1194
1195 *os_ << "/* First instruction of BB - initialize address of next BB"
1196 << " */" << endl;
1197 *os_ << "engine.jumpTarget_ = " << bbEndAddr + 1 << ";" << endl;
1198 }
1199
1200 *os_ << endl << "/* Instruction " << instructionNumber_ << " */" << endl;
1201
1202 // Advance clocks of the conflict detectors
1205 *os_ << "engine.advanceClocks();" << endl;
1206 }
1207
1208 // Do immediate assignments per instruction for FU ports
1209 for (int i = 0; i < instruction.immediateCount(); ++i) {
1210 const Immediate& immediate = instruction.immediate(i);
1211
1212 if (!immediate.destination().isFUPort()) {
1213 continue;
1214 }
1215
1217 int value = immediate.value().value().unsignedValue();
1218 *os_ << " = " << value << "u;";
1219 }
1220
1221 // Get FU Results if there are any ready
1222 std::set<std::string> gotResults; // used to get FU results only once/instr.
1223 DelayedAssignments::iterator it =
1225 while (it != delayedFUResultWrites_.end()) {
1226 *os_ << "engine.clearFUResults(" << it->second.fuResultSymbol << ");" << endl;
1227 *os_ << it->second.targetSymbol << " = " << it->second.sourceSymbol
1228 << ";" << std::endl;
1229 gotResults.insert(it->second.targetSymbol);
1230 delayedFUResultWrites_.erase(it);
1232 }
1233
1234 bool endGuardBracket = false;
1235
1236 // Do moves
1237 std::vector<CompiledSimMove> lateMoves; // moves with buses
1238
1239 // generate the possible guard value reads before the
1240 // actual moves
1241 for (int i = 0; i < instruction.moveCount(); ++i) {
1242 const Move& move = instruction.move(i);
1243 if (!move.isUnconditional()) {
1244 *os_ << generateGuardRead(move) << std::endl;
1245 }
1246 }
1247
1248 for (int i = 0; i < instruction.moveCount(); ++i, moveCounter_++) {
1249 const Move& move = instruction.move(i);
1250 string moveSource = symbolGen_.moveOperandSymbol(
1251 move.source(), move);
1252 string moveDestination = symbolGen_.moveOperandSymbol(
1253 move.destination(), move);
1254
1255 lastGuardBool_.clear();
1256
1257 if (move.source().isFUPort() && gotResults.find(moveSource) == gotResults.end() &&
1258 dynamic_cast<const ControlUnit*>(&move.source().functionUnit()) == NULL) {
1259 *os_
1261 moveSource, symbolGen_.FUResultSymbol(move.source().port()))
1262 << endl;
1263 gotResults.insert(moveSource);
1264 }
1265
1266 if (!move.isUnconditional()) { // has a guard?
1267 *os_ << generateGuardCondition(move);
1268 endGuardBracket = true;
1269 }
1270
1271 // increase move count if the move is guarded or it is an exit point
1272 if (!move.isUnconditional() || exitPoints_.find(
1273 instruction.address().location()) != exitPoints_.end()) {
1274 *os_ << " ++engine.moveExecCounts_[" << moveCounter_ << "]; ";
1275 }
1276
1277 // Find all moves that depend on others i.e. those moves that have to
1278 // be done last.
1279 bool dependingMove = false;
1280 for (int j = instruction.moveCount() - 1; j > 0 && i != j; --j) {
1281 if (moveDestination == symbolGen_.moveOperandSymbol(
1282 instruction.move(j).source(), move)) {
1283 dependingMove = true;
1284 CompiledSimMove lateMove(move, lastGuardBool_, symbolGen_);
1285 lateMoves.push_back(lateMove);
1286 *os_ << lateMove.copyToBusCode();
1287 }
1288 }
1289
1290 // Assign the values directly instead of through
1291 // the SimValue assignment in case:
1292 if ((move.source().isGPR() || move.source().isFUPort()
1293 || move.source().isImmediateRegister()) &&
1294 (move.source().port().width() <= static_cast<int>(sizeof(UIntWord)*8)) &&
1295 move.source().port().width() == move.destination().port().width()) {
1296 if (move.source().isImmediateRegister() && move.source().immediateUnit().signExtends()) {
1297 moveSource += ".sIntWordValue()";
1298 } else {
1299 moveSource += ".uIntWordValue()";
1300 }
1301 }
1302
1303 if (!dependingMove) {
1304 *os_ << moveDestination << " = " << moveSource << "; ";
1305 if (needGuardPipeline_) {
1306 handleRegisterWrite(moveDestination, *os_);
1307 }
1308 }
1309
1310 if (endGuardBracket) {
1311 *os_ << "}";
1312 endGuardBracket = false;
1313 }
1314 }
1315
1316 endGuardBracket = false;
1317
1318 // Do moves with triggers, except stores.
1319 for (int i = 0; i < instruction.moveCount(); ++i) {
1320 const Move& move = instruction.move(i);
1321 if (!move.isTriggering()) {
1322 continue;
1323 }
1324
1325 const TerminalFUPort& tfup =
1326 static_cast<const TerminalFUPort&>(move.destination());
1327 const HWOperation& hwOperation = *tfup.hwOperation();
1328
1329 if (isStoreOperation(hwOperation.name())) {
1330 continue;
1331 }
1332
1333 string moveSource = symbolGen_.moveOperandSymbol(
1334 move.source(), move);
1335 string moveDestination = symbolGen_.moveOperandSymbol(
1336 move.destination(), move);
1337
1338 if (!move.isUnconditional()) { // has a guard?
1339 *os_ << generateGuardCondition(move);
1340 endGuardBracket = true;
1341 }
1342
1343 if (move.source().isFUPort() && gotResults.find(moveSource) ==
1344 gotResults.end() && dynamic_cast<const ControlUnit*>(
1345 &move.source().functionUnit()) == NULL) {
1346 *os_
1348 moveDestination,
1350 << endl;
1351
1352 gotResults.insert(
1353 symbolGen_.moveOperandSymbol(move.source(), move));
1354 }
1355
1356 *os_ << handleOperation(hwOperation)
1358
1359 if (endGuardBracket) {
1360 *os_ << "}" << endl;
1361 endGuardBracket = false;
1362 }
1363 } // end for
1364
1365
1366
1367
1368 // Do moves with store triggers.
1369 for (int i = 0; i < instruction.moveCount(); ++i) {
1370 const Move& move = instruction.move(i);
1371 if (!move.isTriggering()) {
1372 continue;
1373 }
1374
1375 const TerminalFUPort& tfup =
1376 static_cast<const TerminalFUPort&>(move.destination());
1377 const HWOperation& hwOperation = *tfup.hwOperation();
1378
1379 if (!isStoreOperation(hwOperation.name())) {
1380 continue;
1381 }
1382
1383 string moveSource = symbolGen_.moveOperandSymbol(
1384 move.source(), move);
1385 string moveDestination = symbolGen_.moveOperandSymbol(
1386 move.destination(), move);
1387
1388 if (!move.isUnconditional()) { // has a guard?
1389 *os_ << generateGuardCondition(move);
1390 endGuardBracket = true;
1391 }
1392
1393 if (move.source().isFUPort() && gotResults.find(moveSource) ==
1394 gotResults.end() && dynamic_cast<const ControlUnit*>(
1395 &move.source().functionUnit()) == NULL) {
1396 *os_
1398 moveDestination,
1400 << endl;
1401
1402 gotResults.insert(
1403 symbolGen_.moveOperandSymbol(move.source(), move));
1404 }
1405
1406 *os_ << handleOperation(hwOperation)
1408
1409 if (endGuardBracket) {
1410 *os_ << "}" << endl;
1411 endGuardBracket = false;
1412 }
1413 } // end for
1414
1415
1416
1417 // Do immediate assignments for everything else
1418 for (int i = 0; i < instruction.immediateCount(); ++i) {
1419 const Immediate& immediate = instruction.immediate(i);
1420
1421 if (immediate.destination().isFUPort()) {
1422 continue;
1423 }
1424
1426 if (immediate.destination().immediateUnit().signExtends()) {
1427 int value = immediate.value().value().intValue();
1428 *os_ << " = SIntWord("<< value << ");";
1429 } else {
1430 unsigned int value = immediate.value().value().unsignedValue();
1431 *os_ << " = " << value << "u;";
1432 }
1433 }
1434
1435 // Do bus moves
1436 for (std::vector<CompiledSimMove>::const_iterator it = lateMoves.begin();
1437 it != lateMoves.end(); ++it) {
1438 *os_ << it->copyFromBusCode();
1439 if (needGuardPipeline_) {
1440 if (it->destination().isGPR()) {
1442 symbolGen_.registerSymbol(it->destination()), *os_);
1443 }
1444 }
1445 }
1446
1447 // No operation?
1448 if (instruction.moveCount() == 0 && instruction.immediateCount() == 0) {
1449 *os_ << "/* NOP */" << endl;
1450 }
1451
1452 // Let frontend handle cycle end?
1453 if (handleCycleEnd_) {
1454 *os_ << "engine.cycleEnd();" << endl;
1455 }
1456
1457 *os_ << "engine.cycleCount_++;" << endl;
1458
1459 AddressMap::iterator bbEnd = bbEnds_.find(address);
1460
1461 // Increase basic block execution count
1462 if (bbEnd != bbEnds_.end()) {
1463 InstructionAddress bbStart =
1464 bbEnds_.lower_bound(instructionNumber_)->second;
1465 *os_ << "++engine.bbExecCounts_[" << bbStart << "];" << endl;
1466 }
1467
1468 // generate exit code if this is a return instruction
1469 if (exitPoints_.find(address) != exitPoints_.end()) {
1470 generateShutdownCode(address);
1471 }
1472
1473 // Create code for a possible exit after the basic block
1474 if (bbEnd != bbEnds_.end()) {
1475 *os_
1476 << "if (engine.cycleCount_ >= engine.cyclesToSimulate_) {" << endl
1477 << "\t" << "engine.stopRequested_ = true;" << endl
1478 << "\t" << "updateFUOutputs_" << globalSymbolSuffix_
1479 << "(engine);" << endl
1480 << "}" << endl;
1481
1482 *os_ << "{ engine.programCounter_ = engine.jumpTarget_; "
1483 << "engine.lastExecutedInstruction_ = " << address
1484 << "; return; }" << endl;
1485 // Generate shutdown code after the last instruction
1486 if (address == program_.lastInstruction().address().location()) {
1487 generateShutdownCode(address);
1488 }
1489
1490 *os_ << endl << "} /* end function */" << endl << endl;
1491 }
1492}
Word UIntWord
Definition BaseType.hh:144
static bool containsKey(const ContainerType &aContainer, const KeyType &aKey)
std::string generateGuardRead(const TTAProgram::Move &move)
std::set< InstructionAddress > exitPoints_
Program exit point addresses.
std::string handleOperation(const TTAMachine::HWOperation &op)
std::string generateGuardCondition(const TTAProgram::Move &move)
void generateShutdownCode(InstructionAddress address)
bool handleRegisterWrite(const std::string &regSymbolName, std::ostream &stream)
static bool isStoreOperation(const std::string &opName)
ProcedureBBRelations procedureBBRelations_
Basic blocks relations to procedures and vice versa.
StringSet declaredFunctions_
A set of all the declared functions.
std::string moveOperandSymbol(const TTAProgram::Terminal &terminal, const TTAProgram::Move &move) const
std::string detectConflicts(const TTAMachine::HWOperation &op)
int intValue() const
Definition SimValue.cc:895
unsigned int unsignedValue() const
Definition SimValue.cc:919
virtual int width() const =0
InstructionAddress location() const
TerminalImmediate & value() const
Definition Immediate.cc:103
const Terminal & destination() const
Definition Immediate.cc:92
Address address() const
Immediate & immediate(int i) const
bool isUnconditional() const
Definition Move.cc:154
TCEString name() const
Definition Procedure.hh:66
Instruction & lastInstruction() const
Definition Program.cc:463
virtual const TTAMachine::HWOperation * hwOperation() const
virtual SimValue value() const
virtual bool isImmediateRegister() const
Definition Terminal.cc:97
virtual const TTAMachine::ImmediateUnit & immediateUnit() const
Definition Terminal.cc:240
virtual bool isFUPort() const
Definition Terminal.cc:118
std::map< InstructionAddress, std::string > basicBlockFiles
Basic block starts and their corresponding .cpp files.
std::map< InstructionAddress, InstructionAddress > procedureStart
Procedure start per basic block starts.
BasicBlockStarts basicBlockStarts
All basic block start addresses per procedure start.

References TTAProgram::Instruction::address(), ProcedureBBRelations::basicBlockFiles, basicBlockPerFile_, ProcedureBBRelations::basicBlockStarts, CompiledSimSymbolGenerator::basicBlockSymbol(), bbEnds_, bbStarts_, className_, ConflictDetectionCodeGenerator::conflictDetectionEnabled(), conflictDetectionGenerator_, AssocTools::containsKey(), CompiledSimMove::copyToBusCode(), createdFiles_, currentFile_, currentFileName_, currentProcedure_, declaredFunctions_, delayedFUResultWrites_, TTAProgram::Immediate::destination(), TTAProgram::Move::destination(), ConflictDetectionCodeGenerator::detectConflicts(), FileSystem::DIRECTORY_SEPARATOR, DS, CompiledSimSymbolGenerator::enablePrefix(), exitPoints_, functionPerFile_, TTAProgram::Terminal::functionUnit(), CompiledSimSymbolGenerator::FUResultSymbol(), generateFUResultRead(), generateGuardCondition(), generateGuardRead(), generateShutdownCode(), globalSymbolSuffix_, handleCycleEnd_, handleOperation(), handleRegisterWrite(), headerFile_, TTAProgram::TerminalFUPort::hwOperation(), TTAProgram::Instruction::immediate(), TTAProgram::Instruction::immediateCount(), CompiledSimSymbolGenerator::immediateRegisterSymbol(), TTAProgram::Terminal::immediateUnit(), instructionCounter_, instructionNumber_, SimValue::intValue(), TTAProgram::Terminal::isFUPort(), TTAProgram::Terminal::isGPR(), TTAProgram::Terminal::isImmediateRegister(), isProcedureBegin_, isStoreOperation(), TTAProgram::Move::isTriggering(), TTAProgram::Move::isUnconditional(), lastFUWrites_, lastGuardBool_, TTAProgram::Program::lastInstruction(), lastInstructionOfBB_, TTAProgram::Address::location(), maxInstructionsPerFile_, TTAProgram::Instruction::move(), TTAProgram::Instruction::moveCount(), moveCounter_, CompiledSimSymbolGenerator::moveOperandSymbol(), TTAMachine::HWOperation::name(), TTAProgram::Procedure::name(), needGuardPipeline_, os_, TTAProgram::Terminal::port(), procedureBBRelations_, ProcedureBBRelations::procedureStart, program_, CompiledSimSymbolGenerator::registerSymbol(), TTAMachine::ImmediateUnit::signExtends(), TTAProgram::Move::source(), symbolGen_, targetDirectory_, SimValue::unsignedValue(), usedGuardSymbols_, TTAProgram::Immediate::value(), TTAProgram::TerminalImmediate::value(), and TTAMachine::Port::width().

Referenced by generateProcedureCode().

Here is the call graph for this function:

◆ generateJumpTableCode()

void CompiledSimCodeGenerator::generateJumpTableCode ( )
private

Generates code that updates the jump table and finds out all the basic blocks

Definition at line 889 of file CompiledSimCodeGenerator.cc.

889 {
890 *os_ << "\t" << "resizeJumpTable(lastInstruction_ + 1);" << endl;
891
892 // If static simulation, set all jump targets in the constructor.
893 if (!dynamicCompilation_) {
894 for (AddressMap::const_iterator it = bbStarts_.begin();
895 it != bbStarts_.end(); ++it) {
896 *os_ << "\t" << "setJumpTargetFunction(" << it->first << ", &"
897 << symbolGen_.basicBlockSymbol(it->first) << ");" << endl;
898 }
899 }
900}

References CompiledSimSymbolGenerator::basicBlockSymbol(), bbStarts_, dynamicCompilation_, os_, and symbolGen_.

Referenced by generateConstructorCode().

Here is the call graph for this function:

◆ generateLoadTrigger()

string CompiledSimCodeGenerator::generateLoadTrigger ( const TTAMachine::HWOperation op)
private

Generates a faster version of specific load triggers

Parameters
opThe load operation (either ldw, ldq, ldh, ldhu, or ldqu)

Definition at line 1617 of file CompiledSimCodeGenerator.cc.

1618 {
1619 const FunctionUnit& fu = *op.parentUnit();
1620 std::stringstream ss;
1621 string address = symbolGen_.portSymbol(*op.port(1)) + ".uLongWordValue()";
1622 string memory = symbolGen_.DAMemorySymbol(op.parentUnit()->name());
1623 string MAUSize = Conversion::toString(fu.addressSpace()->width());
1624 string method;
1625 string extensionMode = "SIGN_EXTEND";
1626 string resultSignExtend;
1627 string temp = symbolGen_.generateTempVariable();
1628
1629 const MemoryOperationDescription& memOpDesc = supportedMemoryOps.at(
1630 op.name());
1631 method = "fastRead";
1632 if (memOpDesc.mauCount > 1) {
1633 method += std::to_string(memOpDesc.mauCount) + "MAUs";
1634 if (memOpDesc.mauOrder == MAUOrder::littleEndian) {
1635 method += "LE";
1636 } else { // big-endian
1637 method += "BE";
1638 }
1639 } else {
1640 method += "MAU";
1641 }
1642
1643 if (memOpDesc.extensionMode == ExtensionMode::sign) {
1644 extensionMode = "SIGN_EXTEND";
1645 } else {
1646 extensionMode = "ZERO_EXTEND";
1647 }
1648
1649 resultSignExtend = temp + " = " + extensionMode
1650 + "(" + temp + ", (" + MAUSize + "*"
1651 + std::to_string(memOpDesc.mauCount) +"));";
1652
1653 ss << "ULongWord " << temp << "; " << memory + "." << method << "("
1654 << address << ", " << temp << "); ";
1655
1656 ss << resultSignExtend << " ";
1657
1658 ss << generateAddFUResult(*op.port(2), temp, op.latency());
1659
1660 return ss.str();
1661}
std::string generateAddFUResult(const TTAMachine::FUPort &resultPort, const std::string &value, int latency)
static std::string toString(const T &source)
virtual int width() const
virtual FUPort * port(int operand) const
FunctionUnit * parentUnit() const

References TTAMachine::FunctionUnit::addressSpace(), CompiledSimSymbolGenerator::DAMemorySymbol(), generateAddFUResult(), CompiledSimSymbolGenerator::generateTempVariable(), TTAMachine::HWOperation::latency(), TTAMachine::HWOperation::name(), TTAMachine::Component::name(), TTAMachine::HWOperation::parentUnit(), TTAMachine::HWOperation::port(), CompiledSimSymbolGenerator::portSymbol(), symbolGen_, Conversion::toString(), and TTAMachine::AddressSpace::width().

Referenced by generateTriggerCode().

Here is the call graph for this function:

◆ generateMakefile()

void CompiledSimCodeGenerator::generateMakefile ( )
private

Generates a Makefile for compiling the simulation engine.

Definition at line 245 of file CompiledSimCodeGenerator.cc.

245 {
246
249
250 std::ofstream makefile(currentFileName_.c_str());
251 std::vector<std::string> includePaths = Environment::includeDirPaths();
252 std::string includes;
253 for (std::vector<std::string>::iterator it = includePaths.begin();
254 it != includePaths.end(); ++it) {
255 includes += "-I" + *it + " ";
256 }
257
258 makefile
259 << "sources = $(wildcard *.cpp)" << endl
260 << "objects = $(patsubst %.cpp,%.o,$(sources))" << endl
261 << "dobjects = $(patsubst %.cpp,%.so,$(sources))" << endl
262 << "includes = " << includes << endl
263 << "soflags = " << CompiledSimCompiler::COMPILED_SIM_SO_FLAGS << endl
264
265 // use because ccache doesn't like changing directory paths
266 // (in a preprocessor comment)
267 << "cppflags = " << CompiledSimCompiler::COMPILED_SIM_CPP_FLAGS << endl
268 << endl
269
270 << "all: CompiledSimulationEngine.so" << endl << endl
271
272 << "CompiledSimulationEngine.so: CompiledSimulationEngine.hh.gch "
273 << "$(dobjects) CompiledSimulationEngine.cc" << endl
274 << "\t#@echo Compiling CompiledSimulationEngine.so" << endl
275 << "\t$(CC) $(cppflags) -O0 $(includes) CompiledSimulationEngine.cc "
276 << "-c -o CompiledSimulationEngine.o" << endl
277 << "\t$(CC) $(soflags) CompiledSimulationEngine.o -o CompiledSimulationEngine.so"
278 << endl << endl
279 << "$(dobjects): %.so: %.cpp CompiledSimulationEngine.hh.gch" << endl
280
281 // compile and link phases separately to allow distributed compilation
282 // thru distcc
283 << "\t$(CC) -c $(cppflags) $(opt_flags) $(includes) $< -o $@.o" << endl
284 << "\t$(CC) $(soflags) $(opt_flags) -lgcc $@.o -o $@" << endl
285 << "\t@rm -f $@.so.o" << endl
286 << endl
287
288 // use precompiled headers for more speed
289 << "CompiledSimulationEngine.hh.gch:" << endl
290 << "\t$(CC) $(cppflags) $(opt_flags) $(includes) "
291 << "-xc++-header CompiledSimulationEngine.hh" << endl
292 << endl
293
294 << "clean:" << endl
295 << "\t@rm -f $(dobjects) CompiledSimulationEngine.so CompiledSimulationEngine.hh.gch" << endl;
296
297 makefile.close();
298 currentFileName_.clear();
299}
static const char * COMPILED_SIM_SO_FLAGS
flags used when compiling .so files
static const char * COMPILED_SIM_CPP_FLAGS
cpp flags used for compiled simulation
static std::vector< std::string > includeDirPaths()

References CompiledSimCompiler::COMPILED_SIM_CPP_FLAGS, CompiledSimCompiler::COMPILED_SIM_SO_FLAGS, currentFileName_, FileSystem::DIRECTORY_SEPARATOR, Environment::includeDirPaths(), and targetDirectory_.

Referenced by generateToDirectory().

Here is the call graph for this function:

◆ generateProcedureCode()

void CompiledSimCodeGenerator::generateProcedureCode ( const TTAProgram::Procedure procedure)
private

Generates code for each instruction in a procedure

Parameters
procedurethe procedure to generate code from
Exceptions
InstanceNotFoundif the first instruction wasn't found

Definition at line 691 of file CompiledSimCodeGenerator.cc.

691 {
692 currentProcedure_ = &procedure;
693 isProcedureBegin_ = true;
694 for (int i = 0; i < procedure.instructionCount(); i++) {
695 Instruction& instruction = procedure.instructionAtIndex(i);
696 generateInstruction(instruction);
699 isProcedureBegin_ = false;
700 }
701}
void generateInstruction(const TTAProgram::Instruction &instruction)
virtual int instructionCount() const
virtual Instruction & instructionAtIndex(int index) const

References currentProcedure_, generateInstruction(), TTAProgram::CodeSnippet::instructionAtIndex(), TTAProgram::CodeSnippet::instructionCount(), instructionCounter_, instructionNumber_, and isProcedureBegin_.

Referenced by generateSimulationCode().

Here is the call graph for this function:

◆ generateShutdownCode()

void CompiledSimCodeGenerator::generateShutdownCode ( InstructionAddress  address)
private

Generates shutdown code for the given instruction address

Parameters
addressAddress location of the instruction. Will be saved in the PC

Definition at line 710 of file CompiledSimCodeGenerator.cc.

710 {
711 *os_ << "/* PROGRAM EXIT */" << endl
712 << "engine.programCounter_ = " << address << ";" << endl
713 << "engine.isFinished_ = true; return;" << endl;
714}

References os_.

Referenced by generateInstruction().

◆ generateSimulationCode()

void CompiledSimCodeGenerator::generateSimulationCode ( )
private

Generates the simulateCycle() function that is called outside the .so file

The generated function simulates one basic block at a time by calling the according basic block methods.

Definition at line 598 of file CompiledSimCodeGenerator.cc.

598 {
599
602
603 // generate code for all procedures
604 for (int i = 0; i < program_.procedureCount(); ++i) {
606 }
607
608 // Close the last file
609 currentFile_.close();
610 currentFileName_.clear();
611 os_ = NULL;
612}
void generateProcedureCode(const TTAProgram::Procedure &procedure)
virtual std::set< InstructionAddress > findProgramExitPoints(const TTAProgram::Program &program, const TTAMachine::Machine &machine) const

References currentFile_, currentFileName_, exitPoints_, findBasicBlocks(), TTASimulationController::findProgramExitPoints(), generateProcedureCode(), machine_, os_, TTAProgram::Program::procedure(), TTAProgram::Program::procedureCount(), program_, and simController_.

Referenced by generateToDirectory().

Here is the call graph for this function:

◆ generateSimulationGetter()

void CompiledSimCodeGenerator::generateSimulationGetter ( )
private

Generates code for a C function that returns an instance of the compiled sim

Definition at line 749 of file CompiledSimCodeGenerator.cc.

749 {
750 // use C-style functions only! (C++ name mangling complicates stuff)
751 *os_ << "/* Class getter function */" << endl
752 << "extern \"C\" EXPORT CompiledSimulation* "
753 << "getSimulation_" << globalSymbolSuffix_ << "(" << endl
754 << "\tconst TTAMachine::Machine& machine," << endl
755 << "\tInstructionAddress entryAddress," << endl
756 << "\tInstructionAddress lastInstruction," << endl
757 << "\tSimulatorFrontend& frontend," << endl
758 << "\tCompiledSimController& controller," << endl
759 << "\tMemorySystem& memorySystem," << endl
760 << "\tbool dynamicCompilation," << endl
761 << "\tProcedureBBRelations& procedureBBRelations) {" << endl
762 << "\treturn new " << className_
763 << "(machine, entryAddress, lastInstruction, frontend, controller, "
764 << "memorySystem, dynamicCompilation, procedureBBRelations); "
765 << endl << "}" << endl << endl; // 2x end-of-line in the end of file
766}

References className_, globalSymbolSuffix_, and os_.

Referenced by generateConstructorCode().

◆ generateStoreTrigger()

string CompiledSimCodeGenerator::generateStoreTrigger ( const TTAMachine::HWOperation op)
private

Generates a faster version of specific store triggers

Parameters
oThe store operation (either stw, sth or stq)

Definition at line 1588 of file CompiledSimCodeGenerator.cc.

1589 {
1590 string address = symbolGen_.portSymbol(*op.port(1)) + ".uIntWordValue()";
1591 string dataToWrite = symbolGen_.portSymbol(*op.port(2)) + ".uIntWordValue()";
1592 string memory = symbolGen_.DAMemorySymbol(op.parentUnit()->name());
1593 string method;
1594
1595 const MemoryOperationDescription& memOpDesc = supportedMemoryOps.at(
1596 op.name());
1597 method = "fastWrite";
1598 if (memOpDesc.mauCount > 1) {
1599 method += std::to_string(memOpDesc.mauCount) + "MAUs";
1600 if (memOpDesc.mauOrder == MAUOrder::littleEndian) {
1601 method += "LE";
1602 } else { // big-endian
1603 method += "BE";
1604 }
1605 } else {
1606 method += "MAU";
1607 }
1608
1609 return memory + "." + method + "(" + address + ", " + dataToWrite + ");";
1610}

References CompiledSimSymbolGenerator::DAMemorySymbol(), TTAMachine::HWOperation::name(), TTAMachine::Component::name(), TTAMachine::HWOperation::parentUnit(), TTAMachine::HWOperation::port(), CompiledSimSymbolGenerator::portSymbol(), and symbolGen_.

Referenced by generateTriggerCode().

Here is the call graph for this function:

◆ generateSymbolDeclarations()

void CompiledSimCodeGenerator::generateSymbolDeclarations ( )
private

Generates declarations for all the symbols in the declared symbols -list

(SimValues, bool guards...)

Definition at line 874 of file CompiledSimCodeGenerator.cc.

874 {
875
877
878 for (SimValueSymbolDeclarations::const_iterator it =
879 declaredSymbols_.begin(); it != declaredSymbols_.end(); ++it) {
880 *os_ << "\t" << "SimValue " << it->first << ";" << endl;
881 }
882 *os_ << endl;
883}

References declaredSymbols_, CompiledSimSymbolGenerator::disablePrefix(), os_, and symbolGen_.

Referenced by generateHeaderAndMainCode().

Here is the call graph for this function:

◆ generateToDirectory()

void CompiledSimCodeGenerator::generateToDirectory ( const std::string &  dirName)
virtual

Generates compiled simulation code to the given directory.

Parameters
directoryDirectory where all the code is to be generated at
Exceptions
IOExceptionif the directory could not be opened for writing

Definition at line 231 of file CompiledSimCodeGenerator.cc.

231 {
232 targetDirectory_ = directory;
233 headerFile_ = "CompiledSimulationEngine.hh";
234 mainFile_ = "CompiledSimulationEngine.cc";
235
239}

References generateHeaderAndMainCode(), generateMakefile(), generateSimulationCode(), headerFile_, mainFile_, and targetDirectory_.

Referenced by CompiledSimController::reset().

Here is the call graph for this function:

◆ generateTriggerCode()

string CompiledSimCodeGenerator::generateTriggerCode ( const TTAMachine::HWOperation op)
private

Generates code for calling triggered operations

Parameters
opThe operation to be triggered
Returns
A string containing the generated C++ code

Definition at line 1501 of file CompiledSimCodeGenerator.cc.

1502 {
1503
1504 vector<string> operands;
1505 string source = "EXEC_OPERATION(";
1506
1507 // grab all operands and initialize them to the operand table
1508 for (int i = 1; op.port(i) != NULL; ++i) {
1509 if (op.port(i)->isInput()) {
1510 operands.push_back(symbolGen_.portSymbol(*op.port(i)));
1511 } else {
1512 operands.push_back(std::string("outputvalue")+Conversion::toString(i));
1513 }
1514 }
1515
1516 if (isStoreOperation(op.name())) {
1517 return generateStoreTrigger(op);
1518 } else if (isLoadOperation(op.name())) {
1519 return generateLoadTrigger(op);
1520 }
1521 OperationDAG* dag = &operationPool_.operation(op.name().c_str()).dag(0);
1522
1523 std::string simCode =
1525
1526 for (int i = 1, tmp = 1; op.port(i) != NULL; ++i) {
1527 if (op.port(i)->isOutput()) {
1528
1529 std::string outValueStr;
1530 // add output values as delayed assignments
1531 std::string outputStr = std::string("outputvalue") + Conversion::toString(i);
1532 size_t ovLen = outputStr.length() + 3;
1533 while (simCode.find(outputStr + " = ") != string::npos) {
1534 std::size_t begin = simCode.find(outputStr+" = ");
1535 std::size_t end = simCode.find(";", begin);
1536 outValueStr = simCode.substr(begin+ovLen,(end-begin-ovLen));
1537 simCode.erase(begin, end-begin);
1538 }
1539
1540 if (outValueStr.empty()) {
1541 std::string msg = "Machine has bound outport not used by op: ";
1542 msg += op.name();
1543 msg += " port index: ";
1544 msg += Conversion::toString(i);
1545 throw IllegalMachine(__FILE__,__LINE__,__func__,msg);
1546 }
1547
1548 // generate new unique name for it
1549 string tempVariable = symbolGen_.generateTempVariable();
1550
1551 if (simCode.find(outValueStr) == string::npos) {
1552 continue;
1553 }
1554
1555 while(simCode.find(outValueStr) != string::npos) {
1556 string::iterator it = simCode.begin() + simCode.find(outValueStr);
1557 simCode.replace(it, it + outValueStr.length(), tempVariable);
1558 }
1559
1560 simCode.append("\n" + generateAddFUResult(*op.port(i),
1561 tempVariable, op.latency()));
1562 tmp++;
1563 } // end isOutput
1564 } // end for
1565
1566 // fix the names of the tmp[n] values to unique ones so there can be
1567 // multiple in same BB.
1568 while (simCode.find("SimValue tmp") != string::npos) {
1569 std::size_t begin = simCode.find("SimValue tmp");
1570 std::size_t end = simCode.find(";", begin);
1571 std::string tmpName = simCode.substr(begin+9,(end-begin-9));
1572 string tempVariable = symbolGen_.generateTempVariable();
1573
1574 while(simCode.find(tmpName) != string::npos) {
1575 string::iterator it = simCode.begin() + simCode.find(tmpName);
1576 simCode.replace(it,it + tmpName.length(), tempVariable);
1577 }
1578 }
1579
1580 return simCode;
1581}
#define __func__
std::string generateStoreTrigger(const TTAMachine::HWOperation &op)
static bool isLoadOperation(const std::string &opName)
std::string generateLoadTrigger(const TTAMachine::HWOperation &op)
OperationPool operationPool_
The operation pool.
static std::string createSimulationCode(const OperationDAG &dag, std::vector< std::string > *varReplacements=NULL)
Operation & operation(const char *name)
virtual OperationDAG & dag(int index) const
Definition Operation.cc:148
virtual bool isInput() const
Definition Port.cc:298

References __func__, OperationDAGConverter::createSimulationCode(), Operation::dag(), generateAddFUResult(), generateLoadTrigger(), generateStoreTrigger(), CompiledSimSymbolGenerator::generateTempVariable(), TTAMachine::Port::isInput(), isLoadOperation(), TTAMachine::Port::isOutput(), isStoreOperation(), TTAMachine::HWOperation::latency(), TTAMachine::HWOperation::name(), OperationPool::operation(), operationPool_, TTAMachine::HWOperation::port(), CompiledSimSymbolGenerator::portSymbol(), symbolGen_, and Conversion::toString().

Referenced by handleOperation().

Here is the call graph for this function:

◆ guardPipelineTopSymbol()

std::string CompiledSimCodeGenerator::guardPipelineTopSymbol ( const TTAMachine::RegisterGuard guard)
private

Definition at line 1824 of file CompiledSimCodeGenerator.cc.

1825 {
1826 const RegisterFile* rf = rg.registerFile();
1827 std::string regName = "RF_" + rf->name() + "_" +
1828 Conversion::toString(rg.registerIndex());
1829 GuardPipeline::iterator i = guardPipeline_.find(regName);
1830 assert(i!= guardPipeline_.end());
1831 return "engine.guard_pipeline_RF_" +
1832 DisassemblyRegister::registerName(*rf, rg.registerIndex(), '_') +
1833 "_" + Conversion::toString(i->second -1);
1834}
#define assert(condition)
static TCEString registerName(const TTAMachine::RegisterFile &rf, int index, char delim='.')

References assert, guardPipeline_, TTAMachine::Component::name(), TTAMachine::RegisterGuard::registerFile(), TTAMachine::RegisterGuard::registerIndex(), DisassemblyRegister::registerName(), and Conversion::toString().

Referenced by generateGuardRead().

Here is the call graph for this function:

◆ handleJump()

string CompiledSimCodeGenerator::handleJump ( const TTAMachine::HWOperation op)
private

Generates code for a jump operation

Parameters
opA jump or call operation
Returns
A std::string containing generated code for the jump call

Definition at line 921 of file CompiledSimCodeGenerator.cc.

921 {
922 assert(op.name() == "call" || op.name() == "jump");
923
924 std::stringstream ss;
925 ss << "engine.jumpTarget_ = "
926 << symbolGen_.portSymbol(*op.port(1)) << ".sIntWordValue();";
927 if (op.name() == "call") { // save return address
928 ss << symbolGen_.returnAddressSymbol(gcu_) << " = "
929 << instructionNumber_ + gcu_.delaySlots() + 1 << "u;" << endl;
930 }
931 return ss.str();
932}
std::string returnAddressSymbol(const TTAMachine::ControlUnit &gcu) const

References assert, TTAMachine::ControlUnit::delaySlots(), gcu_, instructionNumber_, TTAMachine::HWOperation::name(), TTAMachine::HWOperation::port(), CompiledSimSymbolGenerator::portSymbol(), CompiledSimSymbolGenerator::returnAddressSymbol(), and symbolGen_.

Referenced by handleOperation(), and handleOperationWithoutDag().

Here is the call graph for this function:

◆ handleOperation()

string CompiledSimCodeGenerator::handleOperation ( const TTAMachine::HWOperation op)
private

Generates code for a triggered operation.

Parameters
opThe triggered operation
Returns
A std::string containing generated code for the operation call
Todo:
maybe use IsCall & IsControlFlowOperation.

Definition at line 941 of file CompiledSimCodeGenerator.cc.

941 {
942 std::stringstream ss;
943
944 ss << endl << "/* Operation: " << op.name() << ", latency: "
945 << op.latency() << " */" << endl;
946
947 if (operationPool_.operation(op.name().c_str()).dagCount() <= 0) {
949 } else {
950 /// @todo maybe use IsCall & IsControlFlowOperation.
951 if (op.name() != "jump" && op.name() != "call") {
952 ss << "#define context "
954 << endl
955 << "#define opPool_ engine.operationPool_" << endl
956 << generateTriggerCode(op) << endl
957 << "#undef context" << endl
958 << "#undef opPool_" << endl
959 << endl;
960 } else { // simulate a jump
961 ss << handleJump(op);
962 }
963 }
964 return ss.str();
965}
std::string handleJump(const TTAMachine::HWOperation &op)
std::string handleOperationWithoutDag(const TTAMachine::HWOperation &op)
std::string generateTriggerCode(const TTAMachine::HWOperation &op)
virtual int dagCount() const
Definition Operation.cc:134

References Operation::dagCount(), generateTriggerCode(), handleJump(), handleOperationWithoutDag(), TTAMachine::HWOperation::latency(), TTAMachine::HWOperation::name(), OperationPool::operation(), CompiledSimSymbolGenerator::operationContextSymbol(), operationPool_, TTAMachine::HWOperation::parentUnit(), and symbolGen_.

Referenced by generateInstruction().

Here is the call graph for this function:

◆ handleOperationWithoutDag()

string CompiledSimCodeGenerator::handleOperationWithoutDag ( const TTAMachine::HWOperation op)
private

Generates code for a triggered operation that has no DAG available

Parameters
opThe triggered operation
Returns
A std::string containing generated code for the operation call
Todo:
maybe use IsCall & IsControlFlowOperation.

Definition at line 974 of file CompiledSimCodeGenerator.cc.

975 {
976 std::stringstream ss;
977
978 std::vector<string> operandSymbols;
979 string operandTable = symbolGen_.generateTempVariable();
980
981 // Generate symbols for each operand, and temporaries for output operands
982 for (int i = 1; op.port(i) != NULL; ++i) {
983 if (op.port(i)->isOutput()) {
984 string outputSymbol = symbolGen_.generateTempVariable();
985 operandSymbols.push_back(outputSymbol);
986 ss << "SimValue " << outputSymbol
987 << "(" << op.port(i)->width() << ");" << endl;
988 } else { // input port
989 string inputSymbol = symbolGen_.portSymbol(*op.port(i));
990 operandSymbols.push_back(inputSymbol);
991 }
992 }
993
994 // Add operand symbols to the operand table
995 ss << "SimValue* " << operandTable << "[] = {";
996 for (size_t i = 0; i < operandSymbols.size(); ++i) {
997 ss << "&" << operandSymbols.at(i);
998 if (i < operandSymbols.size() - 1) {
999 ss << ",";
1000 }
1001 ss << " ";
1002 }
1003 ss << "};";
1004
1005 // call simulateTrigger with the previously generated operand table
1006 /// @todo maybe use IsCall & IsControlFlowOperation.
1007 if (op.name() != "jump" && op.name() != "call") {
1008 ss << symbolGen_.operationSymbol(op.name(), *op.parentUnit())
1009 << ".simulateTrigger(" << operandTable << ", "
1011 << "); ";
1012
1013 // add output values as delayed assignments
1014 for (int i = 1; op.port(i) != NULL; ++i) {
1015 if (op.port(i)->isOutput()) {
1016 ss << generateAddFUResult(*op.port(i), operandSymbols.at(i - 1),
1017 op.latency());
1018 }
1019 }
1020 } else { // simulate a jump
1021 ss << handleJump(op);
1022 }
1023
1024 return ss.str();
1025}

References generateAddFUResult(), CompiledSimSymbolGenerator::generateTempVariable(), handleJump(), TTAMachine::Port::isOutput(), TTAMachine::HWOperation::latency(), TTAMachine::HWOperation::name(), CompiledSimSymbolGenerator::operationContextSymbol(), CompiledSimSymbolGenerator::operationSymbol(), TTAMachine::HWOperation::parentUnit(), TTAMachine::HWOperation::port(), CompiledSimSymbolGenerator::portSymbol(), symbolGen_, and TTAMachine::BaseFUPort::width().

Referenced by handleOperation().

Here is the call graph for this function:

◆ handleRegisterWrite()

bool CompiledSimCodeGenerator::handleRegisterWrite ( const std::string &  regSymbolName,
std::ostream &  stream 
)
private

Definition at line 1838 of file CompiledSimCodeGenerator.cc.

1839 {
1840 std::string tmpString;
1841 std::string tmpString2;
1842
1843 const string tmpRef1 = regSymbolName;
1844
1845 // drop ".engine" from beginning
1846 // if found, copy to tmp and take ref to tmp. not found, ref to original
1847 const string& tmpRef2 = (tmpRef1.find("engine.") == 0) ?
1848 tmpString2 = tmpRef1.substr(7) :
1849 tmpRef1;
1850
1851 GuardPipeline::iterator i = guardPipeline_.find(tmpRef2);
1852 if ( i != guardPipeline_.end()) {
1853 stream << "engine.guard_pipeline_" << tmpRef2 << "_0 "
1854 << " = !(MathTools::fastZeroExtendTo("
1855 << tmpRef1 << ".uIntWordValue(), "
1856 << tmpRef1 << ".width()) == 0u);" << std::endl;
1857 return true;
1858 }
1859 return false;
1860}

References guardPipeline_.

Referenced by generateInstruction().

◆ isLoadOperation()

bool CompiledSimCodeGenerator::isLoadOperation ( const std::string &  opName)
staticprivate

Definition at line 1886 of file CompiledSimCodeGenerator.cc.

1886 {
1887 auto it = supportedMemoryOps.find(opName);
1888 if (it == supportedMemoryOps.end()) return false;
1889
1890 return (it->second.accessMode == AccessMode::read);
1891}

Referenced by generateTriggerCode().

◆ isStoreOperation()

bool CompiledSimCodeGenerator::isStoreOperation ( const std::string &  opName)
staticprivate

Definition at line 1878 of file CompiledSimCodeGenerator.cc.

1878 {
1879 auto it = supportedMemoryOps.find(opName);
1880 if (it == supportedMemoryOps.end()) return false;
1881
1882 return (it->second.accessMode == AccessMode::write);
1883}

Referenced by generateInstruction(), and generateTriggerCode().

◆ maxLatency()

int CompiledSimCodeGenerator::maxLatency ( ) const
private

Returns the maximum possible latency from the FUs & GCU

Returns
the maximum possible latency from the FUs & GCU

Definition at line 1769 of file CompiledSimCodeGenerator.cc.

1769 {
1772 for (int i = 0; i < fus.count(); ++i) {
1773 if (maxLatency < fus.item(i)->maxLatency()) {
1774 maxLatency = fus.item(i)->maxLatency();
1775 }
1776 }
1777 return maxLatency;
1778}

References TTAMachine::Machine::controlUnit(), TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::Machine::functionUnitNavigator(), TTAMachine::ControlUnit::globalGuardLatency(), TTAMachine::Machine::Navigator< ComponentType >::item(), machine_, and maxLatency().

Referenced by maxLatency().

Here is the call graph for this function:

◆ operator=()

CompiledSimCodeGenerator & CompiledSimCodeGenerator::operator= ( const CompiledSimCodeGenerator )
private

Assignment not allowed.

◆ procedureBBRelations()

ProcedureBBRelations CompiledSimCodeGenerator::procedureBBRelations ( ) const
virtual

Returns a struct of basic blocks and their corresponding code files

Returns
a struct of basic blocks and their corresponding code files

Definition at line 330 of file CompiledSimCodeGenerator.cc.

330 {
332}

References procedureBBRelations_.

Referenced by CompiledSimController::reset().

◆ supportedMemoryOperations()

TCETools::CIStringSet CompiledSimCodeGenerator::supportedMemoryOperations ( )
static

Returns list of all supported memory accessing operations for compiled simulation.

Definition at line 1868 of file CompiledSimCodeGenerator.cc.

1868 {
1869 TCETools::CIStringSet result;
1870 for (auto& pair : supportedMemoryOps) {
1871 result.insert(pair.first);
1872 }
1873 return result;
1874}
std::set< TCEString, CaseInsensitiveCmp > CIStringSet

◆ updateDeclaredSymbolsList()

void CompiledSimCodeGenerator::updateDeclaredSymbolsList ( )
private

Updates the declared symbols list after the program code is generated.

Generates constructor calls for each declared symbol.

Definition at line 799 of file CompiledSimCodeGenerator.cc.

799 {
800
802
803 // Constructor calls for SimValues
804 for (SimValueSymbolDeclarations::iterator it = declaredSymbols_.begin();
805 it != declaredSymbols_.end(); ++it) {
806 *os_ << "\t";
807 if (it != declaredSymbols_.begin()) {
808 *os_ << ",";
809 }
810 *os_ << it->first << "(" << Conversion::toString(it->second)
811 << ")" << endl;
812 }
813 if (!declaredSymbols_.empty()) {
814 *os_ << endl;
815 }
816
817 // Operations
818 for (OperationSymbolDeclarations::iterator it = usedOperations_.begin();
819 it != usedOperations_.end(); ++it) {
820 *os_ << "\t," << it->second
821 << "(operationPool_.operation(\"" << it->first << "\"))" << endl;
822 }
823 if (!usedOperations_.empty()) {
824 *os_ << endl;
825 }
826
827 // FU result symbols
829 for (int i = 0; i < fus.count(); ++i) {
830 const FunctionUnit& fu = *fus.item(i);
831 std::vector<Port*> outPorts = fuOutputPorts(fu);
832 for (size_t j = 0; j < outPorts.size(); ++j) {
833 *os_ << "\t," << symbolGen_.FUResultSymbol(*outPorts.at(j))
834 << "(" << Conversion::toString(fu.maxLatency()+1) << ")";
835 *os_ << endl;
836 }
837 }
838 if (fus.count() > 0) {
839 *os_ << endl;
840 }
841 // Conflict detectors
843
844 // DirectAccessMemories
845 for (int i = 0; i < fus.count(); i++) {
846 const FunctionUnit & fu = *fus.item(i);
847 if (fu.addressSpace() != NULL) {
848 *os_ << "\t," << symbolGen_.DAMemorySymbol(fu)
849 << "(FUMemory(\"" << fu.name() << "\"))" << endl;
850 }
851 }
852 *os_ << " {" << endl;
853}

References TTAMachine::FunctionUnit::addressSpace(), conflictDetectionGenerator_, TTAMachine::Machine::Navigator< ComponentType >::count(), CompiledSimSymbolGenerator::DAMemorySymbol(), declaredSymbols_, CompiledSimSymbolGenerator::disablePrefix(), TTAMachine::Machine::functionUnitNavigator(), fuOutputPorts(), CompiledSimSymbolGenerator::FUResultSymbol(), TTAMachine::Machine::Navigator< ComponentType >::item(), machine_, TTAMachine::FunctionUnit::maxLatency(), TTAMachine::Component::name(), os_, symbolGen_, Conversion::toString(), ConflictDetectionCodeGenerator::updateSymbolDeclarations(), and usedOperations_.

Referenced by generateConstructorCode().

Here is the call graph for this function:

◆ updateSymbolsMap()

void CompiledSimCodeGenerator::updateSymbolsMap ( )
private

Updates the Symbols map of the CompiledSimulation class

Definition at line 859 of file CompiledSimCodeGenerator.cc.

859 {
860 for (SimValueSymbolDeclarations::const_iterator it =
861 declaredSymbols_.begin(); it != declaredSymbols_.end(); ++it) {
862 string symbolName = it->first;
863 *os_ << "\t" << "addSymbol(\"" << symbolName << "\", "
864 << symbolName << ");" << endl;
865 }
866}

References declaredSymbols_, and os_.

Referenced by generateConstructorCode().

Member Data Documentation

◆ basicBlockPerFile_

bool CompiledSimCodeGenerator::basicBlockPerFile_
private

Should the generator generate only one basic block per code file.

Definition at line 221 of file CompiledSimCodeGenerator.hh.

Referenced by generateInstruction().

◆ bbEnds_

AddressMap CompiledSimCodeGenerator::bbEnds_
mutableprivate

The basic block map referred by end of the block as a key.

Definition at line 260 of file CompiledSimCodeGenerator.hh.

Referenced by basicBlocks(), findBasicBlocks(), generateAddFUResult(), and generateInstruction().

◆ bbStarts_

AddressMap CompiledSimCodeGenerator::bbStarts_
mutableprivate

The basic block map referred by start of the block as a key.

Definition at line 258 of file CompiledSimCodeGenerator.hh.

Referenced by basicBlocks(), findBasicBlocks(), generateConstructorCode(), generateInstruction(), and generateJumpTableCode().

◆ className_

std::string CompiledSimCodeGenerator::className_
private

◆ conflictDetectionGenerator_

ConflictDetectionCodeGenerator CompiledSimCodeGenerator::conflictDetectionGenerator_
private

◆ createdFiles_

StringSet CompiledSimCodeGenerator::createdFiles_
private

A list of the code files created during the process.

Definition at line 233 of file CompiledSimCodeGenerator.hh.

Referenced by createdFiles(), generateConstructorCode(), and generateInstruction().

◆ currentFile_

std::fstream CompiledSimCodeGenerator::currentFile_
private

Current file being processed.

Definition at line 280 of file CompiledSimCodeGenerator.hh.

Referenced by generateConstructorCode(), generateHeaderAndMainCode(), generateInstruction(), and generateSimulationCode().

◆ currentFileName_

std::string CompiledSimCodeGenerator::currentFileName_
private

Name of the current file being processed.

Definition at line 282 of file CompiledSimCodeGenerator.hh.

Referenced by generateHeaderAndMainCode(), generateInstruction(), generateMakefile(), and generateSimulationCode().

◆ currentProcedure_

const TTAProgram::Procedure* CompiledSimCodeGenerator::currentProcedure_
private

Pointer to the current Procedure being processed.

Definition at line 246 of file CompiledSimCodeGenerator.hh.

Referenced by generateInstruction(), and generateProcedureCode().

◆ declaredFunctions_

StringSet CompiledSimCodeGenerator::declaredFunctions_
private

A set of all the declared functions.

Definition at line 231 of file CompiledSimCodeGenerator.hh.

Referenced by generateInstruction().

◆ declaredSymbols_

SimValueSymbolDeclarations CompiledSimCodeGenerator::declaredSymbols_
private

A list of all symbols that are declared after the program code is ready.

Definition at line 228 of file CompiledSimCodeGenerator.hh.

Referenced by addDeclaredSymbol(), generateSymbolDeclarations(), updateDeclaredSymbolsList(), and updateSymbolsMap().

◆ delayedFUResultWrites_

DelayedAssignments CompiledSimCodeGenerator::delayedFUResultWrites_
private

Delayed FU Result assignments.

Definition at line 264 of file CompiledSimCodeGenerator.hh.

Referenced by generateAddFUResult(), and generateInstruction().

◆ dynamicCompilation_

bool CompiledSimCodeGenerator::dynamicCompilation_
private

Is this a dynamic compiled simulation?

Definition at line 219 of file CompiledSimCodeGenerator.hh.

Referenced by generateJumpTableCode().

◆ exitPoints_

std::set<InstructionAddress> CompiledSimCodeGenerator::exitPoints_
private

Program exit point addresses.

Definition at line 255 of file CompiledSimCodeGenerator.hh.

Referenced by generateInstruction(), and generateSimulationCode().

◆ functionPerFile_

bool CompiledSimCodeGenerator::functionPerFile_
private

Should the generator start with a new file after function end.

Definition at line 223 of file CompiledSimCodeGenerator.hh.

Referenced by generateInstruction().

◆ gcu_

const TTAMachine::ControlUnit& CompiledSimCodeGenerator::gcu_
private

GCU.

Definition at line 214 of file CompiledSimCodeGenerator.hh.

Referenced by handleJump().

◆ globalSymbolSuffix_

TCEString CompiledSimCodeGenerator::globalSymbolSuffix_
private

◆ guardPipeline_

GuardPipeline CompiledSimCodeGenerator::guardPipeline_
private

◆ handleCycleEnd_

bool CompiledSimCodeGenerator::handleCycleEnd_
private

Should we let frontend handle each cycle end.

Definition at line 217 of file CompiledSimCodeGenerator.hh.

Referenced by generateInstruction().

◆ headerFile_

std::string CompiledSimCodeGenerator::headerFile_
private

◆ instructionCounter_

int CompiledSimCodeGenerator::instructionCounter_
private

Istruction counter for checking how many instructions to put per file.

Definition at line 240 of file CompiledSimCodeGenerator.hh.

Referenced by generateInstruction(), and generateProcedureCode().

◆ instructionNumber_

int CompiledSimCodeGenerator::instructionNumber_
private

Absolute instruction # being processed.

Definition at line 238 of file CompiledSimCodeGenerator.hh.

Referenced by generateAddFUResult(), generateInstruction(), generateProcedureCode(), and handleJump().

◆ isProcedureBegin_

bool CompiledSimCodeGenerator::isProcedureBegin_
private

Are we at the beginning of a new procedure?

Definition at line 244 of file CompiledSimCodeGenerator.hh.

Referenced by generateInstruction(), and generateProcedureCode().

◆ lastFUWrites_

FUResultWrites CompiledSimCodeGenerator::lastFUWrites_
private

Last known FU result writes.

Definition at line 266 of file CompiledSimCodeGenerator.hh.

Referenced by generateAddFUResult(), and generateInstruction().

◆ lastGuardBool_

std::string CompiledSimCodeGenerator::lastGuardBool_
private

name of the last used guard variable

Definition at line 251 of file CompiledSimCodeGenerator.hh.

Referenced by generateAddFUResult(), generateGuardCondition(), generateGuardRead(), and generateInstruction().

◆ lastInstructionOfBB_

InstructionAddress CompiledSimCodeGenerator::lastInstructionOfBB_
private

last instruction of the current basic block

Definition at line 249 of file CompiledSimCodeGenerator.hh.

Referenced by generateInstruction().

◆ machine_

const TTAMachine::Machine& CompiledSimCodeGenerator::machine_
private

◆ mainFile_

std::string CompiledSimCodeGenerator::mainFile_
private

Main source filename. This includes the constructor and the simulateCycle().

Definition at line 278 of file CompiledSimCodeGenerator.hh.

Referenced by generateConstructorCode(), and generateToDirectory().

◆ maxInstructionsPerFile_

unsigned CompiledSimCodeGenerator::maxInstructionsPerFile_
private

Maximum number of instructions per engine source code file, computed from the instruction width (bus count) to control simulation engine code size explosion with wider simulated machines.

Definition at line 296 of file CompiledSimCodeGenerator.hh.

Referenced by CompiledSimCodeGenerator(), and generateInstruction().

◆ maxInstructionsPerSimulationFunction_

unsigned CompiledSimCodeGenerator::maxInstructionsPerSimulationFunction_
private

Max for each simulation function.

Definition at line 298 of file CompiledSimCodeGenerator.hh.

Referenced by CompiledSimCodeGenerator(), and findBasicBlocks().

◆ moveCounter_

int CompiledSimCodeGenerator::moveCounter_
private

How many moves have we been through with?

Definition at line 242 of file CompiledSimCodeGenerator.hh.

Referenced by generateInstruction().

◆ needGuardPipeline_

bool CompiledSimCodeGenerator::needGuardPipeline_
private

◆ operationPool_

OperationPool CompiledSimCodeGenerator::operationPool_
private

The operation pool.

Definition at line 269 of file CompiledSimCodeGenerator.hh.

Referenced by generateTriggerCode(), and handleOperation().

◆ os_

std::ostream* CompiledSimCodeGenerator::os_
private

◆ procedureBBRelations_

ProcedureBBRelations CompiledSimCodeGenerator::procedureBBRelations_
private

Basic blocks relations to procedures and vice versa.

Definition at line 262 of file CompiledSimCodeGenerator.hh.

Referenced by generateInstruction(), and procedureBBRelations().

◆ program_

const TTAProgram::Program& CompiledSimCodeGenerator::program_
private

The simulated program.

Definition at line 210 of file CompiledSimCodeGenerator.hh.

Referenced by findBasicBlocks(), generateAddFUResult(), generateInstruction(), and generateSimulationCode().

◆ simController_

const TTASimulationController& CompiledSimCodeGenerator::simController_
private

The simulator frontend.

Definition at line 212 of file CompiledSimCodeGenerator.hh.

Referenced by generateSimulationCode().

◆ symbolGen_

CompiledSimSymbolGenerator CompiledSimCodeGenerator::symbolGen_
private

◆ targetDirectory_

std::string CompiledSimCodeGenerator::targetDirectory_
private

Directory where to write the source files of the engine.

Definition at line 272 of file CompiledSimCodeGenerator.hh.

Referenced by generateConstructorCode(), generateHeaderAndMainCode(), generateInstruction(), generateMakefile(), and generateToDirectory().

◆ usedGuardSymbols_

std::map<std::string, std::string> CompiledSimCodeGenerator::usedGuardSymbols_
private

Temporary list of the used guard bool symbols per instruction.

Definition at line 253 of file CompiledSimCodeGenerator.hh.

Referenced by generateGuardCondition(), generateGuardRead(), and generateInstruction().

◆ usedOperations_

OperationSymbolDeclarations CompiledSimCodeGenerator::usedOperations_
private

A list of used operations.

Definition at line 235 of file CompiledSimCodeGenerator.hh.

Referenced by generateHeaderAndMainCode(), and updateDeclaredSymbolsList().


The documentation for this class was generated from the following files: