OpenASIP  2.0
ComponentImplementationSelector.cc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2009 Tampere University.
3 
4  This file is part of TTA-Based Codesign Environment (TCE).
5 
6  Permission is hereby granted, free of charge, to any person obtaining a
7  copy of this software and associated documentation files (the "Software"),
8  to deal in the Software without restriction, including without limitation
9  the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  and/or sell copies of the Software, and to permit persons to whom the
11  Software is furnished to do so, subject to the following conditions:
12 
13  The above copyright notice and this permission notice shall be included in
14  all copies or substantial portions of the Software.
15 
16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  DEALINGS IN THE SOFTWARE.
23  */
24 /**
25  * @file ComponentImplementationSelector.cc
26  *
27  * Implementation of ComponentImplementationSelector class
28  *
29  * @author Jari Mäntyneva 2006 (jari.mantyneva-no.spam-tut.fi)
30  * @author Esa Määttä 2008 (esa.maatta-no.spam-tut.fi)
31  * @note rating: red
32  */
33 
35 #include "FunctionUnit.hh"
36 #include "RegisterFile.hh"
37 #include "RFPort.hh"
38 #include "FUPort.hh"
39 #include "Program.hh"
41 #include "ExecutionTrace.hh"
42 #include "CostEstimates.hh"
43 #include "Operation.hh"
44 #include "HDBManager.hh"
45 #include "FUArchitecture.hh"
46 #include "RFArchitecture.hh"
47 #include "HWOperation.hh"
48 #include "StringTools.hh"
49 #include "FUEntry.hh"
50 #include "RFEntry.hh"
52 #include "FUImplementation.hh"
53 #include "ImmediateUnit.hh"
54 
55 using std::map;
56 using std::pair;
57 using std::set;
58 using std::list;
59 using std::string;
60 using namespace HDB;
61 using namespace TTAMachine;
62 
63 
64 /**
65  * The constructor.
66  */
68 }
69 
70 /**
71  * The destructor
72  */
74 }
75 
76 /**
77  * Adds new HDB to look for components.
78  *
79  * @param hdb The HDB file name to be added.
80  * @exception Exception in case there was a problem while opening the HDB.
81  */
82 void
84  usedHDBs_.insert(hdb.fileName());
85 }
86 
87 /**
88  * Adds new traceDB and corresponding program.
89  *
90  * @param program Test case program to be used.
91  * @param traceDB Simulation trace of the program.
92  */
93 void
95  const TTAProgram::Program&, const ExecutionTrace&) {
96 
97 }
98 
99 /**
100  * Finds set of possible function unit implementations.
101  *
102  * Finds out which function unit implementations fulfill the frequency and
103  * area requirements. The implementations are selected by estimating costs
104  * of different function unit implementations that match the given funtion unit
105  * architecture. All implementations that fulfill the given frequency and area
106  * requirements are returned including the estimated cost data of those
107  * implementations.
108  *
109  * @param fu Function unit architecture.
110  * @param frequencyMHz Target frequency (MHz) of the function unit.
111  * @param maxArea Maximum area (in gates) of the function unit.
112  * @return Set of FU implementations with cost estimation data. Returns an
113  * empty set if none found.
114  */
115 map<const IDF::FUImplementationLocation*, CostEstimates*>
117  const TTAMachine::FunctionUnit& fu, double frequencyMHz, double maxArea) {
118 
119  // Get all fu entries matching the given architecture from all available
120  // HDBs and create implementation locations of them.
121  set<const IDF::FUImplementationLocation*> fuImplementations;
122  for (set<string>::const_iterator i = usedHDBs_.begin();
123  i != usedHDBs_.end(); i++) {
124 
125  HDBManager& hdb = HDBRegistry::instance().hdb(*i);
126  set<RowID> fuEntryIDs = hdb.fuEntriesByArchitecture(fu);
127  set<RowID>::const_iterator id = fuEntryIDs.begin();
128  for (; id != fuEntryIDs.end(); id++) {
131  hdb.fileName(), *id,
132  fu.name());
133  IDF::MachineImplementation* machIDF =
135  machIDF->addFUImplementation(fuIDF);
136  fuImplementations.insert(fuIDF);
137  }
138  }
139  map<const IDF::FUImplementationLocation*, CostEstimates*> results;
140  set<const IDF::FUImplementationLocation*>::const_iterator iter =
141  fuImplementations.begin();
142 
143  // in case we are not limiting the costs, return all matching
144  // implementations
145  if (static_cast<int>(frequencyMHz) <= 0 &&
146  static_cast<int>(maxArea) <= 0) {
147 
148  for (; iter != fuImplementations.end(); iter++) {
149  results.insert(
150  pair<const IDF::FUImplementationLocation*, CostEstimates*>(
151  (*iter), NULL));
152  }
153  return results;
154  }
155 
156  // Estimate costs the the implementations
157  while (iter != fuImplementations.end()) {
158  auto rmIt = iter;
159  try {
160  double area = estimator_.functionUnitArea(fu, *(*iter));
161  if (area > maxArea && static_cast<int>(maxArea) > 0) {
162  // FU area too large
163  iter++;
164  fuImplementations.erase(rmIt);
165  continue;
166  }
167  double delayInNanoSeconds =
168  estimator_.functionUnitMaximumComputationDelay(fu, *(*iter));
169 
170  // 1000/ns = MHz
171  if (delayInNanoSeconds > 0 && (static_cast<double>(1000) / static_cast<double>(delayInNanoSeconds)) < static_cast<double>(frequencyMHz)) {
172  // FU too slow
173  iter++;
174  fuImplementations.erase(rmIt);
175  continue;
176  }
177  CostEstimates* estimates = new CostEstimates();
178  estimates->setArea(area);
179  estimates->setLongestPathDelay(delayInNanoSeconds);
180  results.insert(
181  pair<const IDF::FUImplementationLocation*, CostEstimates*>(
182  (*iter), estimates));
183  } catch (CannotEstimateCost& e) {
184  // Couldn't estimate the fu.
185  iter++;
186  fuImplementations.erase(rmIt);
187  continue;
188  }
189  iter++;
190  }
191  return results;
192 }
193 
194 /**
195  * Finds the minimum set of Function units that is needed to satisfy all the
196  * wanted operations.
197  *
198  * Function units are selected so that the number of needed units would be as
199  * low as possible and smaller latency is preferred. If there are units with
200  * same latency then units with smaller amount of operations is preferred. If
201  * there still are units with equal operations then the unit with the widest
202  * triggering port is preferred.
203  *
204  * @param operationSet Set of operation names the resultig set of function
205  * units must include.
206  * @param width Bitwidth of the funtion unit ports. Not used if left as default.
207  * @return Minimal set of function units that have all the asked operations.
208  * Returns an empty set if all operations cannot be supported by any set of
209  * function units.
210  */
211 list<TTAMachine::FunctionUnit*>
213  const std::set<std::string>& operationSet, int width)
214  const {
215 
216  // Convert operation names to lower case.
217  set<string> operations;
218  set<string>::const_iterator oper = operationSet.begin();
219  for (; oper != operationSet.end(); oper++) {
220  operations.insert(StringTools::stringToLower((*oper)));
221  }
222 
223  // Get all function unit architectures.
224  list<pair<TTAMachine::FunctionUnit*, int> >functionUnits;
225  for (set<string>::const_iterator i = usedHDBs_.begin();
226  i != usedHDBs_.end(); i++) {
227 
228  set<RowID> fuArchIDs =
230  operations);
231  set<RowID>::const_iterator iter = fuArchIDs.begin();
232  for (;iter != fuArchIDs.end(); iter++) {
233  FUArchitecture* fuArch =
235 
236  // check the fu port widths if the width is given as parameter
237  if (width) {
238  bool portsDiffer = false;
239  for (int p = 0; p < fuArch->architecture().portCount(); p++) {
240  if (fuArch->architecture().port(p)->width() != width) {
241  portsDiffer = true;
242  }
243  }
244  if (portsDiffer) {
245  continue;
246  }
247  }
248  pair<FunctionUnit*, int> fuIntPair(&fuArch->architecture(), 0);
249  functionUnits.push_back(fuIntPair);
250  }
251  }
252 
253  list<TTAMachine::FunctionUnit*> results;
254 
255  // Find the best set of function units
256  while (operations.size() != 0) {
257  list<pair<TTAMachine::FunctionUnit*, int> >::iterator fu =
258  functionUnits.begin();
259  for (; fu != functionUnits.end(); fu++) {
260  int neededOperations = 0;
261  set<string>::iterator operation = operations.begin();
262  while (operation != operations.end()) {
263  if ((*fu).first->hasOperation(*operation)) {
264  neededOperations++;
265  }
266  operation++;
267  }
268  (*fu).second = neededOperations;
269  }
270 
271  list<TTAMachine::FunctionUnit*> bestMatches;
272  int bestFU = 0;
273 
274  // Find out which FU:s implement most needed operations
275  for (fu = functionUnits.begin(); fu != functionUnits.end(); fu++) {
276  if ((*fu).second > bestFU) {
277  bestMatches.clear();
278  bestMatches.push_back((*fu).first);
279  bestFU = (*fu).second;
280  } else if ((*fu).second == bestFU) {
281  bestMatches.push_back((*fu).first);
282  }
283  }
284 
285  // if found set
286  if (bestMatches.size() != 0) {
287  TTAMachine::FunctionUnit* bestFU = NULL;
288  int minLatency = -1;
289  int minOperations = -1;
290  int maxPortWidth = -1;
291  // Select one of the best FU:s
292  list<TTAMachine::FunctionUnit*>::const_iterator bestMatchFU =
293  bestMatches.begin();
294  for (; bestMatchFU != bestMatches.end(); bestMatchFU++) {
295  int fuMaxLatency = (*bestMatchFU)->maxLatency();
296  if (fuMaxLatency < minLatency) {
297  minLatency = fuMaxLatency;
298  minOperations = (*bestMatchFU)->operationCount();
299  bestFU = (*bestMatchFU);
300  } else if (minLatency == -1) {
301  minLatency = fuMaxLatency;
302  minOperations = (*bestMatchFU)->operationCount();
303  bestFU = (*bestMatchFU);
304  } else if (fuMaxLatency == minLatency) {
305  int fuOperations = (*bestMatchFU)->operationCount();
306  if (fuOperations < minOperations) {
307  minOperations = fuOperations;
308  bestFU = (*bestMatchFU);
309  } else if (minOperations == -1) {
310  minOperations = fuOperations;
311  bestFU = (*bestMatchFU);
312  } else if (fuOperations == minOperations) {
313  int bestFUPortWidth = 0;
314  for (int i = 0;
315  i < (*bestMatchFU)->operationPortCount();
316  i++) {
317 
318  FUPort* port = (*bestMatchFU)->operationPort(i);
319  if (port->isTriggering()) {
320  if (bestFUPortWidth < port->width()) {
321  bestFUPortWidth = port->width();
322  }
323  }
324  }
325  if (maxPortWidth < bestFUPortWidth) {
326  maxPortWidth = bestFUPortWidth;
327  bestFU = (*bestMatchFU);
328  }
329  }
330  }
331  }
332  for (int oper = 0; oper < bestFU->operationCount(); oper++) {
333  operations.erase(
335  bestFU->operation(oper)->name()));
336  }
337  results.push_back(bestFU);
338 
339  // remove the best suitable fu from the set of function untis.
340  list<pair<FunctionUnit*, int> >::iterator fuIntIter =
341  functionUnits.begin();
342  for (; fuIntIter != functionUnits.end(); fuIntIter++) {
343  if ((*fuIntIter).first == bestFU) {
344  functionUnits.erase(fuIntIter);
345  break;
346  }
347  }
348  } else {
349  break;
350  }
351  }
352  if (operations.size() != 0) {
353  results.clear();
354  }
355  return results;
356 }
357 
358 /**
359  * Finds set of possible register file implementations.
360  *
361  * Finds out which register file implementations fulfill the frequency and
362  * area requirements. The implementations are selected by estimating costs
363  * of different register file implementations that match the given register file
364  * architecture. All implementations that fulfill the given frequency and area
365  * requirements are returned including the estimated cost data of those
366  * implementations.
367  *
368  * @param rf Register file architecture.
369  * @param guarded Flag indicating if the register file is guarded, defaults
370  * to false.
371  * @param frequencyMHz Target frequency (MHz) of the register file.
372  * @param maxArea Maximum area (in gates) of the register file.
373  * @return Set of RF implementations with cost evaluation data. Returns an
374  * empty set if none found.
375  */
376 map<const IDF::RFImplementationLocation*, CostEstimates*>
378  const TTAMachine::RegisterFile& rf, bool guarded, double frequencyMHz,
379  double maxArea) {
380 
381  // Get all rf entries matching the given architecture from all available
382  // HDBs and create implementation locations of them.
383  set<const IDF::RFImplementationLocation*> rfImplementations;
384  for (set<string>::const_iterator i = usedHDBs_.begin();
385  i != usedHDBs_.end(); i++) {
386 
387  HDBManager& hdb = HDBRegistry::instance().hdb(*i);
388  int readPorts = 0;
389  int writePorts = 0;
390  int bidirPorts = 0;
391  for (int p = 0; p < rf.portCount(); p++) {
392  const TTAMachine::RFPort* port = rf.port(p);
393  if (port->inputSocket() != NULL && port->outputSocket() != NULL) {
394  bidirPorts++;
395  } else if (port->inputSocket() != NULL) {
396  writePorts++;
397  } else if (port->outputSocket() != NULL) {
398  readPorts++;
399  }
400  }
401  set<RowID> rfEntryIDs = hdb.rfEntriesByArchitecture(
402  readPorts, writePorts, bidirPorts, rf.maxReads(), rf.maxWrites(),
403  // latency always 1
404  1,
405  // guard support
406  guarded,
407  // guard latency
408  rf.guardLatency(), rf.width(), rf.numberOfRegisters(),
409  rf.zeroRegister());
410 
411  set<RowID>::const_iterator id = rfEntryIDs.begin();
412  for (; id != rfEntryIDs.end(); id++) {
415  hdb.fileName(), *id, rf.name());
416  IDF::MachineImplementation* machIDF =
418  machIDF->addRFImplementation(rfIDF);
419  rfImplementations.insert(rfIDF);
420  }
421  }
422  map<const IDF::RFImplementationLocation*, CostEstimates*> results;
423  set<const IDF::RFImplementationLocation*>::const_iterator iter =
424  rfImplementations.begin();
425 
426  // in case we are not limiting the costs, return all matching
427  // implementations
428  if (static_cast<int>(frequencyMHz) <= 0 &&
429  static_cast<int>(maxArea) <= 0) {
430 
431  for (; iter != rfImplementations.end(); iter++) {
432  results.insert(
433  pair<const IDF::RFImplementationLocation*, CostEstimates*>(
434  (*iter), NULL));
435  }
436  return results;
437  }
438 
439  while (iter != rfImplementations.end()) {
440  auto rmIt = iter;
441  try {
442  double area = estimator_.registerFileArea(rf, *(*iter));
443  if (area > maxArea && static_cast<int>(maxArea) > 0) {
444  // RF area too large
445  iter++;
446  rfImplementations.erase(rmIt);
447  continue;
448  }
449  double delayInNanoSeconds =
450  estimator_.registerFileMaximumComputationDelay(rf, *(*iter));
451 
452  // 1000/ns = MHz
453  if ((1000/delayInNanoSeconds) < frequencyMHz) {
454  // RF too slow
455  iter++;
456  rfImplementations.erase(rmIt);
457  continue;
458  }
459  CostEstimates* estimates = new CostEstimates();
460  estimates->setArea(area);
461  estimates->setLongestPathDelay(delayInNanoSeconds);
462  results.insert(
463  pair<const IDF::RFImplementationLocation*, CostEstimates*>(
464  (*iter), estimates));
465  } catch (CannotEstimateCost& e) {
466  // Couldn't estimate the rf.
467  iter++;
468  rfImplementations.erase(rmIt);
469  continue;
470  }
471  iter++;
472  }
473  return results;
474 }
475 
476 
477 /**
478  * Finds set of possible immediate unit implementations.
479  *
480  * Finds out which immediate unit implementations fulfill the frequency and
481  * area requirements. The implementations are selected by estimating costs
482  * of different immediate unit implementations that match the given immediate
483  * unit architecture. All implementations that fulfill the given frequency
484  * and area requirements are returned including the estimated cost data of
485  * those implementations.
486  *
487  * @param iu Immediate unit architecture.
488  * @param frequencyMHz Target frequency (MHz) of the immediate unit.
489  * @param maxArea Maximum area (in gates) of the immediate unit.
490  * @return Set of IU implementations with cost evaluation data. Returns an
491  * empty set if none found.
492  */
493 map<const IDF::IUImplementationLocation*, CostEstimates*>
495  const TTAMachine::ImmediateUnit& iu, double frequencyMHz, double maxArea) {
496 
497  // Get all iu entries matching the given architecture from all available
498  // HDBs and create implementation locations of them.
499  set<const IDF::IUImplementationLocation*> iuImplementations;
500  for (set<string>::const_iterator i = usedHDBs_.begin();
501  i != usedHDBs_.end(); i++) {
502 
503  HDBManager& hdb = HDBRegistry::instance().hdb(*i);
504  int readPorts = iu.portCount();
505 
506  set<RowID> iuEntryIDs =
508  readPorts,
509  1, // writePorts in iu is always 1, not visible in adf
510  0, // bidirPorts
511  0, // maxReads
512  0, // maxWrites
513  1, // latency always 1
514  false, // guard support always false
515  0, // guard latency
516  iu.width(),
517  iu.numberOfRegisters());
518 
519  set<RowID>::const_iterator id = iuEntryIDs.begin();
520  for (; id != iuEntryIDs.end(); id++) {
523  hdb.fileName(), *id, iu.name());
524  IDF::MachineImplementation* machIDF =
526  machIDF->addIUImplementation(iuIDF);
527  iuImplementations.insert(iuIDF);
528  }
529  }
530  map<const IDF::IUImplementationLocation*, CostEstimates*> results;
531  set<const IDF::IUImplementationLocation*>::const_iterator iter =
532  iuImplementations.begin();
533 
534  // in case we are not limiting the costs, return all matching
535  // implementations
536  if (static_cast<int>(frequencyMHz) <= 0 &&
537  static_cast<int>(maxArea) <= 0) {
538 
539  for (; iter != iuImplementations.end(); iter++) {
540  results.insert(
541  pair<const IDF::IUImplementationLocation*, CostEstimates*>(
542  (*iter), NULL));
543  }
544  return results;
545  }
546 
547  while (iter != iuImplementations.end()) {
548  auto rmIt = iter;
549  try {
550  double area = estimator_.registerFileArea(iu, *(*iter));
551  if (area > maxArea && static_cast<int>(maxArea) > 0) {
552  // IU area too large
553  iter++;
554  iuImplementations.erase(rmIt);
555  continue;
556  }
557  double delayInNanoSeconds =
558  estimator_.registerFileMaximumComputationDelay(iu, *(*iter));
559 
560  // 1000/ns = MHz
561  if ((1000/delayInNanoSeconds) < frequencyMHz) {
562  // RF too slow
563  iter++;
564  iuImplementations.erase(rmIt);
565  continue;
566  }
567  CostEstimates* estimates = new CostEstimates();
568  estimates->setArea(area);
569  estimates->setLongestPathDelay(delayInNanoSeconds);
570  results.insert(
571  pair<const IDF::IUImplementationLocation*, CostEstimates*>(
572  (*iter), estimates));
573  } catch (CannotEstimateCost& e) {
574  // Couldn't estimate the iu.
575  iter++;
576  iuImplementations.erase(rmIt);
577  continue;
578  }
579  iter++;
580  }
581  return results;
582 }
583 
584 
585 /**
586  * Selects the implementations for machine configuration.
587  *
588  * Stores created idf to the given configuration and the configuration hold
589  * information in the given dsdb. If no machine is given then read the machine
590  * from dsdb through given configuration.
591  *
592  * @param conf Machine configuration.
593  * @param dsdb DSDB where implementation is added.
594  * @param mach Machine for what the implementation is generated.
595  * @param icDecoder The name of the ic decoder plugin for idf.
596  * @param icDecoderHDB The name of the hdb used by ic decoder plugin.
597  * @param frequency The minimum frequency of the implementations.
598  * @param maxArea The maximum area of the implementations.
599  */
600 void
603  TTAMachine::Machine* mach, const std::string& icDecoder,
604  const std::string& icDecoderHDB, const double& frequency,
605  const double& maxArea) {
606  if (mach == NULL) {
607  try {
608  mach = dsdb.architecture(conf.architectureID);
609  } catch (const Exception& e) {
610  Exception error(__FILE__, __LINE__, __func__,
611  e.errorMessage());
612  error.setCause(e);
613  throw error;
614  }
615  }
616 
617  IDF::MachineImplementation* idf = NULL;
618  try {
619  // building the idf
620  idf = selectComponents(
621  mach, icDecoder, icDecoderHDB, frequency, maxArea);
622  } catch (const Exception& e) {
623  Exception error(__FILE__, __LINE__, __func__,
624  e.errorMessage());
625  error.setCause(e);
626  conf.hasImplementation = false;
627  throw error;
628  }
629 
630  conf.implementationID = dsdb.addImplementation(*idf, 0, 0);
631  conf.hasImplementation = true;
632 }
633 
634 /**
635  * Selects the implementations for the machine configuration.
636  *
637  * @param configuration MachineConfiguration of which architecture is used.
638  * @param frequency The minimum frequency of the implementations.
639  * @param icDecoder The name of the ic decoder plugin for idf.
640  * @param icDecoderHDB The name of the hdb used by ic decoder plugin.
641  * @return RowID of the new machine configuration having adf and idf.
642  * @exception Exception No suitable implementations found.
643  */
646  const TTAMachine::Machine* mach, const std::string& icDecoder,
647  const std::string& icDecoderHDB, const double& frequency,
648  const double& maxArea) {
649  HDBRegistry& hdbRegistry = HDBRegistry::instance();
650  for (int i = 0; i < hdbRegistry.hdbCount(); i++) {
651  addHDB(hdbRegistry.hdb(i));
652  }
653 
655 
656  // select implementations for funtion units
657  selectFUs(mach, idf, frequency, maxArea);
658 
659  // select implementations for register files
660  selectRFs(mach, idf);
661 
662  // select implementations for immediate units
663  selectIUs(mach, idf, frequency, maxArea);
664 
665  // add the ic decoder plugin
666  std::vector<std::string> icDecPaths =
668  idf->setICDecoderPluginName(icDecoder);
669  idf->setICDecoderHDB(icDecoderHDB);
670  std::vector<std::string>::const_iterator iter = icDecPaths.begin();
671  for (; iter != icDecPaths.end(); iter++) {
672  std::string path = *iter;
673  std::string file =
674  path + FileSystem::DIRECTORY_SEPARATOR + icDecoder + "Plugin.so";
675  if (FileSystem::fileExists(file)) {
676  idf->setICDecoderPluginFile(file);
677  break;
678  }
679  }
680 
681  return idf;
682 }
683 
684 /**
685  * Selects the implementations for FUs in the machine configuration.
686  *
687  * frequency and maxArea to zero by default.
688  * TODO: throw more appropriate exceptions
689  */
690 void
693  const double& frequency, const double& maxArea,
694  const bool& filterLongestPathDelay) {
696 
697  // select implementations for funtion units
698  for (int i = 0; i < fuNav.count(); i++) {
699  FunctionUnit* fu = fuNav.item(i);
700 
701  map<const IDF::FUImplementationLocation*, CostEstimates*> fuMap =
702  fuImplementations(*fu, frequency, maxArea);
703  // Create an id ordered set of idf entries to ensure
704  // deterministic behaviour
705  set<std::pair<const IDF::FUImplementationLocation*, CostEstimates*>,
706  implComp> fuSet;
707  for (map<const IDF::FUImplementationLocation*,
708  CostEstimates*>::iterator i = fuMap.begin();
709  i != fuMap.end(); i++) {
710  fuSet.insert(
711  std::make_pair(i->first, i->second));
712  }
713 
714  set<std::pair<const IDF::FUImplementationLocation*, CostEstimates*> >::
715  const_iterator iter = fuSet.begin();
716  if (fuMap.size() != 0) {
717  set<std::pair<const IDF::FUImplementationLocation*,
718  CostEstimates*> >::const_iterator wanted = iter;
719  if (filterLongestPathDelay && maxArea > 0 && frequency > 0) {
720  double longestPathDelay = 0;
721  double area = 0;
722  bool first = true;
723  while (iter != fuSet.end()) {
724  CostEstimates* estimate = iter->second;
725  if (estimate == NULL) {
726  std::string errorMsg = "When selecting FUs regarding"
727  " longest path delay, no cost estimates were"
728  " found for FU: " + fu->name();
730  __FILE__, __LINE__, __func__, errorMsg, 1);
731  break;
732  }
733  if (first) {
734  area = estimate->area();
735  longestPathDelay = estimate->longestPathDelay();
736  wanted = iter;
737  first = false;
738  } else if (longestPathDelay <
739  estimate->longestPathDelay()) {
740  longestPathDelay = estimate->longestPathDelay();
741  area = estimate->area();
742  wanted = iter;
743  } else if (longestPathDelay ==
744  estimate->longestPathDelay() &&
745  area < estimate->area()) {
746  area = estimate->area();
747  wanted = iter;
748  }
749  iter++;
750  }
751  }
752 
753  const IDF::FUImplementationLocation* fuImpl = (*wanted).first;
754 
755  ObjectState* state = fuImpl->saveState();
756  IDF::FUImplementationLocation* newFUImpl =
758 
759  try {
760  idf->addFUImplementation(newFUImpl);
761  } catch (const Exception& e) {
762  Exception error(
763  __FILE__, __LINE__, __func__,
764  e.errorMessage());
765  error.setCause(e);
766  throw error;
767  }
768  } else {
769  throw Exception(
770  __FILE__, __LINE__, __func__,
771  "no implementations found for FU: " + fu->name());
772  }
773  }
774 }
775 
776 /**
777  * Selects the implementations for RFs in the machine configuration.
778  *
779  * Selects the the RF that has biggest longest path delay.
780  *
781  */
782 void
785  const double& frequency, const double& maxArea) {
787 
788  // selects the register that has biggest longest path delay
789  for (int i = 0; i < rfNav.count(); i++) {
790  RegisterFile* rf = rfNav.item(i);
791  map<const IDF::RFImplementationLocation*, CostEstimates*> rfMap;
792 
793  // check if the register is boolean register.
794  if (rf->isUsedAsGuard()) {
795  // select from guarded registers
796  rfMap = rfImplementations(*rf, true, frequency, maxArea);
797  } else {
798  // select from non guarded registers
799  rfMap = rfImplementations(*rf, false, frequency, maxArea);
800  }
801  // Create an id ordered set of idf entries to ensure the deterministic behaviour
802  set<std::pair<const IDF::RFImplementationLocation*, CostEstimates*>, implComp> rfSet;
803  for ( map<const IDF::RFImplementationLocation*, CostEstimates*>::const_iterator i = rfMap.begin();
804  i != rfMap.end(); i++) {
805  rfSet.insert(std::make_pair(i->first, i->second));
806  }
807  set<std::pair<const IDF::RFImplementationLocation*, CostEstimates*> >::const_iterator iter = rfSet.begin();
808  if (rfMap.size() != 0) {
809  double longestPathDelay = 0;
810  double area = 0;
811  bool first = true;
812  set<std::pair<const IDF::RFImplementationLocation*,
813  CostEstimates*> >::const_iterator wanted = iter;
814  if (maxArea > 0 && frequency > 0) {
815  while (iter != rfSet.end()) {
816  CostEstimates* estimate = iter->second;
817  if (estimate == NULL) {
818  std::string errorMsg = "When selecting RFs regarding"
819  " longest path delay, no cost estimates were"
820  " found for RF: " + rf->name();
822  __FILE__, __LINE__, __func__, errorMsg, 1);
823  break;
824  }
825  if (first) {
826  area = estimate->area();
827  longestPathDelay = estimate->longestPathDelay();
828  wanted = iter;
829  first = false;
830  } else if (longestPathDelay < estimate->longestPathDelay()) {
831  longestPathDelay = estimate->longestPathDelay();
832  area = estimate->area();
833  wanted = iter;
834  } else if (longestPathDelay == estimate->longestPathDelay() && area < estimate->area()) {
835  area = estimate->area();
836  wanted = iter;
837  }
838 
839  iter++;
840  }
841  }
842  const IDF::RFImplementationLocation* rfImpl = (*wanted).first;
843  ObjectState* state = rfImpl->saveState();
844  IDF::RFImplementationLocation* newRFImpl =
846  try {
847  idf->addRFImplementation(newRFImpl);
848  } catch (const Exception& e) {
849  Exception error(__FILE__, __LINE__, __func__,
850  e.errorMessage());
851  error.setCause(e);
852  throw error;
853  }
854  } else {
855  throw Exception(
856  __FILE__, __LINE__, __func__,
857  "no implementations found for RF: " + rf->name());
858  }
859  }
860 }
861 
862 /**
863  * Selects the implementations for IUs in the machine configuration.
864  *
865  */
866 void
869  const double& frequency, const double& maxArea) {
871 
872  // select implementations for immediate units
873  for (int index = 0; index < iuNav.count(); index++) {
874  TTAMachine::ImmediateUnit* iu = iuNav.item(index);
875 
876  map<const IDF::IUImplementationLocation*, CostEstimates*> iuMap =
877  iuImplementations(*iu, frequency, maxArea);
878 
879  // Create an id ordered set of idf entries to ensure the deterministic behaviour
880  set<std::pair<const IDF::IUImplementationLocation*, CostEstimates*>, implComp> iuSet;
881  for (map<const IDF::IUImplementationLocation*, CostEstimates*>::const_iterator i =
882  iuMap.begin(); i != iuMap.end(); i++) {
883  iuSet.insert(std::make_pair(i->first, i->second));
884  }
885  set<std::pair<const IDF::IUImplementationLocation*,
886  CostEstimates*> >::const_iterator iter = iuSet.begin();
887  if (iuMap.size() != 0) {
888  double longestPathDelay = 0;
889  double area = 0;
890  bool first = true;
891  set<std::pair<const IDF::RFImplementationLocation*, CostEstimates*> >::const_iterator wanted = iter;
892 
893  while (iter != iuSet.end()) {
894  CostEstimates* estimate = iter->second;
895  if (estimate == NULL) {
896  std::string errorMsg = "When selecting IUs regarding"
897  " longest path delay, no cost estimates were"
898  " found for IU: " + iu->name();
900  __FILE__, __LINE__, __func__, errorMsg, 1);
901  break;
902  }
903  if (first) {
904  area = estimate->area();
905  longestPathDelay = estimate->longestPathDelay();
906  wanted = iter;
907  first = false;
908  } else if (longestPathDelay < estimate->longestPathDelay()) {
909  longestPathDelay = estimate->longestPathDelay();
910  area = estimate->area();
911  wanted = iter;
912  } else if (longestPathDelay == estimate->longestPathDelay() && area < estimate->area()) {
913  area = estimate->area();
914  wanted = iter;
915  }
916  iter++;
917  }
918 
919  const IDF::IUImplementationLocation* iuImpl = (*wanted).first;
920  ObjectState* state = iuImpl->saveState();
921  IDF::IUImplementationLocation* newIUImpl =
923  try {
924  idf->addIUImplementation(newIUImpl);
925  } catch (const Exception& e) {
926  Exception error(__FILE__, __LINE__, __func__,
927  e.errorMessage());
928  error.setCause(e);
929  throw error;
930  }
931  } else {
932  throw Exception(
933  __FILE__, __LINE__, __func__,
934  "no implementations found for IU: " + iu->name());
935  }
936  }
937 }
IDF::UnitImplementationLocation
Definition: UnitImplementationLocation.hh:48
HDB::FUArchitecture
Definition: FUArchitecture.hh:55
ComponentImplementationSelector::selectComponents
IDF::MachineImplementation * selectComponents(const TTAMachine::Machine *mach, const std::string &icDecoder="ic_hdb", const std::string &icDecoderHDB="asic_130nm_1.5V.hdb", const double &frequency=0, const double &maxArea=0)
Definition: ComponentImplementationSelector.cc:645
TTAProgram::Program
Definition: Program.hh:63
IDF::RFImplementationLocation
UnitImplementationLocation RFImplementationLocation
Definition: ComponentImplementationSelector.hh:57
TTAMachine::Port::inputSocket
virtual Socket * inputSocket() const
Definition: Port.cc:261
CostEstimates::setLongestPathDelay
void setLongestPathDelay(double delay)
Definition: CostEstimates.cc:69
TTAMachine::Component::name
virtual TCEString name() const
Definition: MachinePart.cc:125
ComponentImplementationSelector::addHDB
void addHDB(const HDB::HDBManager &hdb)
Definition: ComponentImplementationSelector.cc:83
HDB
Definition: CostDatabase.hh:49
ComponentImplementationSelector::~ComponentImplementationSelector
virtual ~ComponentImplementationSelector()
Definition: ComponentImplementationSelector.cc:73
CostEstimates
Definition: CostEstimates.hh:57
DSDBManager::architecture
TTAMachine::Machine * architecture(RowID id) const
Definition: DSDBManager.cc:807
FUArchitecture.hh
ComponentImplementationSelector::selectIUs
void selectIUs(const TTAMachine::Machine *mach, IDF::MachineImplementation *idf, const double &frequency=0, const double &maxArea=0)
Definition: ComponentImplementationSelector.cc:867
DSDBManager::MachineConfiguration::hasImplementation
bool hasImplementation
Definition: DSDBManager.hh:80
Application::writeToErrorLog
static void writeToErrorLog(const std::string fileName, const int lineNumber, const std::string functionName, const std::string message, const int neededVerbosity=0)
Definition: Application.cc:224
CannotEstimateCost
Definition: Exception.hh:748
HDB::FUArchitecture::architecture
TTAMachine::FunctionUnit & architecture() const
Definition: FUArchitecture.cc:131
ComponentImplementationSelector::addCase
void addCase(const TTAProgram::Program &program, const ExecutionTrace &traceDB)
Definition: ComponentImplementationSelector.cc:94
Exception::setCause
void setCause(const Exception &cause)
Definition: Exception.cc:75
ObjectState
Definition: ObjectState.hh:59
ComponentImplementationSelector::rfImplementations
std::map< const IDF::RFImplementationLocation *, CostEstimates * > rfImplementations(const TTAMachine::RegisterFile &rf, bool guarded=false, double frequencyMHz=0, double maxArea=0)
Definition: ComponentImplementationSelector.cc:377
HDB::HDBRegistry::hdb
CachedHDBManager & hdb(const std::string fileName)
Definition: HDBRegistry.cc:80
ImmediateUnit.hh
Environment::icDecoderPluginPaths
static std::vector< std::string > icDecoderPluginPaths(bool libraryPathsOnly=false)
Definition: Environment.cc:635
HDB::CachedHDBManager::fuArchitectureByID
virtual FUArchitecture * fuArchitectureByID(RowID id) const
Definition: CachedHDBManager.cc:218
TTAMachine::FunctionUnit::port
virtual BaseFUPort * port(const std::string &name) const
Definition: FunctionUnit.cc:145
TTAMachine::Machine::Navigator::count
int count() const
TTAMachine::FUPort::isTriggering
virtual bool isTriggering() const
Definition: FUPort.cc:182
ComponentImplementationSelector::implComp
Definition: ComponentImplementationSelector.hh:133
TTAMachine::RegisterFile::maxWrites
virtual int maxWrites() const
Definition: RegisterFile.cc:135
HDB::HDBManager::fuArchitectureIDsByOperationSet
std::set< RowID > fuArchitectureIDsByOperationSet(const std::set< std::string > &operationNames) const
Definition: HDBManager.cc:2684
TTAMachine::RFPort
Definition: RFPort.hh:45
ComponentImplementationSelector::ComponentImplementationSelector
ComponentImplementationSelector()
Definition: ComponentImplementationSelector.cc:67
TTAMachine::BaseRegisterFile::numberOfRegisters
virtual int numberOfRegisters() const
StringTools.hh
TTAMachine::FunctionUnit
Definition: FunctionUnit.hh:55
TTAMachine::FUPort
Definition: FUPort.hh:46
IDF::MachineImplementation::setICDecoderHDB
void setICDecoderHDB(const std::string &file)
Definition: MachineImplementation.cc:1488
DSDBManager::MachineConfiguration::implementationID
RowID implementationID
Definition: DSDBManager.hh:81
TTAMachine::RegisterFile::maxReads
virtual int maxReads() const
Definition: RegisterFile.cc:123
CostEstimates::longestPathDelay
double longestPathDelay() const
Definition: CostEstimates.cc:112
HDB::HDBRegistry
Definition: HDBRegistry.hh:46
HWOperation.hh
DSDBManager::MachineConfiguration
Definition: DSDBManager.hh:78
TTAMachine::HWOperation::name
const std::string & name() const
Definition: HWOperation.cc:141
TTAMachine::Machine::immediateUnitNavigator
virtual ImmediateUnitNavigator immediateUnitNavigator() const
Definition: Machine.cc:416
ComponentImplementationSelector::fuImplementations
std::map< const IDF::FUImplementationLocation *, CostEstimates * > fuImplementations(const TTAMachine::FunctionUnit &fu, double frequencyMHz=0, double maxArea=0)
Definition: ComponentImplementationSelector.cc:116
IDF::MachineImplementation::setICDecoderPluginName
void setICDecoderPluginName(const std::string &name)
Definition: MachineImplementation.cc:1462
ExecutionTrace
Definition: ExecutionTrace.hh:56
CostEstimates.hh
FUEntry.hh
NullUnitImplementationLocation.hh
__func__
#define __func__
Definition: Application.hh:67
ComponentImplementationSelector::selectFUs
void selectFUs(const TTAMachine::Machine *mach, IDF::MachineImplementation *idf, const double &frequency=0, const double &maxArea=0, const bool &filterLongestPathDelay=true)
Definition: ComponentImplementationSelector.cc:691
TTAMachine::Machine::functionUnitNavigator
virtual FunctionUnitNavigator functionUnitNavigator() const
Definition: Machine.cc:380
HDB::HDBManager::fuEntriesByArchitecture
std::set< RowID > fuEntriesByArchitecture(const TTAMachine::FunctionUnit &fu) const
Definition: HDBManager.cc:3040
IDF::FUImplementationLocation
UnitImplementationLocation FUImplementationLocation
Definition: ComponentImplementationSelector.hh:55
HDB::HDBManager::rfEntriesByArchitecture
std::set< RowID > rfEntriesByArchitecture(int readPorts, int writePorts, int bidirPorts, int maxReads, int maxWrites, int latency, bool guardSupport, int guardLatency=0, int width=0, int size=0, bool zeroRegister=false) const
Definition: HDBManager.cc:3133
CostEstimates::area
double area() const
Definition: CostEstimates.cc:101
TTAMachine::FunctionUnit::operationCount
virtual int operationCount() const
Definition: FunctionUnit.cc:419
HDB::HDBManager
Definition: HDBManager.hh:82
Operation.hh
RFArchitecture.hh
IDF::MachineImplementation::addRFImplementation
void addRFImplementation(RFImplementationLocation *implementation)
Definition: MachineImplementation.cc:554
Exception
Definition: Exception.hh:54
DSDBManager
Definition: DSDBManager.hh:76
ComponentImplementationSelector.hh
FUImplementation.hh
TTAMachine::Unit::portCount
virtual int portCount() const
Definition: Unit.cc:135
Exception::errorMessage
std::string errorMessage() const
Definition: Exception.cc:123
HDB::HDBRegistry::hdbCount
int hdbCount()
Definition: HDBRegistry.cc:135
FileSystem::DIRECTORY_SEPARATOR
static const std::string DIRECTORY_SEPARATOR
Definition: FileSystem.hh:189
IDF::UnitImplementationLocation::saveState
ObjectState * saveState() const
Definition: UnitImplementationLocation.cc:187
HDB::HDBManager::fileName
std::string fileName() const
Definition: HDBManager.cc:612
ComponentImplementationSelector::selectRFs
void selectRFs(const TTAMachine::Machine *mach, IDF::MachineImplementation *idf, const double &frequency=0, const double &maxArea=0)
Definition: ComponentImplementationSelector.cc:783
TTAMachine::BaseRegisterFile::port
virtual RFPort * port(const std::string &name) const
Definition: BaseRegisterFile.cc:129
TTAMachine::Machine::registerFileNavigator
virtual RegisterFileNavigator registerFileNavigator() const
Definition: Machine.cc:450
Program.hh
TTAMachine::RegisterFile::isUsedAsGuard
virtual bool isUsedAsGuard() const
Definition: RegisterFile.cc:567
IDF::MachineImplementation::addFUImplementation
void addFUImplementation(FUImplementationLocation *implementation)
Definition: MachineImplementation.cc:533
CostEstimates::setArea
void setArea(double area)
Definition: CostEstimates.cc:58
IDF::IUImplementationLocation
UnitImplementationLocation IUImplementationLocation
Definition: ComponentImplementationSelector.hh:58
FileSystem::fileExists
static bool fileExists(const std::string fileName)
RegisterFile.hh
ComponentImplementationSelector::fuArchsByOpSetWithMinLatency
std::list< TTAMachine::FunctionUnit * > fuArchsByOpSetWithMinLatency(const std::set< std::string > &operationSet, int width=0) const
Definition: ComponentImplementationSelector.cc:212
FUPort.hh
TTAMachine::Port::outputSocket
virtual Socket * outputSocket() const
Definition: Port.cc:281
ComponentImplementationSelector::iuImplementations
std::map< const IDF::IUImplementationLocation *, CostEstimates * > iuImplementations(const TTAMachine::ImmediateUnit &iu, double frequencyMHz=0, double maxArea=0)
Definition: ComponentImplementationSelector.cc:494
RFEntry.hh
RFPort.hh
TTAMachine::Machine::Navigator::item
ComponentType * item(int index) const
TTAMachine::FunctionUnit::operation
virtual HWOperation * operation(const std::string &name) const
Definition: FunctionUnit.cc:363
TTAMachine::RegisterFile::guardLatency
virtual int guardLatency() const
Definition: RegisterFile.cc:333
TTAMachine::RegisterFile
Definition: RegisterFile.hh:47
ComponentImplementationSelector::selectComponentsToConf
void selectComponentsToConf(DSDBManager::MachineConfiguration &conf, DSDBManager &dsdb, TTAMachine::Machine *mach=NULL, const std::string &icDecoder="ic_hdb", const std::string &icDecoderHDB="asic_130nm_1.5V.hdb", const double &frequency=0, const double &maxArea=0)
Definition: ComponentImplementationSelector.cc:601
IDF::MachineImplementation::setICDecoderPluginFile
void setICDecoderPluginFile(const std::string &file)
Definition: MachineImplementation.cc:1474
TTAMachine
Definition: Assembler.hh:48
HDBManager.hh
TTAMachine::BaseRegisterFile::width
virtual int width() const
DSDBManager::MachineConfiguration::architectureID
RowID architectureID
Definition: DSDBManager.hh:79
TTAMachine::Machine::Navigator
Definition: Machine.hh:186
DSDBManager::addImplementation
RowID addImplementation(const IDF::MachineImplementation &impl, double longestPathDelay, CostEstimator::AreaInGates area)
Definition: DSDBManager.cc:252
IDF::MachineImplementation
Definition: MachineImplementation.hh:54
StringTools::stringToLower
static std::string stringToLower(const std::string &source)
Definition: StringTools.cc:160
UnitImplementationLocation.hh
IDF::MachineImplementation::addIUImplementation
void addIUImplementation(RFImplementationLocation *implementation)
Definition: MachineImplementation.cc:575
TTAMachine::BaseFUPort::width
virtual int width() const
Definition: BaseFUPort.cc:109
TTAMachine::RegisterFile::zeroRegister
virtual bool zeroRegister() const
Definition: RegisterFile.cc:629
TTAMachine::Machine
Definition: Machine.hh:73
FunctionUnit.hh
HDB::HDBRegistry::instance
static HDBRegistry & instance()
Definition: HDBRegistry.cc:62
ExecutionTrace.hh
TTAMachine::ImmediateUnit
Definition: ImmediateUnit.hh:50