OpenASIP 2.2
Loading...
Searching...
No Matches
Functions
Automagic Namespace Reference

Functions

std::string findHDBPath (std::string name)
 
bool findInOptionList (const std::string &option, std::vector< std::string > list, bool enableAll=true)
 
std::vector< IDF::FUGenerated::DAGOperationgenerateableDAGOperations (const std::vector< IDF::FUGenerated::Info > infos, std::ostream &verbose)
 
std::vector< IDF::FUGenerated::InfocreateFUGeneratableOperationInfos (const ProGeOptions &options, std::ostream &verbose)
 
bool checkForGeneratableFU (const ProGeOptions &options, TTAMachine::FunctionUnit &fu, IDF::FUGenerated &fug, const std::vector< IDF::FUGenerated::Info > &infos, const std::vector< IDF::FUGenerated::DAGOperation > dagops)
 
bool checkForSelectableFU (const ProGeOptions &options, TTAMachine::FunctionUnit &fu, IDF::FUImplementationLocation &loc, std::ostream &verbose)
 
bool checkForSelectableRF (const ProGeOptions &options, TTAMachine::RegisterFile &rf, IDF::RFImplementationLocation &loc, std::ostream &verbose)
 
bool checkForSelectableIU (const ProGeOptions &options, TTAMachine::ImmediateUnit &iu, IDF::IUImplementationLocation &loc, std::ostream &verbose)
 
bool canGenerateFromDAG (const OperationDAG &dag, const std::vector< IDF::FUGenerated::Info > infos, std::vector< IDF::FUGenerated::Info > *subops)
 
int dagLatency (const OperationDAG &dag, const std::unordered_map< std::string, int > &maxOpLatency)
 
int maxLatencyToNode (const OperationDAG &dag, OperationDAGNode &node, const std::unordered_map< std::string, int > &maxOpLatency, bool allowDifference=true)
 
int nodeLatency (OperationDAGNode &node, const std::unordered_map< std::string, int > &maxOpLatency)
 
bool languageMatches (HDB::BlockImplementationFile::Format format, ProGe::HDL language)
 

Function Documentation

◆ canGenerateFromDAG()

bool Automagic::canGenerateFromDAG ( const OperationDAG dag,
const std::vector< IDF::FUGenerated::Info infos,
std::vector< IDF::FUGenerated::Info > *  subops 
)

Checks if DAG operation can be implemented, i.e. all basic operations can be implemented

Definition at line 193 of file AutomagicTools.cc.

195 {
196 if (dag.isNull()) {
197 return false;
198 }
199
200 bool canImplement = true;
201 for (int n = 0; n < dag.nodeCount(); ++n) {
202 OperationNode* operationNode =
203 dynamic_cast<OperationNode*>(&dag.node(n));
204 if (operationNode) {
205 std::string operation = operationNode->referencedOperation().name();
206 operation = StringTools::stringToLower(operation);
207
208 bool foundOperation = false;
209 for (auto&& info : infos) {
210 if (info.operationName == operation) {
211 foundOperation = true;
212 if (subops) {
213 subops->emplace_back(info);
214 }
215 break;
216 }
217 }
218 if (foundOperation == false) {
219 canImplement = false;
220 break;
221 }
222
223 }
224 }
225 return canImplement;
226}
int nodeCount() const
Node & node(const int index) const
bool isNull() const
Operation & referencedOperation() const
virtual TCEString name() const
Definition Operation.cc:93
static std::string stringToLower(const std::string &source)

References OperationDAG::isNull(), Operation::name(), BoostGraph< GraphNode, GraphEdge >::node(), BoostGraph< GraphNode, GraphEdge >::nodeCount(), OperationNode::referencedOperation(), and StringTools::stringToLower().

Here is the call graph for this function:

◆ checkForGeneratableFU()

bool Automagic::checkForGeneratableFU ( const ProGeOptions options,
TTAMachine::FunctionUnit fu,
IDF::FUGenerated fug,
const std::vector< IDF::FUGenerated::Info > &  infos,
const std::vector< IDF::FUGenerated::DAGOperation dagops 
)

Check if given fu can be generated. If so return it in fug.

Definition at line 58 of file AutomagicTools.cc.

61 {
62
63 std::vector<TTAMachine::HWOperation*> operations;
64 std::vector<std::string> genops;
65
66 for (int i = 0; i < fu.operationCount(); ++i) {
67 operations.emplace_back(fu.operation(i));
68 }
69
70 for (auto&& op : operations) {
71 int maxLatency;
73 fug.name(), options.fuFrontRegistered, false)) {
74 maxLatency = op->latency() - 1;
76 fug.name(), options.fuMiddleRegistered, false)) {
77 maxLatency = op->latency() - 2;
79 fug.name(), options.fuBackRegistered, false)) {
80 maxLatency = op->latency();
82 fug.name(), options.fuFrontRegistered)) {
83 maxLatency = op->latency() - 1;
85 fug.name(), options.fuMiddleRegistered)) {
86 maxLatency = op->latency() - 2;
87 } else { // Default to back-register
88 maxLatency = op->latency();
89 }
90 for (auto&& info : infos) {
91 if (op->name() == info.operationName
92 && maxLatency >= info.latency) {
93 fug.addOperation(info);
94 genops.emplace_back(info.operationName);
95 break;
96 }
97 }
98 }
99
100 for (auto&& op : operations) {
101 for (auto&& dop : dagops) {
102 if (std::find(genops.begin(), genops.end(), op->name()) ==
103 genops.end() &&
104 op->name() == dop.operationName) {
105 fug.addOperation(dop);
106 genops.emplace_back(dop.operationName);
107 }
108 }
109 }
110
111 size_t neededFUops = fu.operationCount();
112
113 if (genops.size() == neededFUops) {
114 return true;
115 } else {
116 return false;
117 }
118}
static MachInfoCmdLineOptions options
Definition MachInfo.cc:46
void addOperation(const Info &op)
std::string name() const
virtual HWOperation * operation(const std::string &name) const
virtual int operationCount() const
bool findInOptionList(const std::string &option, std::vector< std::string > list, bool enableAll=true)

References IDF::FUGenerated::addOperation(), findInOptionList(), IDF::FUGenerated::name(), TTAMachine::FunctionUnit::operation(), TTAMachine::FunctionUnit::operationCount(), and options.

Here is the call graph for this function:

◆ checkForSelectableFU()

bool Automagic::checkForSelectableFU ( const ProGeOptions options,
TTAMachine::FunctionUnit fu,
IDF::FUImplementationLocation loc,
std::ostream &  verbose 
)

Checks if FU has an implementation in hdbs.

Definition at line 348 of file AutomagicTools.cc.

350 {
351 (void)verbose;
352 for (auto&& hdb : options.hdbList) {
353 std::string hdbPath = findHDBPath(hdb);
354 HDB::CachedHDBManager& manager =
356 std::set<RowID> rows = manager.fuEntryIDs();
357 for (auto&& row : rows) {
358 auto fuEntry = manager.fuByEntryID(row);
359 if (!fuEntry->hasImplementation() ||
360 !fuEntry->hasArchitecture()) {
361 continue;
362 }
363 auto arch = fuEntry->architecture();
364 auto impl = fuEntry->implementation();
365 // Check that operations match.
366 if (fu.operationCount() !=
367 arch.architecture().operationCount()) {
368 continue;
369 }
370 bool wrongLanguage = false;
371 for (int i = 0; i < impl.implementationFileCount(); ++i) {
372 auto f = impl.file(i);
373 if (f.format() ==
375 options.language == ProGe::HDL::Verilog) {
376 wrongLanguage = true;
377 break;
378 } else if (f.format() == HDB::BlockImplementationFile::
379 Format::Verilog &&
380 options.language == ProGe::HDL::VHDL) {
381 wrongLanguage = true;
382 break;
383 }
384 }
385 if (wrongLanguage) {
386 continue;
387 }
388 bool found = true;
389 for (int i = 0; i < fu.operationCount(); ++i) {
390 auto op = fu.operation(i);
391 if (!arch.architecture().hasOperation(op->name())) {
392 found = false;
393 break;
394 }
395 if (op->latency() !=
396 arch.architecture().operation(op->name())->latency()) {
397 found = false;
398 break;
399 }
400 }
401 if (!found) {
402 continue;
403 }
404
405 loc.setID(row);
406 loc.setHDBFile(hdbPath);
407 return true;
408 }
409 }
410
411 return false;
412}
static CachedHDBManager & instance(const std::string &hdbFile)
FUArchitecture & architecture() const
Definition FUEntry.cc:129
FUEntry * fuByEntryID(RowID id) const
std::set< RowID > fuEntryIDs() const
virtual void setHDBFile(std::string file)
Definition FUGen.hh:54
HDL
HDLs supported by ProGe.
Definition ProGeTypes.hh:40
@ Verilog
Verilog.
Definition ProGeTypes.hh:42
@ VHDL
VHDL.
Definition ProGeTypes.hh:41

References HDB::FUEntry::architecture(), HDB::HDBManager::fuByEntryID(), HDB::HDBManager::fuEntryIDs(), HDB::CachedHDBManager::instance(), TTAMachine::FunctionUnit::operation(), TTAMachine::FunctionUnit::operationCount(), options, IDF::UnitImplementationLocation::setHDBFile(), IDF::UnitImplementationLocation::setID(), ProGe::Verilog, HDB::BlockImplementationFile::VHDL, and ProGe::VHDL.

Here is the call graph for this function:

◆ checkForSelectableIU()

bool Automagic::checkForSelectableIU ( const ProGeOptions options,
TTAMachine::ImmediateUnit iu,
IDF::IUImplementationLocation loc,
std::ostream &  verbose 
)

Checks if RF has an implementation in hdbs.

Definition at line 491 of file AutomagicTools.cc.

493 {
494 (void)verbose;
495 for (auto&& hdb : options.hdbList) {
496 std::string hdbPath = findHDBPath(hdb);
497 HDB::CachedHDBManager& manager =
499 std::set<RowID> rows = manager.rfEntryIDs();
500 for (auto&& row : rows) {
501 auto rfEntry = manager.rfByEntryID(row);
502 // Exclude these:
503 if (!rfEntry->hasImplementation() ||
504 !rfEntry->hasArchitecture()) {
505 continue;
506 }
507 auto arch = rfEntry->architecture();
508 auto impl = rfEntry->implementation();
509 bool wrongLanguage = false;
510 for (int i = 0; i < impl.implementationFileCount(); ++i) {
511 auto f = impl.file(i);
512 if (f.format() ==
514 options.language == ProGe::HDL::Verilog) {
515 wrongLanguage = true;
516 break;
517 } else if (f.format() == HDB::BlockImplementationFile::
518 Format::Verilog &&
519 options.language == ProGe::HDL::VHDL) {
520 wrongLanguage = true;
521 break;
522 }
523 }
524 if (wrongLanguage) {
525 continue;
526 }
527 if (iu.isUsedAsGuard() != arch.hasGuardSupport()) {
528 continue;
529 }
530 if (iu.maxReads() != arch.readPortCount()) {
531 continue;
532 }
533 if (1 != arch.writePortCount()) {
534 continue;
535 }
536 if (iu.latency() != arch.latency()) {
537 continue;
538 }
539 if (!arch.hasParameterizedWidth() &&
540 (iu.width() != arch.width())) {
541 continue;
542 }
543 if (!arch.hasParameterizedSize() &&
544 (iu.size() != arch.size())) {
545 continue;
546 }
547 // Must be a perfect choise.
548 loc.setID(row);
549 loc.setHDBFile(hdbPath);
550 return true;
551 }
552 }
553 return false;
554}
std::set< RowID > rfEntryIDs() const
RFEntry * rfByEntryID(RowID id) const
RFArchitecture & architecture() const
Definition RFEntry.cc:145
virtual int size() const
virtual int width() const
virtual int latency() const
virtual int maxReads() const
virtual bool isUsedAsGuard() const

References HDB::RFEntry::architecture(), HDB::CachedHDBManager::instance(), TTAMachine::RegisterFile::isUsedAsGuard(), TTAMachine::ImmediateUnit::latency(), TTAMachine::RegisterFile::maxReads(), options, HDB::HDBManager::rfByEntryID(), HDB::HDBManager::rfEntryIDs(), IDF::UnitImplementationLocation::setHDBFile(), IDF::UnitImplementationLocation::setID(), TTAMachine::BaseRegisterFile::size(), ProGe::Verilog, HDB::BlockImplementationFile::VHDL, ProGe::VHDL, and TTAMachine::BaseRegisterFile::width().

Here is the call graph for this function:

◆ checkForSelectableRF()

bool Automagic::checkForSelectableRF ( const ProGeOptions options,
TTAMachine::RegisterFile rf,
IDF::RFImplementationLocation loc,
std::ostream &  verbose 
)

Checks if RF has an implementation in hdbs.

Definition at line 417 of file AutomagicTools.cc.

419 {
420 (void)verbose;
421 for (auto&& hdb : options.hdbList) {
422 std::string hdbPath = findHDBPath(hdb);
423 HDB::CachedHDBManager& manager =
425 std::set<RowID> rows = manager.rfEntryIDs();
426 for (auto&& row : rows) {
427 auto rfEntry = manager.rfByEntryID(row);
428 // Exclude these:
429 if (!rfEntry->hasImplementation() ||
430 !rfEntry->hasArchitecture()) {
431 continue;
432 }
433 auto arch = rfEntry->architecture();
434 auto impl = rfEntry->implementation();
435 bool wrongLanguage = false;
436 for (int i = 0; i < impl.implementationFileCount(); ++i) {
437 auto f = impl.file(i);
438 if (f.format() ==
440 options.language == ProGe::HDL::Verilog) {
441 wrongLanguage = true;
442 break;
443 } else if (f.format() == HDB::BlockImplementationFile::
444 Format::Verilog &&
445 options.language == ProGe::HDL::VHDL) {
446 wrongLanguage = true;
447 break;
448 }
449 }
450 if (wrongLanguage) {
451 continue;
452 }
453 if (rf.isUsedAsGuard() != arch.hasGuardSupport()) {
454 continue;
455 }
456 if (rf.outputPortCount() != arch.readPortCount()) {
457 continue;
458 }
459 if (rf.inputPortCount() != arch.writePortCount()) {
460 continue;
461 }
462 if (rf.bidirPortCount() != arch.bidirPortCount()) {
463 continue;
464 }
465 if (1 != arch.latency()) {
466 continue;
467 }
468 if (rf.guardLatency() != arch.guardLatency()) {
469 continue;
470 }
471 if (!arch.hasParameterizedWidth() &&
472 (rf.width() != arch.width())) {
473 continue;
474 }
475 if (!arch.hasParameterizedSize() &&
476 (rf.size() != arch.size())) {
477 continue;
478 }
479 // Must be a perfect choise.
480 loc.setID(row);
481 loc.setHDBFile(hdbPath);
482 return true;
483 }
484 }
485 return false;
486}
virtual int guardLatency() const
virtual int bidirPortCount() const
Definition Unit.cc:174
virtual int inputPortCount(bool countBidir=false) const
Definition Unit.cc:160
virtual int outputPortCount(bool countBidir=false) const
Definition Unit.cc:145

References HDB::RFEntry::architecture(), TTAMachine::Unit::bidirPortCount(), TTAMachine::RegisterFile::guardLatency(), TTAMachine::Unit::inputPortCount(), HDB::CachedHDBManager::instance(), TTAMachine::RegisterFile::isUsedAsGuard(), options, TTAMachine::Unit::outputPortCount(), HDB::HDBManager::rfByEntryID(), HDB::HDBManager::rfEntryIDs(), IDF::UnitImplementationLocation::setHDBFile(), IDF::UnitImplementationLocation::setID(), TTAMachine::BaseRegisterFile::size(), ProGe::Verilog, HDB::BlockImplementationFile::VHDL, ProGe::VHDL, and TTAMachine::BaseRegisterFile::width().

Here is the call graph for this function:

◆ createFUGeneratableOperationInfos()

std::vector< IDF::FUGenerated::Info > Automagic::createFUGeneratableOperationInfos ( const ProGeOptions options,
std::ostream &  verbose 
)

Parses all given hdbs for operation implementations.

Definition at line 305 of file AutomagicTools.cc.

306 {
307 std::vector<IDF::FUGenerated::Info> infos;
308
309 for (auto&& hdb : options.hdbList) {
310 std::string hdbPath = findHDBPath(hdb);
311 verbose << " searching implementations from " << hdbPath << "\n";
312 HDB::CachedHDBManager& manager =
314 std::set<RowID> rows = manager.OperationImplementationIDs();
315 std::vector<IDF::FUGenerated::Info> newInfos;
316 for (auto&& row : rows) {
317 auto opimpl = manager.OperationImplementationByID(row);
318 newInfos.emplace_back(IDF::FUGenerated::Info{opimpl.name, hdbPath,
319 opimpl.id, opimpl.latency});
320 }
321
322 std::sort(newInfos.begin(), newInfos.end(),
324 { return a.latency > b.latency; });
325
326 infos.insert(infos.end(), newInfos.begin(), newInfos.end());
327 }
328
329 return infos;
330}
std::set< RowID > OperationImplementationIDs() const
OperationImplementation OperationImplementationByID(RowID id) const

References IDF::FUGenerated::Info::id, HDB::CachedHDBManager::instance(), HDB::HDBManager::OperationImplementationByID(), HDB::HDBManager::OperationImplementationIDs(), and options.

Here is the call graph for this function:

◆ dagLatency()

int Automagic::dagLatency ( const OperationDAG dag,
const std::unordered_map< std::string, int > &  maxOpLatency 
)

Finds the maximum latency of the dag. Uses maxOpLatency for the node latencies.

Definition at line 233 of file AutomagicTools.cc.

234 {
235 assert(!dag.isNull());
236
237 int maxLatency = 0;
238
239 // To find the global critical path, go through every end terminal's
240 // critical path and find the maximum.
241 auto sinkNodes = dag.sinkNodes();
242 for (auto node : sinkNodes) {
243 int latency = maxLatencyToNode(dag, *node, maxOpLatency);
244 maxLatency = std::max(latency, maxLatency);
245 }
246 return maxLatency;
247}
#define assert(condition)
virtual NodeSet sinkNodes() const

References assert, OperationDAG::isNull(), and BoostGraph< GraphNode, GraphEdge >::sinkNodes().

Here is the call graph for this function:

◆ findHDBPath()

std::string Automagic::findHDBPath ( std::string  name)

Tries to find full path for hdb file.

Definition at line 335 of file AutomagicTools.cc.

335 {
336
337 if (FileSystem::fileExists(name)) {
338 return name;
339 }
340
341 std::vector<std::string> paths = Environment::hdbPaths();
342 return FileSystem::findFileInSearchPaths(paths, name);
343}
static std::vector< std::string > hdbPaths(bool libraryPathsOnly=false)
static std::string findFileInSearchPaths(const std::vector< std::string > &searchPaths, const std::string &file)
static bool fileExists(const std::string fileName)

References FileSystem::fileExists(), FileSystem::findFileInSearchPaths(), and Environment::hdbPaths().

Here is the call graph for this function:

◆ findInOptionList()

bool Automagic::findInOptionList ( const std::string &  option,
std::vector< std::string >  list,
bool  enableAll = true 
)

Check if option is in the list or list has 'ALL' in it.

Definition at line 123 of file AutomagicTools.cc.

124 {
125 std::string lowered_option = StringTools::stringToLower(option);
126 for (auto&& item : list) {
127 std::string lowered_item = StringTools::stringToLower(item);
128 if (lowered_item == lowered_option
129 || (enableAll && lowered_item == "all")) {
130 return true;
131 }
132 }
133 return false;
134}

References StringTools::stringToLower().

Referenced by checkForGeneratableFU().

Here is the call graph for this function:

◆ generateableDAGOperations()

std::vector< IDF::FUGenerated::DAGOperation > Automagic::generateableDAGOperations ( const std::vector< IDF::FUGenerated::Info infos,
std::ostream &  verbose 
)

Find out all operations we can generate from DAG.

Definition at line 140 of file AutomagicTools.cc.

142 {
143 std::vector<IDF::FUGenerated::DAGOperation> dagops;
144 std::set<std::string> opNames;
145
146 verbose << " can implement DAG operations that use:\n ";
147 std::string sep;
148 for (auto&& info : infos) {
149 verbose << sep << info.operationName;
150 sep = ", ";
151 }
152 verbose << "\n";
153
154 OperationPool opPool;
155 OperationIndex& opIndex = opPool.index();
156 for (int i = 0; i < opIndex.moduleCount(); ++i) {
157 OperationModule& module = opIndex.module(i);
158 for (int j = 0; j < opIndex.operationCount(module); ++j) {
159 std::string opName = opIndex.operationName(j, module);
160 if (opNames.count(opName) > 0) {
161 continue;
162 }
163 Operation& op = opPool.operation(opName.c_str());
164 for (int d = 0; d < op.dagCount(); ++d) {
165 std::vector<IDF::FUGenerated::Info> subops;
166 if (canGenerateFromDAG(op.dag(d), infos, &subops)) {
167 opName = StringTools::stringToLower(opName);
168 dagops.emplace_back(IDF::FUGenerated::DAGOperation{opName,
169 subops});
170 opNames.insert(opName);
171 break;
172 }
173 }
174 }
175 }
176
177 verbose << " can implement DAG operations:\n ";
178 sep = "";
179 for (auto&& op : dagops) {
180 verbose << sep << op.operationName;
181 sep = ", ";
182 }
183 verbose << "\n";
184
185 return dagops;
186}
std::string operationName(int i, const OperationModule &om)
int operationCount(const OperationModule &om)
int moduleCount() const
OperationIndex & index()
Operation & operation(const char *name)
virtual OperationDAG & dag(int index) const
Definition Operation.cc:148
virtual int dagCount() const
Definition Operation.cc:134
bool canGenerateFromDAG(const OperationDAG &dag, const std::vector< IDF::FUGenerated::Info > infos, std::vector< IDF::FUGenerated::Info > *subops)

References Operation::dag(), Operation::dagCount(), OperationPool::index(), OperationIndex::moduleCount(), OperationPool::operation(), OperationIndex::operationCount(), OperationIndex::operationName(), and StringTools::stringToLower().

Here is the call graph for this function:

◆ languageMatches()

bool Automagic::languageMatches ( HDB::BlockImplementationFile::Format  format,
ProGe::HDL  language 
)

◆ maxLatencyToNode()

int Automagic::maxLatencyToNode ( const OperationDAG dag,
OperationDAGNode node,
const std::unordered_map< std::string, int > &  maxOpLatency,
bool  allowDifference = true 
)

Definition at line 273 of file AutomagicTools.cc.

276 {
277
278 // Go through all the parents.
279 int maxLeafLatency = -1;
280 for (auto&& e : dag.inEdges(node)) {
281 OperationDAGNode& nextNode = dag.tailNode(*e);
282 // Recursive call to parent nodes
283 int parentLatency = maxLatencyToNode(dag, nextNode, maxOpLatency)
284 + nodeLatency(nextNode, maxOpLatency);
285
286 if (!allowDifference && maxLeafLatency != -1) {
287 assert(maxLeafLatency == parentLatency &&
288 "Two input edges of DAG node have different latency!");
289 }
290
291 maxLeafLatency = std::max(maxLeafLatency, parentLatency);
292 }
293
294 // For nodes without children
295 maxLeafLatency = std::max(maxLeafLatency, 0);
296
297 // Return only the longest leaf latency.
298 return maxLeafLatency;
299}
virtual Node & tailNode(const Edge &edge) const

References assert, BoostGraph< GraphNode, GraphEdge >::inEdges(), and BoostGraph< GraphNode, GraphEdge >::tailNode().

Here is the call graph for this function:

◆ nodeLatency()

int Automagic::nodeLatency ( OperationDAGNode node,
const std::unordered_map< std::string, int > &  maxOpLatency 
)

Definition at line 250 of file AutomagicTools.cc.

252 {
253
254 int latency = 0;
255
256 OperationNode* operationNode = dynamic_cast<OperationNode*>(&node);
257 if (operationNode) {
258 std::string subOpName = operationNode->referencedOperation().name();
259 subOpName = StringTools::stringToLower(subOpName);
260 if (maxOpLatency.find(subOpName) != maxOpLatency.end()) {
261 latency = maxOpLatency.at(subOpName);
262 }
263 }
264
265 return latency;
266}

References Operation::name(), OperationNode::referencedOperation(), and StringTools::stringToLower().

Here is the call graph for this function: