OpenASIP 2.2
Loading...
Searching...
No Matches
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
55using std::map;
56using std::pair;
57using std::set;
58using std::list;
59using std::string;
60using namespace HDB;
61using namespace TTAMachine;
62
63
64/**
65 * The constructor.
66 */
69
70/**
71 * The destructor
72 */
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 */
82void
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 */
93void
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 */
115map<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
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());
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 =
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 */
211list<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 */
376map<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
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());
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 =
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 */
493map<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
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());
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 =
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 */
600void
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 */
690void
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();
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 */
782void
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();
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 */
866void
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();
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}
#define __func__
static void writeToErrorLog(const std::string fileName, const int lineNumber, const std::string functionName, const std::string message, const int neededVerbosity=0)
std::set< std::string > usedHDBs_
HDBs from which implementations are serched are stored in this set.
void selectRFs(const TTAMachine::Machine *mach, IDF::MachineImplementation *idf, const double &frequency=0, const double &maxArea=0)
std::list< TTAMachine::FunctionUnit * > fuArchsByOpSetWithMinLatency(const std::set< std::string > &operationSet, int width=0) const
void selectFUs(const TTAMachine::Machine *mach, IDF::MachineImplementation *idf, const double &frequency=0, const double &maxArea=0, const bool &filterLongestPathDelay=true)
std::map< const IDF::FUImplementationLocation *, CostEstimates * > fuImplementations(const TTAMachine::FunctionUnit &fu, double frequencyMHz=0, double maxArea=0)
std::map< const IDF::RFImplementationLocation *, CostEstimates * > rfImplementations(const TTAMachine::RegisterFile &rf, bool guarded=false, double frequencyMHz=0, double maxArea=0)
std::map< const IDF::IUImplementationLocation *, CostEstimates * > iuImplementations(const TTAMachine::ImmediateUnit &iu, double frequencyMHz=0, double maxArea=0)
void selectIUs(const TTAMachine::Machine *mach, IDF::MachineImplementation *idf, const double &frequency=0, const double &maxArea=0)
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)
CostEstimator::Estimator estimator_
Cost estimator to estimate the unit costs.
void addCase(const TTAProgram::Program &program, const ExecutionTrace &traceDB)
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)
void setLongestPathDelay(double delay)
void setArea(double area)
double area() const
double longestPathDelay() const
DelayInNanoSeconds registerFileMaximumComputationDelay(const TTAMachine::BaseRegisterFile &architecture, const IDF::RFImplementationLocation &implementationEntry)
Definition Estimator.cc:876
DelayInNanoSeconds functionUnitMaximumComputationDelay(const TTAMachine::FunctionUnit &architecture, const IDF::FUImplementationLocation &implementation)
Definition Estimator.cc:834
AreaInGates registerFileArea(const TTAMachine::BaseRegisterFile &architecture, const IDF::RFImplementationLocation &implementationEntry)
Definition Estimator.cc:398
AreaInGates functionUnitArea(const TTAMachine::FunctionUnit &architecture, const IDF::FUImplementationLocation &implementationEntry)
Definition Estimator.cc:364
TTAMachine::Machine * architecture(RowID id) const
RowID addImplementation(const IDF::MachineImplementation &impl, double longestPathDelay, CostEstimator::AreaInGates area)
static std::vector< std::string > icDecoderPluginPaths(bool libraryPathsOnly=false)
std::string errorMessage() const
Definition Exception.cc:123
void setCause(const Exception &cause)
Definition Exception.cc:75
static const std::string DIRECTORY_SEPARATOR
static bool fileExists(const std::string fileName)
virtual FUArchitecture * fuArchitectureByID(RowID id) const
TTAMachine::FunctionUnit & architecture() const
std::set< RowID > fuEntriesByArchitecture(const TTAMachine::FunctionUnit &fu) const
std::set< RowID > fuArchitectureIDsByOperationSet(const std::set< std::string > &operationNames) const
std::string fileName() const
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
static HDBRegistry & instance()
CachedHDBManager & hdb(const std::string fileName)
void setICDecoderHDB(const std::string &file)
void setICDecoderPluginFile(const std::string &file)
void addIUImplementation(RFImplementationLocation *implementation)
void addRFImplementation(RFImplementationLocation *implementation)
void addFUImplementation(FUImplementationLocation *implementation)
void setICDecoderPluginName(const std::string &name)
static std::string stringToLower(const std::string &source)
virtual int width() const
virtual int numberOfRegisters() const
virtual int width() const
virtual RFPort * port(const std::string &name) const
virtual TCEString name() const
virtual bool isTriggering() const
Definition FUPort.cc:182
virtual HWOperation * operation(const std::string &name) const
virtual int operationCount() const
virtual int maxLatency() const
virtual BaseFUPort * port(const std::string &name) const
const std::string & name() const
ComponentType * item(int index) const
virtual RegisterFileNavigator registerFileNavigator() const
Definition Machine.cc:450
virtual FunctionUnitNavigator functionUnitNavigator() const
Definition Machine.cc:380
virtual ImmediateUnitNavigator immediateUnitNavigator() const
Definition Machine.cc:416
virtual Socket * outputSocket() const
Definition Port.cc:281
virtual Socket * inputSocket() const
Definition Port.cc:261
virtual int maxReads() const
virtual bool zeroRegister() const
virtual int guardLatency() const
virtual bool isUsedAsGuard() const
virtual int maxWrites() const
virtual int portCount() const
Definition Unit.cc:135
UnitImplementationLocation IUImplementationLocation
UnitImplementationLocation RFImplementationLocation
UnitImplementationLocation FUImplementationLocation