OpenASIP 2.2
Loading...
Searching...
No Matches
DefaultICDecoderPlugin.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 DefaultICDecoderPlugin.hh
26 *
27 * Declaration and implementation of DefaultICDecoderPlugin class.
28 *
29 * @author Pekka Jääskeläinen 2005 (pekka.jaaskelainen-no.spam-tut.fi)
30 * @author Vinogradov Viacheslav(added Verilog generating) 2012
31 * @note rating: red
32 */
33
34#include <string>
35#include <vector>
36#include <set>
37#include <algorithm>
38#include <utility>
39#include <iterator>
40#include <fstream>
41#include <iostream>
42#include <map>
43#include <math.h>
44
45#include "boost/regex.hpp"
46#include "boost/format.hpp"
47
48#include "HDBManager.hh"
49#include "HDBRegistry.hh"
50#include "Machine.hh"
51#include "MachineInfo.hh"
52#include "Socket.hh"
53#include "Bus.hh"
54#include "Segment.hh"
55#include "ControlUnit.hh"
56#include "Guard.hh"
57#include "FUPort.hh"
58#include "RFPort.hh"
61#include "Program.hh"
62#include "ExecutionTrace.hh"
63
65#include "ProGeTypes.hh"
66#include "NetlistBlock.hh"
67#include "LoopBufferBlock.hh"
68#include "NetlistGenerator.hh"
69#include "Netlist.hh"
70#include "NetlistPort.hh"
71#include "VHDLNetlistWriter.hh"
73#include "CUOpcodeGenerator.hh"
74#include "SignalTypes.hh"
75
77#include "DefaultICGenerator.hh"
78
79#include "BinaryEncoding.hh"
80#include "MoveSlot.hh"
81#include "SourceField.hh"
82#include "DestinationField.hh"
83#include "GuardField.hh"
84#include "ImmediateSlotField.hh"
87#include "GuardEncoding.hh"
88#include "GPRGuardEncoding.hh"
89#include "FUGuardEncoding.hh"
91#include "SocketEncoding.hh"
92#include "RFPortCode.hh"
93#include "IUPortCode.hh"
94#include "FUPortCode.hh"
95#include "SocketCodeTable.hh"
96#include "BlockSourceCopier.hh"
97
98#include "Application.hh"
99#include "MathTools.hh"
100#include "DataObject.hh"
101#include "MapTools.hh"
102#include "Conversion.hh"
103#include "Environment.hh"
105
106#include "CUOpcodeGenerator.hh"
107
108using namespace CostEstimator;
109using std::cerr;
110using std::endl;
111using std::cout;
112
113const std::string RISCV_SIMM_PORT_OUT_NAME = "simm_out";
114const std::string IFETCH_STALL_PORT_NAME = "ifetch_stall";
115
116////////////////////////////////////////////////////////////////////////////
117// DefaultICDecoderEstimator
118////////////////////////////////////////////////////////////////////////////
119
120/**
121 * The default IC&decoder cost estimation plugin.
122 *
123 */
125public:
126
127 /**
128 * Constructor.
129 *
130 * @param name The name of this plugin.
131 * @param dataSource The HDB used to fetch cost estimation data.
132 */
134 const std::string& name) :
136 }
137
138 /**
139 * Destructor.
140 */
142 }
143
144
145 /**
146 * Estimates the delay of an IC path.
147 *
148 * The default implementation estimates the delays by summing up delays of
149 * the subcomponent of the machine part that is registered to be the
150 * 'delay component'. In practice, an entry named
151 * 'delay_subsocket_reference' or 'delay_subbus_reference' is first
152 * fetched from HDB. The entry pointed to by the fetched entry contains
153 * the delay data for the socket/bus at hand.
154 *
155 * @param path Transport path of which delay is estimated.
156 * @param machineImplementation Implementation of the machine.
157 * @param sourceSocketImplementation Not used.
158 * @param busImplementation Not used.
159 * @param destinationSocketImplementation Not used.
160 * @param delay Result delay of the transport path.
161 * @return True if the estimation succeeded.
162 */
164 HDB::HDBRegistry& hdbRegistry,
165 const TransportPath& path,
166 const IDF::MachineImplementation& machineImplementation,
170 DelayInNanoSeconds& delay) {
171//#define DEBUG_DELAY_ESTIMATION
172 try {
173 HDB::HDBManager& hdb =
174 hdbRegistry.hdb(machineImplementation.icDecoderHDB());
175 DelayInNanoSeconds sourceDelay =
176 delayOfSocket(hdb, path.sourceSocket());
177 DelayInNanoSeconds destinationDelay =
178 delayOfSocket(hdb, path.destinationSocket());
179 DelayInNanoSeconds busDelay = delayOfBus(hdb, path.bus());
180 delay = sourceDelay + busDelay + destinationDelay;
181
182#ifdef DEBUG_DELAY_ESTIMATION
183 std::cout
184 << "path: {" << path.sourceSocket().name()
185 << "," << path.bus().name() << ","
186 << path.destinationSocket().name() << "} "
187 << "delays={" << sourceDelay << "," << busDelay << ","
188 << destinationDelay << "} = " << delay << std::endl;
189#endif
190 return true;
191 } catch (const Exception& e) {
193 return false;
194 }
195
196 return false;
197 }
198
199 /**
200 * Estimates the area of an IC path.
201 *
202 * The default implementation estimates the area by summing up areas of
203 * of all subcomponents of sockets and buses in the machine. Subcomponent
204 * data is entered by user to HDB before estimation. The estimation
205 * algorithm does not figure out the subcomponents, it only sums up the c
206 * costs of all subcomponents of a machine part. Subcomponent is a
207 * fanin/fanout combination included in a component. There can be multiple
208 * such combinations due to different widths in inputs and outputs.
209 *
210 * The subcomponent data is fetched from HDB by first fetching all
211 * subcomponent ids of the machine part by looking for entries named
212 * 'subsocket_reference' or 'subbus_reference'. The values of these
213 * entries are identifiers of subsocket entries in the cost table.
214 * Each subsocket entry has a string of name/value pairs as their
215 * value. The cost data is stored in the name/value string. The
216 * cost data string must be in the following format:
217 * 'throughput_delay=53 area=5.2 active_energy=3 idle_energy=3
218 * control_delay=3'
219 */
220 virtual bool estimateICArea(
221 HDB::HDBRegistry& hdbRegistry,
223 const IDF::MachineImplementation& machineImplementation,
224 AreaInGates& area) {
225 area = 0;
226
227//#define DEBUG_AREA_ESTIMATION
228
229 std::string socketName = "";
230 try {
231 /// @todo each socket may have own HDB associated to their
232 /// implementation location object
233 HDB::HDBManager& hdb =
234 hdbRegistry.hdb(machineImplementation.icDecoderHDB());
237 for (int i = 0; i < socketNav.count(); ++i) {
238 const TTAMachine::Socket& socket = *socketNav.item(i);
239 socketName = "";
240 if (socket.direction() == TTAMachine::Socket::INPUT) {
241 socketName = "input_sub_socket";
242 } else if (socket.direction() == TTAMachine::Socket::OUTPUT) {
243 socketName = "output_sub_socket";
244 } else {
245 // Socket direction is unknown
246 // No need to estimate, since it will not be used.
247 continue;
248 }
249
250 FanInFanOutCombinationSet parameterSet =
251 socketParameters(socket);
252 // socket fanin, fanout and data width is added to name string
253 FanInFanOutCombinationSet::const_iterator iter =
254 parameterSet.begin();
255 std::string socketNameCopy = socketName;
256 for (; iter != parameterSet.end(); iter++) {
257 socketName = socketNameCopy + " " +
258 Conversion::toString((*iter).fanIn) + " " +
259 Conversion::toString((*iter).fanOut) + " " +
260 Conversion::toString((*iter).dataWidth);
261 try {
262 DataObject subsocketData =
263 hdb.costEstimationDataValue(socketName, name());
265 "area", subsocketData.stringValue()).doubleValue();
266 } catch (const KeyNotFound& e) {
267 std::set<std::string>::iterator iter =
268 missingComponents_.find("area" + socketName);
269 if (iter == missingComponents_.end()) {
270 std::cerr << "Warning: Could not get area data "
271 << "for '"
272 << socketName << "' from HDB: "
273 << hdb.fileName() << ". Area of this "
274 << "socket not counted to total."
275 << std::endl;
276 missingComponents_.insert("area" + socketName);
277 }
278 }
279 }
280 }
281 } catch (const Exception& e) {
282 HDB::HDBManager& hdb =
283 hdbRegistry.hdb(machineImplementation.icDecoderHDB());
284 debugLog(
285 std::string("Could not get socket area data '") +
286 socketName + "' from HDB: " + hdb.fileName() +
287 e.errorMessage());
288 return false;
289 }
290
291 std::string busName = "";
292 try {
293 /// @todo each bus may have own HDB associated to their
294 /// implementation location object
295 HDB::HDBManager& hdb =
296 hdbRegistry.hdb(machineImplementation.icDecoderHDB());
299 for (int i = 0; i < busNav.count(); ++i) {
300 const TTAMachine::Bus& bus = *busNav.item(i);
301
302 FanInFanOutCombinationSet parameterSet = busParameters(bus);
303 // bus fanin, fanout and data width is added to name string
304 FanInFanOutCombinationSet::const_iterator iter =
305 parameterSet.begin();
306 for (; iter != parameterSet.end(); iter++) {
307 busName = "sub_bus " +
308 Conversion::toString((*iter).fanIn) + " " +
309 Conversion::toString((*iter).fanOut) + " " +
310 Conversion::toString((*iter).dataWidth);
311 try {
312 DataObject subbusData =
313 hdb.costEstimationDataValue(busName, name());
315 "area", subbusData.stringValue()).doubleValue();
316 } catch (const KeyNotFound& e) {
317 std::set<std::string>::iterator iter =
318 missingComponents_.find("area" + busName);
319 if (iter == missingComponents_.end()) {
320 std::cerr << "Warning: Could not get area data "
321 << "for '"
322 << busName << "' from HDB: "
323 << hdb.fileName() << ". Area of this "
324 << "bus not counted to total."
325 << std::endl;
326 missingComponents_.insert("area" + busName);
327 }
328 }
329 }
330 }
331 } catch (const Exception& e) {
332 HDB::HDBManager& hdb =
333 hdbRegistry.hdb(machineImplementation.icDecoderHDB());
334 debugLog(
335 std::string("Could not get bus area data '") +
336 busName + "' from HDB. " + hdb.fileName() +
337 e.errorMessage());
338 return false;
339 }
340
341 return true;
342 }
343
344 /**
345 * Estimates the energy consumed by IC.
346 *
347 * The default implementation estimates the area by summing up energies of
348 * of all subcomponents of sockets and buses. For more information, see
349 * the comment of the area estimation function.
350 */
351 virtual bool estimateICEnergy(
352 HDB::HDBRegistry& hdbRegistry,
354 const IDF::MachineImplementation& machineImplementation,
355 const TTAProgram::Program& /*program*/,
356 const ExecutionTrace& traceDB,
357 EnergyInMilliJoules& energy) {
358
359//#define DEBUG_ENERGY_ESTIMATION
360
361 energy = 0.0;
362
363 ClockCycleCount totalCycles = traceDB.simulatedCycleCount();
364
365 std::string socketName = "";
366 try {
367 HDB::HDBManager& hdb =
368 hdbRegistry.hdb(machineImplementation.icDecoderHDB());
371 for (int i = 0; i < socketNav.count(); ++i) {
372 const TTAMachine::Socket& socket = *socketNav.item(i);
373 socketName = "";
374 if (socket.direction() == TTAMachine::Socket::INPUT) {
375 socketName = "input_sub_socket";
376 } else if (socket.direction() == TTAMachine::Socket::OUTPUT) {
377 socketName = "output_sub_socket";
378 } else {
379 // Socket direction is unknown
380 // No need to estimate, since it will not be used.
381 continue;
382 }
383
384 FanInFanOutCombinationSet parameterSet =
385 socketParameters(socket);
386 // socket fanin, fanout and data width is added to name string
387 FanInFanOutCombinationSet::const_iterator iter =
388 parameterSet.begin();
389 std::string socketNameCopy = socketName;
390 for (; iter != parameterSet.end(); iter++) {
391 socketName = socketNameCopy + " " +
392 Conversion::toString((*iter).fanIn) + " " +
393 Conversion::toString((*iter).fanOut) + " " +
394 Conversion::toString((*iter).dataWidth);
395 DataObject subsocketData =
396 hdb.costEstimationDataValue(socketName, name());
397
398 // sum the active and idle energies of all subsockets
399 // multiplied with write and idle clock counts,
400 // respectively
401 EnergyInMilliJoules idleEnergy =
403 "idle_energy", subsocketData.stringValue()).
404 doubleValue();
405 EnergyInMilliJoules activeEnergy =
407 "active_energy", subsocketData.stringValue()).
408 doubleValue();
409
410 ClockCycleCount activeCycles =
411 traceDB.socketWriteCount(socket.name());
412
413 EnergyInMilliJoules totalActiveEnergy =
414 activeEnergy*activeCycles;
415
416 ClockCycleCount idleCycles = totalCycles - activeCycles;
417
418 EnergyInMilliJoules totalIdleEnergy =
419 idleEnergy*idleCycles;
420
421 EnergyInMilliJoules totalEnergy =
422 totalIdleEnergy + totalActiveEnergy;
423 energy += totalEnergy;
424#ifdef DEBUG_ENERGY_ESTIMATION
425 std::cout
426 << "socket " << socket.name() << ", subsocket "
427 << socketName << ": "
428 << "active energy = " << activeEnergy
429 << " mJ/cycle * " << activeCycles << " cycle = "
430 << totalActiveEnergy << ", "
431 << "idle energy = " << idleEnergy
432 << " mJ/cycle * " << idleCycles << " cycle = "
433 << totalIdleEnergy << " TOTAL = " << totalEnergy
434 << std::endl;
435#endif
436 }
437 }
438 } catch (const Exception& e) {
439 debugLog(
440 std::string("Could not get socket area data '") +
441 socketName + "' from HDB. " + e.errorMessage());
442 return false;
443 }
444 std::string busName = "";
445 try {
446 HDB::HDBManager& hdb =
447 hdbRegistry.hdb(machineImplementation.icDecoderHDB());
449 for (int i = 0; i < busNav.count(); ++i) {
450 const TTAMachine::Bus& bus = *busNav.item(i);
451
452 FanInFanOutCombinationSet parameterSet = busParameters(bus);
453 // bus fanin, fanout and data width is added to name string
454 FanInFanOutCombinationSet::const_iterator iter =
455 parameterSet.begin();
456 for (; iter != parameterSet.end(); iter++) {
457 busName = "sub_bus " +
458 Conversion::toString((*iter).fanIn) + " " +
459 Conversion::toString((*iter).fanOut) + " " +
460 Conversion::toString((*iter).dataWidth);
461 DataObject subbusData =
462 hdb.costEstimationDataValue(busName, name());
463
464 // sum the active and idle energies of all subbuses
465 // multiplied with write and idle clock counts,
466 // respectively
467 EnergyInMilliJoules idleEnergy =
469 "idle_energy", subbusData.stringValue()).
470 doubleValue();
471 EnergyInMilliJoules activeEnergy =
473 "active_energy", subbusData.stringValue()).
474 doubleValue();
475
476 ClockCycleCount activeCycles =
477 traceDB.busWriteCount(bus.name());
478
479 EnergyInMilliJoules totalActiveEnergy =
480 activeEnergy*activeCycles;
481
482 ClockCycleCount idleCycles = totalCycles - activeCycles;
483
484 EnergyInMilliJoules totalIdleEnergy =
485 idleEnergy*idleCycles;
486
487 EnergyInMilliJoules totalEnergy =
488 totalIdleEnergy + totalActiveEnergy;
489 energy += totalEnergy;
490#ifdef DEBUG_ENERGY_ESTIMATION
491 std::cout
492 << "bus " << bus.name() << ", subbus "
493 << busName << ": "
494 << "active energy = " << activeEnergy
495 << " mJ/cycle * " << activeCycles << " cycle = "
496 << totalActiveEnergy << ", "
497 << "idle energy = " << idleEnergy
498 << " mJ/cycle * " << idleCycles << " cycle = "
499 << totalIdleEnergy << " TOTAL = " << totalEnergy
500 << std::endl;
501#endif
502 }
503 }
504 } catch (const Exception& e) {
505 debugLog(
506 std::string("Could not get bus energy data '") + busName +
507 "' from HDB. " + e.errorMessage());
508 return false;
509 }
510 return true;
511 }
512
513private:
514
515 /// Set for component names that are missing from HDB.
516 std::set<std::string> missingComponents_;
517
518 /**
519 * Finds out the delay of the given socket.
520 */
523 DelayInNanoSeconds delay = 0;
524 std::string socketName = "";
525 try {
526 if (socket.direction() == TTAMachine::Socket::INPUT) {
527 socketName = "input_sub_socket";
528 } else if (socket.direction() == TTAMachine::Socket::OUTPUT) {
529 socketName = "output_sub_socket";
530 } else {
531 // Socket direction is unknown, should never be
532 assert(false);
533 }
534
535 FanInFanOutCombinationSet parameterSet =
536 socketParameters(socket);
537 // socket fanin, fanout and data width is added to name string
538 FanInFanOutCombinationSet::const_iterator iter =
539 parameterSet.begin();
540 std::string socketNameCopy = socketName;
541 for (; iter != parameterSet.end(); iter++) {
542 socketName = socketNameCopy + " " +
543 Conversion::toString((*iter).fanIn) + " " +
544 Conversion::toString((*iter).fanOut) + " " +
545 Conversion::toString((*iter).dataWidth);
546 if (socket.direction() == TTAMachine::Socket::INPUT &&
547 (*iter).fanIn == 1 && (*iter).fanOut == 1) {
548 // input socket 1 1 * --> no delay
549 return 0;
550 }
551 try {
552 DataObject subsocketData =
553 hdb.costEstimationDataValue(socketName, name());
555 "throughput_delay",
556 subsocketData.stringValue()).doubleValue();
557 } catch (const KeyNotFound& e) {
558 std::set<std::string>::iterator iter =
559 missingComponents_.find("tdelay" + socketName);
560 if (iter == missingComponents_.end()) {
561 std::cerr << "Warning: Could not get throughput delay "
562 << "data for '"
563 << socketName << "' from HDB: "
564 << hdb.fileName() << ". This value is "
565 << "not counted to total." << std::endl;
566 missingComponents_.insert("tdelay" + socketName);
567 }
568 }
569 }
570 } catch (const Exception& e) {
571 throw Exception(
572 __FILE__, __LINE__, __func__,
573 std::string("Cannot fetch socket delay data '") +
574 socketName + "'." + e.errorMessage());
575 }
576 return delay;
577 }
578
579 /**
580 * Finds out the delay of the given bus.
581 */
584 DelayInNanoSeconds delay = 0;
585 std::string busName = "";
586 try {
587 FanInFanOutCombinationSet parameterSet = busParameters(bus);
588 // bus fanin, fanout and data width is added to name string
589 FanInFanOutCombinationSet::const_iterator iter =
590 parameterSet.begin();
591 for (; iter != parameterSet.end(); iter++) {
592 busName = "sub_bus " +
593 Conversion::toString((*iter).fanIn) + " " +
594 Conversion::toString((*iter).fanOut) + " " +
595 Conversion::toString((*iter).dataWidth);
596
597 try {
598 DataObject subbusData =
599 hdb.costEstimationDataValue(busName, name());
600
602 "throughput_delay",
603 subbusData.stringValue()).doubleValue();
604 } catch (const KeyNotFound& e) {
605 std::set<std::string>::iterator iter =
606 missingComponents_.find("tdelay" + busName);
607 if (iter == missingComponents_.end()) {
608 std::cerr << "Warning: Could not get throughput delay "
609 << "data for '"
610 << busName << "' from HDB: "
611 << hdb.fileName() << ". This value is "
612 << "not counted to total." << std::endl;
613 missingComponents_.insert("tdelay" + busName);
614 }
615 }
616 }
617 } catch (const Exception& e) {
618 throw Exception(
619 __FILE__, __LINE__, __func__,
620 std::string("Cannot fetch bus delay data '") +
621 busName + "'." + e.errorMessage());
622 }
623 return delay;
624 }
625
626 /**
627 * Finds out the delay of the given socket.
628 *
629 * Not used with current implementation.
630 */
633 HDB::HDBRegistry& hdbRegistry,
635 // First fetch the id of the 'delay_subsocket_reference' of the
636 // socket. The id is used to fetch the subsocket data which carries
637 // the delay data.
638 int implementationId = implementation.id();
639
640 HDB::HDBManager& hdb = hdbRegistry.hdb(implementation.hdbFile());
641
642 std::string entry = "delay_subsocket_reference";
643
644 try {
645 DataObject subsocketReference =
646 hdb.socketCostEstimationData(entry, implementationId, name_);
647
648 int entryId = subsocketReference.integerValue();
649
650 entry = std::string("id=") + Conversion::toString(entryId);
651 DataObject subsocketData = hdb.costEstimationDataValue(entryId);
653 "throughput_delay", subsocketData.stringValue()).doubleValue();
654 } catch (const Exception& e) {
655 throw Exception(
656 __FILE__, __LINE__, __func__,
657 std::string("Cannot fetch socket delay data '") +
658 entry + "'." + e.errorMessage());
659 }
660 }
661
662 /**
663 * Finds out the delay of the given bus.
664 */
667 HDB::HDBRegistry& hdbRegistry,
669 // First fetch the id of the 'delay_subbus_reference' of the
670 // socket. The id is used to fetch the subbus data which carries
671 // the delay data.
672 int implementationId = implementation.id();
673
674 HDB::HDBManager& hdb = hdbRegistry.hdb(implementation.hdbFile());
675
676 try {
677 return hdb.busCostEstimationData(
678 "throughput_delay", implementationId, name_).doubleValue();
679
680 } catch (const Exception& e) {
681 throw Exception(
682 __FILE__, __LINE__, __func__,
683 std::string("Cannot fetch bus delay data. ") +
684 e.errorMessage());
685 }
686 }
687
688 /**
689 * Parses a string of key-value pairs and returns a value with given key.
690 *
691 * The string must be in format "key1=value1 key2=value2" etc.
692 * the value must not have spaces in it.
693 *
694 * @param keyName The key of the value to fetch from the string.
695 * @param keyValuePairString The key-value pair string to parse.
696 * @return The value.
697 * @exception KeyNotFound In case the key was not found in the string.
698 *
699 */
702 const std::string& keyName, const std::string& keyValuePairString) {
703 boost::smatch parsed;
704 boost::regex regexp(
705 (boost::format("(.*)(%s)=([^\\s]*)(.*)") % keyName).str());
706 if (!regex_match(keyValuePairString, parsed, regexp)) {
707 throw KeyNotFound(
708 __FILE__, __LINE__, __func__,
709 "Key not found in value string.");
710 } else {
711 if (parsed.size() < 3)
712 throw KeyNotFound(__FILE__, __LINE__, __func__);
713 DataObject data;
714 data.setString(parsed[3]);
715 return data;
716 }
717 }
718
720 std::size_t fanIn;
721 std::size_t fanOut;
722 std::size_t dataWidth;
723 };
724
725 typedef std::vector<ICParameters> FanInFanOutCombinationSet;
726
727 /**
728 * Generates all possible fanin/fanout/data width combinations
729 * (subcomponents) for given input and output widths.
730 *
731 * @param inputWidths Set containing component's input widths.
732 * @param outputWidths Set containing component's output widths.
733 * @return Set of fanin/fanout/data width combinations.
734 */
737 std::vector<std::size_t>& inputWidths,
738 std::vector<std::size_t>& outputWidths) {
739
740 std::sort(inputWidths.begin(), inputWidths.end());
741 std::sort(outputWidths.begin(), outputWidths.end());
742
743 std::set<std::size_t> allWidthsTemp;
744 std::copy(
745 inputWidths.begin(), inputWidths.end(),
746 std::insert_iterator<std::set<std::size_t> >(
747 allWidthsTemp, allWidthsTemp.begin()));
748 std::copy(
749 outputWidths.begin(), outputWidths.end(),
750 std::insert_iterator<std::set<std::size_t> >(
751 allWidthsTemp, allWidthsTemp.begin()));
752 std::vector<std::size_t> allWidths;
753 std::copy(
754 allWidthsTemp.begin(), allWidthsTemp.end(),
755 std::insert_iterator<std::vector<std::size_t> >(
756 allWidths, allWidths.begin()));
757
758
759 FanInFanOutCombinationSet combinations;
760 for (std::vector<std::size_t>::iterator i = allWidths.begin();
761 i != allWidths.end(); ++i) {
762
763 const unsigned int width = *i;
764
765 // how many input widths fits in the current width?
766 std::size_t fanIn = 0;
767 for (unsigned int n = 0; n < inputWidths.size(); n++) {
768 // we can do a trick like this because the vector is ordered
769 if (width > inputWidths.at(n) && inputWidths.at(n) > 0)
770 break;
771 if (inputWidths.at(n) != 0) {
772 fanIn++;
773 }
774 }
775
776 // how many output widths fits in the current width?
777 std::size_t fanOut = 0;
778 for (unsigned int n = 0; n < outputWidths.size(); n++) {
779 // we can do a trick like this because the vector is ordered
780 if (width > outputWidths.at(n) && outputWidths.at(n) > 0)
781 break;
782 if (outputWidths.at(n) != 0) {
783 fanOut++;
784 }
785 }
786
787 if (fanIn == 0 || fanOut == 0)
788 return combinations; //continue;
789 ICParameters parameters;
790 parameters.fanIn = fanIn;
791 parameters.fanOut = fanOut;
792 parameters.dataWidth = width;
793 combinations.push_back(parameters);
794
795 for (unsigned int n = 0; n < inputWidths.size(); n++) {
796 if (inputWidths.at(n) > width) {
797 inputWidths.at(n) = inputWidths.at(n) - width;
798 } else {
799 inputWidths.at(n) = 0;
800 }
801 }
802 for (unsigned int n = 0; n < outputWidths.size(); n++) {
803 if (outputWidths.at(n) > width) {
804 outputWidths.at(n) = outputWidths.at(n) - width;
805 } else {
806 outputWidths.at(n) = 0;
807 }
808 }
809
810 for (unsigned int n = 0; n < allWidths.size(); n++) {
811 if (allWidths.at(n) > width) {
812 allWidths.at(n) = allWidths.at(n) - width;
813 } else {
814 allWidths.at(n) = 0;
815 }
816 }
817
818 }
819
820 return combinations;
821 }
822
823
824 /**
825 * Generates fanin/fanout/width combinations to a socket.
826 *
827 * @param socket Socket which parameters are generated.
828 * @return Set of fanin/fanout/width combinations.
829 */
832 const TTAMachine::Socket& socket) {
833
834 std::vector<std::size_t> inputWidths;
835 std::vector<std::size_t> outputWidths;
836
837 if (socket.direction() == TTAMachine::Socket::INPUT) {
838 for (int i = 0; i < socket.segmentCount(); i++) {
839 inputWidths.push_back(socket.segment(i)->parentBus()->width());
840 }
841 for (int i = 0; i < socket.portCount(); i++) {
842 outputWidths.push_back(socket.port(i)->width());
843 }
844 } else if (socket.direction() == TTAMachine::Socket::OUTPUT) {
845 for (int i = 0; i < socket.segmentCount(); i++) {
846 outputWidths.push_back(socket.segment(i)->parentBus()->width());
847 }
848 for (int i = 0; i < socket.portCount(); i++) {
849 inputWidths.push_back(socket.port(i)->width());
850 }
851 }
852 return generateFanInFanOutCombinations(inputWidths, outputWidths);
853 }
854
855 /**
856 * Generates fanin/fanout/width combinations to a bus.
857 *
858 * @param bus Bus which parameters are generated.
859 * @return Set of fanin/fanout/width combinations.
860 */
863 const TTAMachine::Bus& bus) {
864
865 std::vector<std::size_t> inputWidths;
866 std::vector<std::size_t> outputWidths;
867
869 bus.machine()->socketNavigator();
870 for (int i = 0; i < socketNav.count(); ++i) {
871 const TTAMachine::Socket& socket = *socketNav.item(i);
872 if (bus.isConnectedTo(socket)) {
873 std::size_t width = 0;
874 for (int port = 0; port < socket.portCount(); port++) {
875 if (static_cast<unsigned int>(
876 socket.port(port)->width()) > width) {
877 width = socket.port(port)->width();
878 }
879 }
880 if (width == 0) {
881 continue;
882 }
883 if (socket.direction() == TTAMachine::Socket::OUTPUT) {
884 inputWidths.push_back(width);
885 } else {
886 outputWidths.push_back(width);
887 }
888 }
889 }
890
891 return generateFanInFanOutCombinations(inputWidths, outputWidths);
892 }
893};
894////////////////////////////////////////////////////////////////////////////
895// DefaultICDecoderGenerator
896////////////////////////////////////////////////////////////////////////////
897
898using namespace TTAMachine;
899using namespace ProGe;
900using std::string;
901using std::endl;
902
903const std::string ENABLE_FEATURE = "yes";
904const std::string GENERATE_DEBUGGER_PARAM = "debugger";
906const std::string GENERATE_DEBUGGER_PARAM_INTERNAL = "internal";
907const std::string GENERATE_DEBUGGER_PARAM_EXTERNAL = "external";
908const std::string GENERATE_DEBUGGER_PARAM_MINIMAL = "minimal";
909const std::string GENERATE_BUS_TRACE_PARAM = "bustrace";
911const std::string GENERATE_LOCK_TRACE_PARAM = "locktrace";
913const std::string BYPASS_FETCHBLOCK_REG_PARAM = "bypassinstructionregister";
915const std::string LOCK_TRACE_STARTING_CYCLE = "locktracestartingcycle";
916const std::string BUS_TRACE_STARTING_CYCLE = "bustracestartingcycle";
917const std::string PLUGIN_DESCRIPTION =
918 "Generates the IC as as an AND-OR network.";
919const std::string NO_SELF_LOCKING_PARAM = "no-self-locking";
921const std::string SYNC_RESET = "synchronous-reset";
922
923#include <iostream>
924#include <cmath>
925using namespace std;
926/**
927 * Default implementation for IC/decoder generator.
928 */
930public:
934 dbsmBlock(NULL),
935 icGenerator_(NULL),
936 decoderGenerator_(NULL),
938 bem_(bem) {
941 "Generates wires to the internal hardware debugger if "
942 "the value is '" + GENERATE_DEBUGGER_PARAM_INTERNAL
943 + "', and to the external debugger if the value is '"
944 + GENERATE_DEBUGGER_PARAM_EXTERNAL + "'. A minimal set of wires, "
945 "for softreset and break, are added if the value is '"
949 "Generates code that prints bus trace if the value is '" +
950 ENABLE_FEATURE + "'.");
953 "The first cycle for which the bus trace is printed.");
956 "Generates code that prints global lock trace if the value is"
957 " '" +
958 ENABLE_FEATURE + "'.");
961 "The first cycle for which the global lock trace is printed. "
962 "If value is \"" + BUS_TRACE_STARTING_CYCLE + "\" then the "
963 "value is inherited from " + BUS_TRACE_STARTING_CYCLE + ".");
966 "-1 delay slot by removing instruction fetch register. "
967 "'" +
968 ENABLE_FEATURE + "' to enable the feature.");
969
973 }
974
976 delete icGenerator_;
977 delete decoderGenerator_;
978 }
979
980 /**
981 * Completes the given netlist by adding IC block and completing the
982 * decoder block by adding the ports connected to IC. Connects also IC to
983 * all the units in the machine.
984 *
985 * @param The netlist to complete.
986 * @param generator The netlist generator which generated the netlist.
987 */
988 virtual void
990 NetlistBlock& netlistBlock, const NetlistGenerator& generator) {
991 // add interconnection network to the netlist and connect it to the
992 // units
993 icGenerator_->addICToNetlist(generator, netlistBlock);
994
995 // complete the decoder block and connect it to the IC and units
996 decoderGenerator_->completeDecoderBlock(generator, netlistBlock);
997
999 addRV32MicroCode(netlistBlock, generator);
1000 }
1001 }
1002
1003 void
1005 NetlistBlock& netlistBlock, const NetlistGenerator& generator) {
1006 NetlistBlock& decompressor = generator.instructionDecompressor();
1007 NetlistBlock& decoder = generator.instructionDecoder();
1008 NetlistBlock& ifetch = generator.instructionFetch();
1009 Netlist& netlist = netlistBlock.netlist();
1010
1011 // Change port width to 32 to match socket width
1012 ifetch.port("pc_in")->setWidthFormula("32");
1013
1014 NetlistBlock* microCodeBlock = new NetlistBlock(
1015 "rv32_microcode_wrapper", "rv32_microcode_wrapper_i");
1016
1017 // Adds the block to the netlist
1018 netlistBlock.addSubBlock(microCodeBlock);
1019
1020 NetlistPort* decoderRISCVSimmPort = new NetlistPort(
1022 ProGe::BIT_VECTOR, ProGe::IN, decoder);
1023
1024 NetlistPort* clk = new NetlistPort(
1025 "clk", "1", ProGe::BIT, ProGe::IN, *microCodeBlock);
1026
1027 NetlistPort* rst = new NetlistPort(
1028 "rstx", "1", ProGe::BIT, ProGe::IN, *microCodeBlock);
1029
1030 NetlistPort* glock = new NetlistPort(
1031 "glock_in", "1", ProGe::BIT, ProGe::IN, *microCodeBlock);
1032
1033 netlist.connect(
1035
1036 netlist.connect(*clk, generator.clkPort(netlistBlock));
1037
1038 netlist.connect(*rst, generator.rstPort(netlistBlock));
1039
1040 NetlistPort* instructionOut = new NetlistPort(
1041 "instruction_out", "INSTRUCTIONWIDTH", BIT_VECTOR, ProGe::OUT,
1042 *microCodeBlock);
1043
1044 NetlistPort* microCodeImmOut = new NetlistPort(
1046 *microCodeBlock);
1047
1048 NetlistPort* instructionIn = new NetlistPort(
1049 "instruction_in", "IMEMWIDTHINMAUS*IMEMMAUWIDTH", BIT_VECTOR,
1050 ProGe::IN, *microCodeBlock);
1051
1052 netlist.connect(*microCodeImmOut, *decoderRISCVSimmPort);
1053
1054 netlist.disconnectPorts(
1057
1058 netlist.connect(
1059 *instructionOut,
1061
1062 netlist.connect(
1064 *instructionIn);
1065
1067 ->setWidthFormula("INSTRUCTIONWIDTH");
1068
1069 NetlistPort* ifetchStallPortIFetch = new NetlistPort(
1071
1072 NetlistPort* ifetchStallPortMicroCode = new NetlistPort(
1074 *microCodeBlock);
1075
1076 NetlistPort* rvJumpPortMicroCode = new NetlistPort(
1077 "rv_jump", "1", ProGe::BIT, ProGe::OUT, *microCodeBlock);
1078
1079 NetlistPort* rvAuipcPortMicroCode = new NetlistPort(
1080 "rv_auipc", "1", ProGe::BIT, ProGe::OUT, *microCodeBlock);
1081
1082 NetlistPort* rvOffsetPortMicroCode = new NetlistPort(
1083 "rv_offset", "32", BIT_VECTOR, ProGe::OUT, *microCodeBlock);
1084
1085 NetlistPort* rvOffsetPortIfetch =
1086 new NetlistPort("rv_offset", "32", BIT_VECTOR, ProGe::IN, ifetch);
1087
1088 NetlistPort* rvJumpPortIfetch =
1089 new NetlistPort("rv_jump", "1", ProGe::BIT, ProGe::IN, ifetch);
1090
1091 NetlistPort* rvAuipcPortIfetch =
1092 new NetlistPort("rv_auipc", "1", ProGe::BIT, ProGe::IN, ifetch);
1093
1094 netlist.connect(*rvJumpPortMicroCode, *rvJumpPortIfetch);
1095 netlist.connect(*rvAuipcPortMicroCode, *rvAuipcPortIfetch);
1096 netlist.connect(*rvOffsetPortMicroCode, *rvOffsetPortIfetch);
1097
1098 netlist.connect(*ifetchStallPortMicroCode, *ifetchStallPortIFetch);
1099 }
1100
1102 assert(
1103 generateDebugger() &&
1104 "Entered debugger connection generation without cause.");
1105
1106 NetlistBlock* decoderBlock = &generator.instructionDecoder();
1107 NetlistBlock& toplevelBlock = decoderBlock->parentBlock();
1108 std::string addrWidthFormula = generator.gcuReturnAddressInPort()
1109 .widthFormula();
1110 NetlistBlock* fetchBlock = &generator.instructionFetch();
1111 NetlistBlock* icBlock = NULL;
1112
1113 bool is_external = false, is_internal = false, is_minimal = false;
1114
1117 is_external = true;
1120 is_minimal = true;
1121 } else {
1122 is_internal = true;
1123 }
1124
1125 for (std::size_t i = 0; i < toplevelBlock.subBlockCount(); i++) {
1126 icBlock = &toplevelBlock.subBlock(i);
1127 if (icBlock->instanceName() == "ic")
1128 break;
1129 if (icBlock->moduleName() == "ic")
1130 break;
1131 }
1132
1133 if (is_internal) {
1134 //Include debugger package with width constants in tta0.vhdl
1135 toplevelBlock.addPackage("debugger_if");
1136 }
1137
1138 NetlistPort* ttaResetPort = new NetlistPort(
1139 "db_tta_nreset", "1", BIT, ProGe::IN, toplevelBlock);
1140 NetlistPort *ttaLockcountPort = new NetlistPort("db_lockcnt",
1141 "64", ProGe::BIT_VECTOR, ProGe::OUT, toplevelBlock);
1142 NetlistPort *ttaCyclecountPort = new NetlistPort("db_cyclecnt",
1143 "64", ProGe::BIT_VECTOR, ProGe::OUT, toplevelBlock);
1144
1145 NetlistPort *ttaPCPort = new NetlistPort("db_pc",
1146 "IMEMADDRWIDTH", ProGe::BIT_VECTOR, ProGe::OUT, toplevelBlock);
1147
1148 if (is_minimal || is_external) {
1149
1150 NetlistPort* dbGlockReqPort = new NetlistPort(
1151 "db_lockrq", "1", BIT, ProGe::IN, toplevelBlock);
1152
1153 // Connect to the highest bit of decoder lockrq vector, others are
1154 // already connected
1155 NetlistPort* decoderGlockReqPort =
1156 decoderBlock->port("lock_req");
1157 int bit = decoderGenerator_->glockRequestWidth()-1;
1158 toplevelBlock.netlist().connect(
1159 *dbGlockReqPort, *decoderGlockReqPort, 0, bit, 1);
1160
1161 // Connect ifetch debug ports
1162 NetlistPort* ifetchDebugResetPort = new NetlistPort(
1163 "db_rstx", "1", 1, ProGe::BIT, ProGe::IN, *fetchBlock);
1164 toplevelBlock.netlist().connect(*ttaResetPort,
1165 *ifetchDebugResetPort);
1166
1167 NetlistPort* ifetchDebugLockRqPort = new NetlistPort(
1168 "db_lockreq", "1", 1, ProGe::BIT, ProGe::IN, *fetchBlock);
1169 toplevelBlock.netlist().connect(*dbGlockReqPort,
1170 *ifetchDebugLockRqPort);
1171
1172 NetlistPort* ifetchCyclecountPort = new NetlistPort(
1173 "db_cyclecnt", "64", 64, ProGe::BIT_VECTOR, ProGe::OUT,
1174 *fetchBlock);
1175 toplevelBlock.netlist().connect(
1176 *ifetchCyclecountPort, *ttaCyclecountPort);
1177 NetlistPort* ifetchLockcountPort = new NetlistPort(
1178 "db_lockcnt", "64", 64, ProGe::BIT_VECTOR, ProGe::OUT,
1179 *fetchBlock);
1180 toplevelBlock.netlist().connect(
1181 *ifetchLockcountPort, *ttaLockcountPort);
1182
1183 NetlistPort* ifetchPCPort = new NetlistPort(
1184 "db_pc", "IMEMADDRWIDTH", ProGe::BIT_VECTOR, ProGe::OUT,
1185 *fetchBlock);
1186 toplevelBlock.netlist().connect(*ifetchPCPort, *ttaPCPort);
1187 }
1188 if (!is_minimal) {
1189 //Add debugger interface ports to tta0 entity
1190 NetlistPort *ttaPCStartPort = new NetlistPort("db_pc_start",
1191 "IMEMADDRWIDTH", ProGe::BIT_VECTOR, ProGe::IN, toplevelBlock);
1192 NetlistPort *ttaBustracePort = new NetlistPort("db_bustraces",
1193 "BUSTRACE_WIDTH", ProGe::BIT_VECTOR, ProGe::OUT, toplevelBlock);
1194
1195 // Connect bustraces out and away
1196 NetlistPort* icBustracePort = icBlock->port("db_bustraces");
1197 assert(icBustracePort);
1198 toplevelBlock.netlist().connect(
1199 *icBustracePort, *ttaBustracePort);
1200
1201 if (is_external) {
1202 NetlistPort* dbPCNextPort = new NetlistPort(
1203 "db_pc_next", "IMEMADDRWIDTH",
1204 ProGe::BIT_VECTOR, ProGe::OUT, toplevelBlock);
1205
1206 NetlistPort* ifetchPCStartPort = new NetlistPort(
1207 "db_pc_start", "IMEMADDRWIDTH", ProGe::BIT_VECTOR,
1208 ProGe::IN, *fetchBlock);
1209 toplevelBlock.netlist().connect(*ifetchPCStartPort,
1210 *ttaPCStartPort);
1211 NetlistPort* ifetchPCNextPort = new NetlistPort(
1212 "db_pc_next", "IMEMADDRWIDTH", ProGe::BIT_VECTOR,
1213 ProGe::OUT, *fetchBlock);
1214 toplevelBlock.netlist().connect(*ifetchPCNextPort,
1215 *dbPCNextPort);
1216
1217 } else if (is_internal) { // Generate internal debugger
1218 NetlistPort* ttaBpEnaPort = new NetlistPort(
1219 "db_bp_ena", "1+db_breakpoints",
1220 ProGe::BIT_VECTOR, ProGe::IN, toplevelBlock);
1221 NetlistPort* ttaBp0Port = new NetlistPort(
1222 "bp_target_cc", "db_breakpoints_cc*db_data_width",
1223 ProGe::BIT_VECTOR, ProGe::IN, toplevelBlock);
1224 NetlistPort* ttaBp41Port = new NetlistPort(
1225 "bp_target_pc", "db_breakpoints_pc*IMEMADDRWIDTH",
1227 toplevelBlock);
1228 NetlistPort* ttaBpHitPort = new NetlistPort(
1229 "db_bp_hit", "2+db_breakpoints",
1230 ProGe::BIT_VECTOR, ProGe::OUT, toplevelBlock);
1231 NetlistPort* ttaContinuePort = new NetlistPort(
1232 "db_tta_continue", "1", BIT, ProGe::IN, toplevelBlock);
1233 NetlistPort* ttaForceBreakPort = new NetlistPort(
1234 "db_tta_forcebreak", "1", BIT, ProGe::IN, toplevelBlock);
1235 NetlistPort* ttaStdoutBreakPort = new NetlistPort(
1236 "db_tta_stdoutbreak", "1", BIT, ProGe::IN, toplevelBlock);
1237
1238 //Build and connect the debugger state machine block in tta0.vhdl
1239 dbsmBlock = new NetlistBlock("dbsm", "dbsm_1");
1240 toplevelBlock.addSubBlock(dbsmBlock);
1241
1242 dbsmBlock->setParameter("cyclecnt_width_g", "integer",
1243 "db_data_width");
1244 dbsmBlock->setParameter("pc_width_g", "integer",
1245 "IMEMADDRWIDTH");
1246
1247 NetlistPort* dbsmClkPort = new NetlistPort(
1248 "clk", "1", BIT, ProGe::IN, *dbsmBlock);
1249 toplevelBlock.netlist().connect(
1250 *dbsmClkPort, generator.clkPort(toplevelBlock));
1251
1252 NetlistPort* dbsmNresetPort = new NetlistPort(
1253 "nreset", "1", BIT, ProGe::IN, *dbsmBlock);
1254 toplevelBlock.netlist().connect(
1255 *dbsmNresetPort, generator.rstPort(toplevelBlock));
1256
1257 NetlistPort* dbsmBpEnaPort = new NetlistPort(
1258 "bp_ena", "1+db_breakpoints",
1260 toplevelBlock.netlist().connect(*ttaBpEnaPort, *dbsmBpEnaPort);
1261
1262 NetlistPort* dbsmBp0Port = new NetlistPort(
1263 "bp_target_cc", "db_breakpoints_cc*cyclecnt_width_g",
1266 toplevelBlock.netlist().connect(*ttaBp0Port, *dbsmBp0Port);
1267
1268 NetlistPort* dbsmCyclecountPort = new NetlistPort(
1269 "cyclecnt", "cyclecnt_width_g", ProGe::BIT_VECTOR,
1271
1272 NetlistPort* dbsmBp41Port = new NetlistPort(
1273 "bp_target_pc", "db_breakpoints_pc*IMEMADDRWIDTH",
1275 toplevelBlock.netlist().connect(*ttaBp41Port, *dbsmBp41Port);
1276
1277 NetlistPort* dbsmPCNextPort = new NetlistPort(
1278 "pc_next", "IMEMADDRWIDTH", ProGe::BIT_VECTOR,
1280
1281 NetlistPort* dbsmContinuePort = new NetlistPort(
1282 "tta_continue", "1", BIT, ProGe::IN, *dbsmBlock);
1283 toplevelBlock.netlist().connect(
1284 *ttaContinuePort, *dbsmContinuePort);
1285
1286 NetlistPort* dbsmForceBreakPort = new NetlistPort(
1287 "tta_forcebreak", "1", BIT, ProGe::IN, *dbsmBlock);
1288 toplevelBlock.netlist().connect(*ttaForceBreakPort,
1289 *dbsmForceBreakPort);
1290
1291 NetlistPort* dbsmStdoutBreakPort = new NetlistPort(
1292 "tta_stdoutbreak", "1", BIT, ProGe::IN, *dbsmBlock);
1293 toplevelBlock.netlist().connect(
1294 *ttaStdoutBreakPort, *dbsmStdoutBreakPort);
1295
1296 NetlistPort* dbsmBpHitPort = new NetlistPort(
1297 "bp_hit", "2+db_breakpoints",
1299 toplevelBlock.netlist().connect(*ttaBpHitPort, *dbsmBpHitPort);
1300
1301 NetlistPort* dbsmExtlockPort = new NetlistPort(
1302 "extlock", "1", BIT, ProGe::IN, *dbsmBlock);
1303 toplevelBlock.netlist().connect(
1304 *toplevelBlock.port("busy"), *dbsmExtlockPort);
1305
1306
1307 // Connect to the highest bit of decoder lockrq vector, others are
1308 // already connected
1309 NetlistPort* dbsmGlockReqPort = new NetlistPort(
1310 "bp_lockrq", "1", BIT, ProGe::OUT, *dbsmBlock);
1311 NetlistPort* decoderGlockReqPort =
1312 decoderBlock->port("lock_req");
1313 int bit = decoderGenerator_->glockRequestWidth()-1;
1314 toplevelBlock.netlist().connect(
1315 *dbsmGlockReqPort, *decoderGlockReqPort, 0, bit, 1);
1316
1317 // Connect ifetch debug ports
1318 NetlistPort* ifetchDebugLockRqPort = new NetlistPort(
1319 "db_lockreq", "1", 1, ProGe::BIT, ProGe::IN, *fetchBlock);
1320 toplevelBlock.netlist().connect(*dbsmGlockReqPort,
1321 *ifetchDebugLockRqPort);
1322 NetlistPort* ifetchDebugResetPort = new NetlistPort(
1323 "db_rstx", "1", 1, ProGe::BIT, ProGe::IN, *fetchBlock);
1324 toplevelBlock.netlist().connect(*ttaResetPort,
1325 *ifetchDebugResetPort);
1326 NetlistPort* ifetchPCStartPort = new NetlistPort(
1327 "db_pc_start", "IMEMADDRWIDTH", ProGe::BIT_VECTOR, ProGe::IN,
1328 *fetchBlock);
1329 toplevelBlock.netlist().connect(*ifetchPCStartPort,
1330 *ttaPCStartPort);
1331 NetlistPort* ifetchPCPort = new NetlistPort(
1332 "db_pc", "IMEMADDRWIDTH", ProGe::BIT_VECTOR, ProGe::OUT,
1333 *fetchBlock);
1334 toplevelBlock.netlist().connect(*ifetchPCPort, *ttaPCPort);
1335 NetlistPort* ifetchPCNextPort = new NetlistPort(
1336 "db_pc_next", "IMEMADDRWIDTH", ProGe::BIT_VECTOR, ProGe::OUT,
1337 *fetchBlock);
1338 toplevelBlock.netlist().connect(
1339 *ifetchPCNextPort, *dbsmPCNextPort);
1340 NetlistPort* ifetchCyclecountPort = new NetlistPort(
1341 "db_cyclecnt", "64", 64, ProGe::BIT_VECTOR, ProGe::OUT,
1342 *fetchBlock);
1343 toplevelBlock.netlist().connect(
1344 *ifetchCyclecountPort, *ttaCyclecountPort);
1345 toplevelBlock.netlist().connect(
1346 *ifetchCyclecountPort, *dbsmCyclecountPort);
1347 NetlistPort* ifetchLockcountPort = new NetlistPort(
1348 "db_lockcnt", "64", 64, ProGe::BIT_VECTOR, ProGe::OUT,
1349 *fetchBlock);
1350 toplevelBlock.netlist().connect(
1351 *ifetchLockcountPort, *ttaLockcountPort);
1352 NetlistPort *ttaInstrPort = new NetlistPort(
1353 "db_instr", "IMEMWIDTHINMAUS*IMEMMAUWIDTH",
1354 ProGe::BIT_VECTOR, ProGe::OUT, toplevelBlock);
1355 NetlistPort* ifetchFetchblockPort =
1356 fetchBlock->port("fetchblock");
1357 toplevelBlock.netlist().connect(
1358 *ifetchFetchblockPort, *ttaInstrPort);
1359
1360 }
1361 }
1362
1363 // Connect decoder softreset
1364 NetlistPort* decoderDBResetPort = decoderBlock->port("db_tta_nreset");
1365 decoderDBResetPort->unsetStatic();
1366 toplevelBlock.netlist().connect(*ttaResetPort, *decoderDBResetPort);
1367 }
1368
1369 void
1371 NetlistBlock* fetchBlock = &generator.instructionFetch();
1372 // Connect ifetch debug ports
1373 NetlistPort* ifetchDebugLockRqPort = new NetlistPort(
1374 "db_lockreq", "1", 1, ProGe::BIT, ProGe::IN, *fetchBlock);
1375 ifetchDebugLockRqPort->setToStatic(ProGe::StaticSignal::GND);
1376 NetlistPort* ifetchDebugResetPort = new NetlistPort(
1377 "db_rstx", "1", 1, ProGe::BIT, ProGe::IN, *fetchBlock);
1378 ifetchDebugResetPort->setToStatic(ProGe::StaticSignal::VCC);
1379 new NetlistPort(
1380 "db_pc", "IMEMADDRWIDTH", ProGe::BIT_VECTOR, ProGe::OUT,
1381 *fetchBlock);
1382 new NetlistPort(
1383 "db_pc_next", "IMEMADDRWIDTH", ProGe::BIT_VECTOR, ProGe::OUT,
1384 *fetchBlock);
1385 new NetlistPort(
1386 "db_cyclecnt", "32", 32, ProGe::BIT_VECTOR, ProGe::OUT,
1387 *fetchBlock);
1388 new NetlistPort(
1389 "db_lockcnt", "32", 32, ProGe::BIT_VECTOR, ProGe::OUT,
1390 *fetchBlock);
1391 }
1392
1393 /**
1394 * Generates the interconnection network and instruction decoder to
1395 * the given destination directory.
1396 *
1397 * @param dstDirectory The destination directory.
1398 * @param generator The netlist generator that generated the netlist.
1399 */
1400 virtual void
1402 HDL language, const std::string& dstDirectory,
1403 const NetlistGenerator& generator,
1405 const std::string& entityString) {
1406 const string DS = FileSystem::DIRECTORY_SEPARATOR;
1407 const string templateDir = Environment::dataDirPath("ProGe");
1408
1409 BlockSourceCopier copier(implementation, entityString, language);
1411 MachineInfo::getOpset(*generator.context().adf().controlUnit());
1412 Path proGeDataDir(Environment::dataDirPath("ProGe"));
1413 HDLTemplateInstantiator& instantiator =
1414 copier.getTemplateInstatiator();
1415
1417 instantiator.replacePlaceholder(
1418 "ifetch-stall-cond",
1419 " and " + IFETCH_STALL_PORT_NAME + " = '0'");
1420 instantiator.replacePlaceholder(
1421 "ifetch-stall-port-declarations",
1422 IFETCH_STALL_PORT_NAME + " : in std_logic;");
1423
1424 ProGe::RV32MicroCodeGenerator* microCodeGen =
1425 new RV32MicroCodeGenerator(ttamachine_, bem_, entityString);
1426 microCodeGen->setBypassInstructionRegister(
1428 microCodeGen->generateRTL(instantiator, dstDirectory);
1429 }
1430
1431 if (generateBusTrace()) {
1434 } else {
1436 }
1437
1438 try {
1439 // Check for illegal combinations in fetch/decode unit options
1440
1441 if (!generateDebugger()) {
1442 // Signal declarations as a stand-in for debug ports
1443 instantiator.replacePlaceholderFromFile(
1444 "db-signal-declarations",
1445 proGeDataDir /
1446 std::string("no_debug_signal_declaration.snippet"));
1447 }
1448
1449 if (hasSynchronousReset()) {
1450 if (language == VHDL) {
1451 generator.instructionFetch().setParameter(
1452 "sync_reset_g", "boolean", "true");
1453 instantiator.replacePlaceholder("sync-waitlist", "clk");
1454 } else { // language == Verilog
1455 instantiator.replacePlaceholder(
1456 "update-condition", "always@(posedge clk)");
1457 }
1458 } else {
1459 if (language == VHDL) {
1460 instantiator.replacePlaceholder(
1461 "sync-waitlist", "clk, rstx");
1462 } else { // language == Verilog
1463 instantiator.replacePlaceholder(
1464 "update-condition",
1465 "always@(posedge clk or negedge rstx)");
1466 }
1467 }
1468
1471 if (language == VHDL) {
1472 generator.instructionFetch().setParameter(
1473 "no_glock_loopback_g", "std_logic", "'1'");
1474 } // todo verilog version
1475 }
1476
1477 // Set the pc opcode port width
1478 std::size_t reqOpcodeWidth =
1480 instantiator.replacePlaceholder(
1481 "pc-opcode-len", Conversion::toString(reqOpcodeWidth - 1));
1482
1483 instantiator.replacePlaceholderFromFile(
1484 "default-instr-reg-write",
1485 Path(
1486 proGeDataDir /
1487 std::string("default-instr-reg-write.snippet")));
1488
1489 // Next PC process sensitivity list
1490 std::string sensitivityStringPCBypassed =
1491 "pc_in, pc_reg, increased_pc ";
1492 std::string sensitivityStringPCNotBypassed = "";
1493 // Complete the default sensitivity list
1494 sensitivityStringPCBypassed += ",\n pc_load, pc_opcode";
1495 instantiator.replacePlaceholder( // This is bypassed too
1496 "pc-sensitivity-list-pc-bypass", sensitivityStringPCBypassed);
1497
1498 // Next PC signal assign condition
1499 std::string conditionString =
1500 "pc_load = '1' and ((unsigned(pc_opcode) = IFE_CALL or \n"
1501 " unsigned(pc_opcode) = IFE_JUMP))\n";
1502 instantiator.replacePlaceholder(
1503 "not-bypassed-next-pc-condition", conditionString);
1504
1505 if (generateDebugger()) { // DEBUGTODO
1506 if (language != VHDL) {
1507 std::string errorMsg =
1508 "Language not set to VHDL when HW debugger is in "
1509 "use.";
1510 throw Exception(__FILE__, __LINE__, __func__, errorMsg);
1511 }
1512
1513 generator.instructionFetch().setParameter(
1514 "debug_logic_g", "boolean", "true");
1517 instantiator.replacePlaceholderFromFile(
1518 "db-port-declarations",
1519 Path(
1520 proGeDataDir /
1521 std::string(
1522 "debug_minimal_port_declaration.snippet")));
1523 instantiator.replacePlaceholderFromFile(
1524 "db-signal-declarations",
1525 Path(
1526 proGeDataDir /
1527 std::string(
1528 "debug_minimal_signal_declaration.snippet")));
1529 } else {
1530 instantiator.replacePlaceholderFromFile(
1531 "db-port-declarations",
1532 Path(
1533 proGeDataDir /
1534 std::string("debug_port_declaration.snippet")));
1535 instantiator.replacePlaceholderFromFile(
1536 "db-signal-declarations",
1537 Path(
1538 proGeDataDir /
1539 std::string("debug_signal_declaration.snippet")));
1540 }
1542 templateDir + DS + "ifetch." +
1543 (language == VHDL ? "vhdl" : "v") + ".tmpl",
1544 dstDirectory,
1545 std::string("ifetch.") +
1546 (language == VHDL ? "vhdl" : "v"));
1547 } else {
1549 templateDir + DS + "ifetch." +
1550 (language == VHDL ? "vhdl" : "v") + ".tmpl",
1551 dstDirectory,
1552 std::string("ifetch.") +
1553 (language == VHDL ? "vhdl" : "v"));
1554 }
1555 } catch (const Exception& e) {
1557 }
1558
1560 if (language != VHDL) {
1561 std::string errorMsg =
1562 "Instruction register bypass is not supported for "
1563 "given HDL.";
1564 throw Exception(__FILE__, __LINE__, __func__, errorMsg);
1565 }
1566
1567 addInstructioRegisterBypass(language, generator);
1568 }
1569
1570 // generate the IC
1571 icGenerator_->SetHDL(language);
1573 // generate the decoder
1574 decoderGenerator_->SetHDL(language);
1575 decoderGenerator_->generateInstructionDecoder(generator, dstDirectory);
1576
1577 if (generateDebugger()) {
1578 if (language != VHDL) {
1579 std::string errorMsg =
1580 "Language not set to VHDL when HW debugger is in use.";
1581 throw Exception(__FILE__, __LINE__, __func__, errorMsg);
1582 } else {
1583 generateDebuggerCode(generator);
1584 }
1585 }
1588 templateDir + DS + "rv32_ifetch.vhdl.tmpl", dstDirectory,
1589 "ifetch.vhdl");
1590 } else {
1592 templateDir + DS + "ifetch.vhdl.tmpl", dstDirectory,
1593 "ifetch.vhdl");
1594 }
1595 }
1596
1597 /**
1598 * Returns the required latency of the hardware implementation of the
1599 * given immediate unit.
1600 *
1601 * @param iu The immediate unit.
1602 */
1603 virtual std::set<int>
1607
1608 /**
1609 * Verifies that the plugin is compatible with the machine.
1610 *
1611 * @exception InvalidData If the plugin is not compatible with the
1612 * machine.
1613 */
1614 virtual void
1616 int requiredDelaySlots = calculateSupportedDelaySlots();
1617 int specifiedDelaySlots = ttamachine_.controlUnit()->delaySlots();
1618
1619 if (specifiedDelaySlots != requiredDelaySlots) {
1620 throw InvalidData(
1621 __FILE__, __LINE__, __func__,
1622 TCEString("Decoder generator supports ") +
1623 Conversion::toString(requiredDelaySlots + 1) +
1624 "-stage transport pipeline of GCU with given options. "
1625 "Given machine has " +
1626 Conversion::toString(specifiedDelaySlots + 1) +
1627 " stages");
1628 }
1629
1632 }
1633
1634private:
1635 /**
1636 * Returns global package definitions in the form of a stream specifically
1637 * for the variable length instruction architecture.
1638 *
1639 * @param pkgStream The destination stream
1640 */
1641 virtual void
1642 writeGlobalDefinitions(HDL language, std::ostream& pkgStream) const {
1643 if (language == ProGe::VHDL) {
1644 pkgStream << " -- instruction width" << endl
1645 << " constant INSTRUCTIONWIDTH : positive := "
1646 << bem().width() << ";" << endl;
1647 } else if (language == ProGe::Verilog) {
1648 pkgStream << "// instruction width" << endl
1649 << "parameter INSTRUCTIONWIDTH = " << bem().width()
1650 << endl;
1651 }
1652 }
1653
1654 /**
1655 * Tells whether IC generator should generate debug interface code.
1656 *
1657 * @return True if IC generator should generate the code.
1658 */
1659 bool generateDebugger(bool minimal = true) const {
1661 return false;
1662 } else {
1663 string paramValue = parameterValue(GENERATE_DEBUGGER_PARAM);
1664 if (paramValue == GENERATE_DEBUGGER_PARAM_YES ||
1665 paramValue == GENERATE_DEBUGGER_PARAM_INTERNAL ||
1666 paramValue == GENERATE_DEBUGGER_PARAM_EXTERNAL ||
1667 (paramValue == GENERATE_DEBUGGER_PARAM_MINIMAL && minimal)) {
1668 return true;
1669 } else {
1670 return false;
1671 }
1672 }
1673 }
1674
1675 /**
1676 * Tells whether IC generator should generate bus tracing code.
1677 *
1678 * @return True if IC generator should generate the code.
1679 */
1680 bool generateBusTrace() const {
1682 return false;
1683 } else {
1684 string paramValue = parameterValue(GENERATE_BUS_TRACE_PARAM);
1685 if (paramValue == GENERATE_BUS_TRACE_PARAM_YES) {
1686 return true;
1687 } else {
1688 return false;
1689 }
1690 }
1691 }
1692
1693 bool
1698
1699 /**
1700 * Tells whether IC generator should generate global lock tracing code.
1701 *
1702 * @return True if IC generator should generate the code.
1703 */
1704 bool generateLockTrace() const {
1706 return false;
1707 } else {
1708 string paramValue = parameterValue(GENERATE_LOCK_TRACE_PARAM);
1709 if (paramValue == GENERATE_LOCK_TRACE_PARAM_YES) {
1710 return true;
1711 } else {
1712 return false;
1713 }
1714 }
1715 }
1716
1717 /**
1718 * Tells whether instruction register should be left generated (true).
1719 */
1720 bool
1723 return false;
1724 } else {
1725 string paramValue = parameterValue(BYPASS_FETCHBLOCK_REG_PARAM);
1726 if (paramValue == BYPASS_FETCHBLOCK_REG_PARAM_YES) {
1727 return true;
1728 } else {
1729 return false;
1730 }
1731 }
1732 }
1733
1734 /**
1735 * Returns the starting cycle to be written to the bus trace given as
1736 * parameter.
1737 *
1738 * @return The starting cycle.
1739 */
1742 return 0;
1743 } else {
1744 string paramValue = parameterValue(BUS_TRACE_STARTING_CYCLE);
1745 try {
1746 unsigned int cycle = Conversion::toUnsignedInt(paramValue);
1747 return cycle;
1748 } catch (const Exception&) {
1749 return 0;
1750 }
1751 }
1752 }
1753
1754 /**
1755 * Returns the starting cycle to be written to the global lock trace
1756 * given as parameter.
1757 *
1758 * If parameter is not defined use value from busTraceStartingCycle()
1759 * instead.
1760 *
1761 * @return The starting cycle.
1762 */
1765 return busTraceStartingCycle();
1766 } else {
1767 string paramValue = parameterValue(LOCK_TRACE_STARTING_CYCLE);
1768
1769 if (paramValue == BUS_TRACE_STARTING_CYCLE) {
1770 return busTraceStartingCycle();
1771 }
1772
1773 try {
1774 unsigned int cycle = Conversion::toUnsignedInt(paramValue);
1775 return cycle;
1776 } catch (const Exception&) {
1777 return 0;
1778 }
1779 }
1780 }
1781
1782 bool
1785 return false;
1786 } else {
1787 string paramValue = parameterValue(NO_SELF_LOCKING_PARAM);
1788 return paramValue == NO_SELF_LOCKING_PARAM_YES;
1789 }
1790 }
1791
1792 /**
1793 * Converts the given direction to a string.
1794 *
1795 * @param direction The direction.
1796 * @return The direction as string in VHDL.
1797 */
1798 static std::string
1800 switch (direction) {
1801 case ProGe::IN:
1802 return "in";
1803 case ProGe::OUT:
1804 return "out";
1805 case ProGe::BIDIR:
1806 return "inout";
1807 }
1808 assert(false);
1809 return std::string();
1810 }
1811
1812 /**
1813 * Calculates the data port width of the given socket.
1814 *
1815 * @param socket The socket.
1816 * @return The width of the data port.
1817 */
1818 static int dataPortWidth(const TTAMachine::Socket& socket) {
1819 int ports = socket.portCount();
1820 int width(0);
1821 for (int i = 0; i < ports; i++) {
1822 Port* port = socket.port(i);
1823 if (port->width() > width) {
1824 width = port->width();
1825 }
1826 }
1827 return width;
1828 }
1829
1830 /**
1831 * Enables instruction register bypass feature in the instruction fetch
1832 * block.
1833 */
1834 void
1836 HDL language, const NetlistGenerator& generator) {
1837 assert(
1839 "Instruction register by pass only implemented for RISC-V");
1840
1841 // Todo: remove when this feature is added to debugger-fetch.
1842 assert(
1843 !generateDebugger() &&
1844 "addInstructionRegisterBypass(): "
1845 "debugger does not support Instruction Register Bypass "
1846 "feature yet.");
1847
1848 NetlistBlock* ifetchBlock = &generator.instructionFetch();
1849
1850 if (language == ProGe::VHDL) {
1851 ifetchBlock->setParameter(
1852 "bypass_fetchblock_register", "boolean", "true");
1853 } else if (language == ProGe::Verilog) {
1854 // Todo
1855 assert(
1856 false &&
1857 "Verilog version of instruction register bypass "
1858 "not implemented.");
1859 } else {
1860 assert(false && "Unknown HDL choice.");
1861 }
1862 }
1863
1864 /**
1865 * Return number of required delay slots. By default the number is three
1866 * but can be reduced or increased by options.
1867 */
1868 int
1870 int delaySlots = 3;
1872 delaySlots -= 1;
1873 }
1874 return delaySlots;
1875 }
1876
1877 /**
1878 * Reads parameters and configures the IC and decoder generators.
1879 */
1880 void
1903
1905
1910
1911}; // class DefaultICDecoderGenerator
1912
1913EXPORT_ICDEC_GENERATOR(DefaultICDecoder)
1914EXPORT_ICDEC_ESTIMATOR(DefaultICDecoder)
#define debugLog(text)
#define __func__
#define abortWithError(message)
#define assert(condition)
const std::string GENERATE_DEBUGGER_PARAM_MINIMAL
const std::string GENERATE_BUS_TRACE_PARAM
const std::string GENERATE_LOCK_TRACE_PARAM_YES
const std::string RISCV_SIMM_PORT_OUT_NAME
const std::string NO_SELF_LOCKING_PARAM_YES
const std::string BUS_TRACE_STARTING_CYCLE
const std::string ENABLE_FEATURE
const std::string GENERATE_DEBUGGER_PARAM
const std::string GENERATE_DEBUGGER_PARAM_EXTERNAL
const std::string BYPASS_FETCHBLOCK_REG_PARAM_YES
const std::string GENERATE_DEBUGGER_PARAM_YES
const std::string GENERATE_LOCK_TRACE_PARAM
const std::string LOCK_TRACE_STARTING_CYCLE
const std::string PLUGIN_DESCRIPTION
const std::string SYNC_RESET
const std::string BYPASS_FETCHBLOCK_REG_PARAM
const std::string GENERATE_DEBUGGER_PARAM_INTERNAL
const std::string NO_SELF_LOCKING_PARAM
const std::string IFETCH_STALL_PORT_NAME
const std::string GENERATE_BUS_TRACE_PARAM_YES
IDF::MachineImplementation * implementation
the implementation definition of the estimated processor
TTAMachine::Machine * machine
the architecture definition of the estimated processor
#define EXPORT_ICDEC_ESTIMATOR(PLUGIN_NAME__)
#define EXPORT_ICDEC_GENERATOR(PLUGIN_NAME__)
#define DS
CycleCount ClockCycleCount
Alias for ClockCycleCount.
virtual int width(const TCEString &templateName) const
static std::string toString(const T &source)
static unsigned int toUnsignedInt(const T &source)
std::string name_
the name of the plugin class in the HDB; used to identify cost data
const TTAMachine::Bus & bus() const
const TTAMachine::Socket & sourceSocket() const
const TTAMachine::Socket & destinationSocket() const
virtual std::string stringValue() const
virtual double doubleValue() const
virtual void setString(std::string value)
virtual int integerValue() const
void completeDecoderBlock(const ProGe::NetlistGenerator &nlGenerator, ProGe::NetlistBlock &coreBlock)
static const std::string RISCV_SIMM_PORT_IN_NAME
void SetHDL(ProGe::HDL language)
void setLockTraceStartingCycle(unsigned int startCycle)
static const std::string GLOCK_PORT_NAME
void generateInstructionDecoder(const ProGe::NetlistGenerator &nlGenerator, const std::string &dstDirectory)
std::set< int > requiredRFLatencies(const TTAMachine::ImmediateUnit &iu) const
void setGenerateLockTrace(bool generate)
void setGenerateNoLoopbackGlock(bool generate)
void setGenerateDebugger(bool generate)
virtual bool estimateICEnergy(HDB::HDBRegistry &hdbRegistry, const TTAMachine::Machine &machine, const IDF::MachineImplementation &machineImplementation, const TTAProgram::Program &, const ExecutionTrace &traceDB, EnergyInMilliJoules &energy)
DefaultICDecoderEstimator(const std::string &name)
DelayInNanoSeconds delayOfSocket(HDB::HDBManager &hdb, const TTAMachine::Socket &socket)
DelayInNanoSeconds delayOfBus(HDB::HDBRegistry &hdbRegistry, const IDF::BusImplementationLocation &implementation)
FanInFanOutCombinationSet socketParameters(const TTAMachine::Socket &socket)
std::vector< ICParameters > FanInFanOutCombinationSet
DelayInNanoSeconds delayOfSocket(HDB::HDBRegistry &hdbRegistry, const IDF::SocketImplementationLocation &implementation)
virtual bool estimateICArea(HDB::HDBRegistry &hdbRegistry, const TTAMachine::Machine &machine, const IDF::MachineImplementation &machineImplementation, AreaInGates &area)
FanInFanOutCombinationSet busParameters(const TTAMachine::Bus &bus)
std::set< std::string > missingComponents_
Set for component names that are missing from HDB.
DataObject valueFromKeyValuePairString(const std::string &keyName, const std::string &keyValuePairString)
DelayInNanoSeconds delayOfBus(HDB::HDBManager &hdb, const TTAMachine::Bus &bus)
FanInFanOutCombinationSet generateFanInFanOutCombinations(std::vector< std::size_t > &inputWidths, std::vector< std::size_t > &outputWidths)
virtual bool estimateICDelayOfPath(HDB::HDBRegistry &hdbRegistry, const TransportPath &path, const IDF::MachineImplementation &machineImplementation, const IDF::SocketImplementationLocation &, const IDF::BusImplementationLocation &, const IDF::SocketImplementationLocation &, DelayInNanoSeconds &delay)
virtual void generate(HDL language, const std::string &dstDirectory, const NetlistGenerator &generator, const IDF::MachineImplementation &implementation, const std::string &entityString)
virtual void verifyCompatibility() const
bool generateDebugger(bool minimal=true) const
void generateDebuggerCode(const NetlistGenerator &generator)
virtual void completeNetlist(NetlistBlock &netlistBlock, const NetlistGenerator &generator)
void addDummyIfetchDebugPorts(const NetlistGenerator &generator)
static std::string vhdlDirection(ProGe::Direction direction)
DefaultICDecoderGenerator(const TTAMachine::Machine &machine, const BinaryEncoding &bem)
static int dataPortWidth(const TTAMachine::Socket &socket)
void addInstructioRegisterBypass(HDL language, const NetlistGenerator &generator)
virtual std::set< int > requiredRFLatencies(const TTAMachine::ImmediateUnit &iu) const
DefaultDecoderGenerator * decoderGenerator_
const TTAMachine::Machine & ttamachine_
virtual void writeGlobalDefinitions(HDL language, std::ostream &pkgStream) const
void addRV32MicroCode(NetlistBlock &netlistBlock, const NetlistGenerator &generator)
void verifyCompatibility() const
void setBusTraceStartingCycle(unsigned int cycle)
void setGenerateBusTrace(bool generate)
void SetHDL(ProGe::HDL language)
void addICToNetlist(const ProGe::NetlistGenerator &generator, ProGe::NetlistBlock &netlistBlock)
void setExportBustrace(bool export_bt)
void generateInterconnectionNetwork(const std::string &dstDirectory)
static std::string dataDirPath(const std::string &prog)
std::string errorMessage() const
Definition Exception.cc:123
ClockCycleCount simulatedCycleCount() const
ClockCycleCount socketWriteCount(SocketID socket) const
ClockCycleCount busWriteCount(BusID bus) const
static const std::string DIRECTORY_SEPARATOR
std::string fileName() const
virtual DataObject costEstimationDataValue(const std::string &valueName, const std::string &pluginName) const
DataObject socketCostEstimationData(const std::string &valueName, RowID socketID, const std::string &pluginName) const
DataObject busCostEstimationData(const std::string &valueName, RowID busID, const std::string &pluginName) const
CachedHDBManager & hdb(const std::string fileName)
void replacePlaceholderFromFile(const std::string &key, const Path &filePath, bool append=false)
void replacePlaceholder(const std::string &key, const std::string &replacer, bool append=false)
TCETools::CIStringSet OperationSet
static OperationSet getOpset(const TTAMachine::Machine &mach)
const std::string & instanceName() const
const std::string & moduleName() const
HDLTemplateInstantiator & getTemplateInstatiator()
void instantiateHDLTemplate(const std::string &srcFile, const std::string &dstDirectory, std::string newName="0")
static size_t gcuOpcodeWidth(const TTAMachine::Machine &mach)
void addParameter(const std::string &name, const std::string &description)
const BinaryEncoding & bem() const
std::string parameterValue(const std::string &name) const
bool hasParameterSet(const std::string &name) const
const TTAMachine::Machine & machine() const
virtual size_t subBlockCount() const
void addSubBlock(BaseNetlistBlock *subBlock, const std::string &instanceName="")
void setParameter(const std::string &name, const std::string &type, const std::string &value)
virtual NetlistPort * port(const std::string &portName, bool partialMatch=true)
NetlistBlock & subBlock(size_t index) override
void addPackage(const std::string &packageName)
virtual const NetlistBlock & parentBlock() const override
virtual const Netlist & netlist() const
NetlistPort & rstPort(const NetlistBlock &block) const
static const std::string FETCHBLOCK_PORT_NAME
NetlistPort & gcuReturnAddressInPort() const
NetlistBlock & instructionDecompressor() const
NetlistBlock & instructionDecoder() const
NetlistBlock & instructionFetch() const
NetlistPort & clkPort(const NetlistBlock &block) const
const ProGeContext & context() const
void setToStatic(StaticSignal value) const
void setWidthFormula(const std::string &newFormula)
std::string widthFormula() const
void unsetStatic() const
bool connect(const NetlistPort &port1, const NetlistPort &port2, int port1FirstBit, int port2FirstBit, int width=1)
Definition Netlist.cc:83
void disconnectPorts(const NetlistPort &port1, const NetlistPort &port2)
Definition Netlist.cc:135
const TTAMachine::Machine & adf() const
void setBypassInstructionRegister(const bool &value)
void generateRTL(HDLTemplateInstantiator &instantiator, const std::string &fileDst)
@ GND
All port signals set to low.
@ VCC
All port signals set to high.
int width() const
Definition Bus.cc:149
virtual bool isConnectedTo(const Socket &socket) const
Definition Bus.cc:303
virtual Machine * machine() const
virtual TCEString name() const
ComponentType * item(int index) const
virtual SocketNavigator socketNavigator() const
Definition Machine.cc:368
virtual BusNavigator busNavigator() const
Definition Machine.cc:356
virtual ControlUnit * controlUnit() const
Definition Machine.cc:345
bool isRISCVMachine() const
Definition Machine.cc:1057
virtual int width() const =0
Bus * parentBus() const
@ OUTPUT
Data goes from port to bus.
Definition Socket.hh:60
@ INPUT
Data goes from bus to port.
Definition Socket.hh:59
Direction direction() const
Port * port(int index) const
Definition Socket.cc:266
Segment * segment(int index) const
Definition Socket.cc:401
int segmentCount() const
int portCount() const
double AreaInGates
type for area values in equivalent gates
double DelayInNanoSeconds
type for propagation delays in nano seconds
double EnergyInMilliJoules
type for consumed energy in milli joules
Definition FUGen.hh:54
@ BIT
One bit.
Definition ProGeTypes.hh:47
@ BIT_VECTOR
Several bits.
Definition ProGeTypes.hh:48
Direction
Direction of the port.
Definition ProGeTypes.hh:52
@ OUT
Output port.
Definition ProGeTypes.hh:54
@ IN
Input port.
Definition ProGeTypes.hh:53
@ BIDIR
Bidirectional port.
Definition ProGeTypes.hh:55
HDL
HDLs supported by ProGe.
Definition ProGeTypes.hh:40
@ Verilog
Verilog.
Definition ProGeTypes.hh:42
@ VHDL
VHDL.
Definition ProGeTypes.hh:41