My Project
DFnetlist.h
Go to the documentation of this file.
1 #ifndef DATAFLOW_IMPL_H
2 #define DATAFLOW_IMPL_H
3 
4 #include <cassert>
5 #include <deque>
6 #include <list>
7 #include <map>
8 #include <string>
9 #include "Dataflow.h"
10 #include "ErrorManager.h"
11 #include "FileUtil.h"
12 #include "MILP_Model.h"
13 
14 // Some useful macros
15 #define ForAllBlocks(b) for (blockID b: allBlocks)
16 #define ForAllChannels(c) for (channelID c: allChannels)
17 #define ForAllPorts(b,p) for (portID p: getPorts(b, ALL_PORTS))
18 #define ForAllInputPorts(b,p) for (portID p: getPorts(b, INPUT_PORTS))
19 #define ForAllOutputPorts(b,p) for (portID p: getPorts(b, OUTPUT_PORTS))
20 #define ForAllBasicBlocks(bb) for (bbID bb = 0; bb < numBasicBlocks(); ++bb)
21 
22 namespace Dataflow
23 {
24 struct milpVarsEB; // Defined locally in DFnetlist_buffers.cpp
25 struct milpVarsMG; // Defined locally in DFnetlist_MG.cpp
26 
27 using bbID = int; // Identifiers for Basic Blocks
28 using bbArcID = int; // Identifiers for Basic Block arcs
29 using vecBBs = std::vector<bbID>;
30 using setBBs = std::set<bbID>;
31 using vecBBArcs = std::vector<bbArcID>;
32 using setBBArcs = std::set<bbArcID>;
33 
34 using longValueType = long long; // Internal representation for constant values
35 
46 {
47 public:
48 
53  clear();
54  }
55 
59  void clear() {
60  BBs.clear();
61  Arcs.clear();
62  entryBB = invalidDataflowID;
63  }
64 
68  int numBasicBlocks() const {
69  return BBs.size();
70  }
71 
75  int numArcs() const {
76  return Arcs.size();
77  }
78 
82  bool empty() const {
83  return numBasicBlocks() == 0;
84  }
85 
92  bbID id = BBs.size() + 1;
93 
94  // Block with freq = -1 and exec = 1
95  BasicBlock bb;
96  bb.exec = 1;
97  bb.freq = -1;
98  bb.id = id;
99 
100  BBs.push_back(bb);
101  return id;
102  }
103 
108  void setEntryBasicBlock(bbID bb) {
109  entryBB = bb;
110  }
111 
115  bbID getEntryBasicBlock() const {
116  return entryBB;
117  }
118 
119  setBBs& getExitBasicBlocks() {
120  return exitBBs;
121  }
122 
123  void addExitBasicBlock(bbID bb) {
124  exitBBs.insert(bb);
125  }
126 
127  bool isEntryBasicBlock(bbID bb) {
128  return entryBB == bb;
129  }
130 
131  bool isExitBasicBlock(bbID bb) {
132  return exitBBs.count(bb) > 0;
133  }
134 
142  bbArcID findArc(bbID src, bbID dst) const;
143 
150  bbArcID findOrAddArc(bbID src, bbID dst, double freq = 0);
151 
157  bbID getSrcBB(bbArcID arc) const {
158  return Arcs[arc].src;
159  }
160 
166  bbID getDstBB(bbArcID arc) const {
167  return Arcs[arc].dst;
168  }
169 
175  void setProbability(bbArcID arc, double prob) {
176  Arcs[arc].prob = prob;
177  }
178 
184  double getProbability(bbArcID arc) const {
185  return Arcs[arc].prob;
186  }
187 
188  void setFrequencyArc(bbArcID arc, double freq) {
189  Arcs[arc].freq = freq;
190  }
191 
192  double getFrequencyArc(bbArcID arc) const {
193  return Arcs[arc].freq;
194  }
195 
202  bool calculateBackArcs();
203 
209  void setBackArc(bbArcID arc, bool back = true) {
210  Arcs[arc].back = back;
211  }
212 
218  bool isBackArc(bbArcID arc) const {
219  return Arcs[arc].back;
220  }
221 
227  setBBArcs& predecessors(bbID bb) {
228  return BBs[bb - 1].pred;
229  }
230 
236  setBBArcs& successors(bbID bb) {
237  return BBs[bb - 1].succ;
238  }
239 
245  void setFrequency(bbID bb, double f) {
246  BBs[bb - 1].freq = f;
247  }
248 
254  double getFrequency(bbID bb) const {
255  return BBs[bb - 1].freq;
256  }
257 
263  void setExecTime(bbID bb, double t) {
264  BBs[bb - 1].exec = t;
265  }
266 
272  double getExecTime(bbID bb) const {
273  return BBs[bb - 1].exec;
274  }
275 
276  double isEntryBB(bbID bb) {
277  return entryBB == bb;
278  }
279 
280  double getDFSorder(bbID bb) {
281  return BBs[bb - 1].DFS_order;
282  }
283 
284  void setDFSorder(bbID bb, int order) {
285  BBs[bb - 1].DFS_order = order;
286  }
287 
288  double getSCCnumber(bbID bb) {
289  return BBs[bb - 1].SCC_number;
290  }
291 
292  void setSCCnumber(bbID bb, int number) {
293  BBs[bb - 1].SCC_number = number;
294  }
295 
296 
308  bool calculateBasicBlockFrequencies(double back_prob = 0.9);
309 
318  //SHAB_note: check this :-?
319  double extractBasicBlockCycles(double coverage = -1.0);
320 
321  void DFS();
322 
323  void computeSCC();
324 
325  void setDSUnumberArc(bbArcID arc, int number) {
326  assert (arc >= 0 && arc < numArcs());
327  Arcs[arc].DSU_number = number;
328  }
329 
330  void addMGnumber(bbArcID arc, int number) {
331  assert (arc >= 0 && arc < numArcs());
332  Arcs[arc].MG_numbers.push_back(number);
333  }
334 
335  int getDSUnumberArc(bbArcID arc) {
336  return Arcs[arc].DSU_number;
337  }
338 
339  vector<int>& getMGnumbers(bbArcID arc) {
340  return Arcs[arc].MG_numbers;
341  }
342 
343  std::vector<bbID>& getBlocksInCycle(int cycle_number){
344  return cycles[cycle_number].cycle;
345  }
346 
347  int getCycleNum(){
348  return cycles.size();
349  }
350 
351 private:
352  // Structure to represent a Basic Block.
353  struct BasicBlock {
354  double freq; // Execution frequency of the BB
355  double exec; // Execution time of the BB
356  setBBArcs pred; // Prededessor arcs
357  setBBArcs succ; // Successor arcs
358  double residual_freq; // Residual frequency (used to compute frequent cycles)
359  bbID id;
360  int DFS_order;
361  int SCC_number;
362  };
363 
364  // Arc connecting two BBs in the Basic Block Graph
365  struct BB_Arc {
366  bbID src; // Src BB
367  bbID dst; // Dst BB
368  bool back; // Is it a back edge?
369  double prob; // Probability of taking the arc (-1 if undefined)
370  bbArcID id;
371  double freq; // Execution frequency of the arc
372 
373  vector<int> MG_numbers;
374  int DSU_number;
375  };
376 
377  // Structure to represent a cycle in the Basic Block Graph.
378  struct BasicBlockCycle {
379  double freq; // Execution frequency of the cycle
380  double exec; // Execution time of the cycle
381  std::vector<bbID> cycle; // Sequence of BBs (the last BB is connected to the first)
382  std::vector<bool> executed; // A flag to denote which block is executed
383  };
384 
385  std::vector<BasicBlock> BBs; // List of basic blocks
386  std::vector<BB_Arc> Arcs; // List of arcs
387  bbID entryBB; // Entry Basic Block
388  setBBs exitBBs; // set of exit Basic Blocks
389  std::vector<bbID> DFSorder; // DFS order to get SCC of MGs
390 
391  std::vector<BasicBlockCycle> cycles; // List of critical cycles
392 
401  void setDefaultProbabilities(double back_prob = 0.9);
402 
407  BasicBlockCycle extractBasicBlockCycle();
408 };
409 
418 {
419 
420 public:
424  DFnetlist_Impl();
425 
430  DFnetlist_Impl(const std::string& name);
431 
437  DFnetlist_Impl(FILE* file);
438 
446  DFnetlist_Impl(const std::string& name, const std::string& name_bb);
447 
453  bool check();
454 
458  const std::string& getName() const;
459 
466  blockID createBlock(BlockType type, const std::string& name = "");
467 
473  blockID getBlock(const std::string& name) const;
474 
480  const std::string& getBlockName(blockID id) const;
481 
487  BlockType getBlockType(blockID id) const;
488 
489  std::string printBlockType(BlockType type) const;
490 
491  void printChannelInfo(channelID c, int slots, int transparent);
492 
493  bool isInnerChannel(channelID c);
494 
495  bool getChannelMerge(channelID c); //Carmine 09.03.22 these two functions are used to preserve
496  void setChannelMerge(channelID c); //Carmine 09.03.22 the information for writing the dot after reduceMerges function
497 
498 
504  double getBlockDelay(blockID id, int indx) const;
505 
506 
511  void setBasicBlock(blockID id, bbID bb = invalidDataflowID);
512 
518  bbID getBasicBlock(blockID id) const;
519 
525  void setBlockDelay(blockID id, double d, int indx);
526 
532  int getLatency(blockID id) const;
533 
539  void setLatency(blockID id, int lat);
540 
541 
542  double getBlockRetimingDiff(blockID id) const;
543 
544 
545  void setBlockRetimingDiff(blockID id, double diff);
546 
552  int getInitiationInterval(blockID id) const;
553 
559  void setInitiationInterval(blockID id, int ii);
560 
566  void setExecutionFrequency(blockID id, double freq);
567 
573  int getExecutionFrequency(blockID id) const;
574 
575 
581  void setTrueFrac(blockID id, double freq);
582 
588  double getTrueFrac(blockID id) const;
589 
595  void setValue(blockID id, longValueType value);
596 
602  void setOperation(blockID id, std::string op);
603 
604  // Lana 02.07.19
605  const std::string& getOperation(blockID id) const;
606 
607  // Lana 03.07.19
608  void setMemPortID(blockID id, int memPortID);
609 
610  int getMemPortID(blockID id) const;
611 
612  void setMemOffset(blockID id, int memOffset);
613 
614  int getMemOffset(blockID id) const;
615 
616  void setMemBBCount(blockID id, int count);
617 
618  int getMemBBCount(blockID id) const;
619 
620  void setMemLdCount(blockID id, int count);
621 
622  int getMemLdCount(blockID id) const;
623 
624  void setMemStCount(blockID id, int count);
625 
626  int getMemStCount(blockID id) const;
627 
628  void setMemName(blockID id, std::string name);
629 
630  const std::string& getMemName(blockID id) const;
631 
632  void setMemPortSuffix(blockID id, std::string op);
633 
634  const std::string& getMemPortSuffix(blockID id) const;
635 
636  void setFuncName(blockID id, std::string op);
637 
638  const std::string& getFuncName(blockID id) const;
639 
640  void setOrderings(blockID id, map<bbID, vector<int>> value);
641 
642  // Lana 04/10/19
643 
644  void setLSQDepth(blockID id, int depth);
645 
646  int getLSQDepth(blockID id) const;
647 
648  void setNumLoads(blockID id, std::string name);
649 
650  const std::string& getNumLoads(blockID id) const;
651 
652  void setNumStores(blockID id, std::string name);
653 
654  const std::string& getNumStores(blockID id) const;
655 
656  void setLoadOffsets(blockID id, std::string name);
657 
658  const std::string& getLoadOffsets(blockID id) const;
659 
660  void setStoreOffsets(blockID id, std::string name);
661 
662  const std::string& getStoreOffsets(blockID id) const;
663 
664  void setLoadPorts(blockID id, std::string name);
665 
666  const std::string& getLoadPorts(blockID id) const;
667 
668  void setStorePorts(blockID id, std::string name);
669 
670  const std::string& getStorePorts(blockID id) const;
671 
672  void setGetPtrConst(blockID id, int c);
673 
674  int getGetPtrConst(blockID id) const;
675 
681  longValueType getValue(blockID id);
682 
688  bool getBoolValue(blockID id) const;
689 
695  int getBufferSize(blockID id) const;
696 
702  void setBufferSize(blockID id, int slots);
703 
709  bool isBufferTransparent(blockID id) const;
710 
716  void setBufferTransparency(blockID id, bool value);
717 
722  blockID getBlockFromPort(portID p) const;
723 
728  void removeBlock(blockID block);
729 
740  portID createPort(blockID block, bool isInput, const std::string& name="", int width = -1, PortType type = GENERIC_PORT);
741 
746  void removePort(portID port);
747 
754  portID getPort(blockID block, const std::string& name) const;
755 
762  const std::string& getPortName(portID port, bool full=true) const;
763 
769  PortType getPortType(portID port) const;
770 
776  bool isInputPort(portID port) const;
777 
783  bool isOutputPort(portID port) const;
784 
790  void setPortWidth(portID port, int width);
791 
797  int getPortWidth(portID port) const;
798 
804  bool isBooleanPort(portID port) const;
805 
811  bool isControlPort(portID port) const;
812 
819  bool isBooleanConstant(portID port, bool& value) const;
820 
826  double getPortDelay(portID port) const;
827 
833  void setPortDelay(portID port, double d);
834 
843  double getCombinationalDelay(portID inp, portID outp) const;
844 
851  const setPorts& getPorts(blockID id, PortDirection dir) const;
852 
858  const setPorts& getDefinitions(portID p) const;
859 
864  portID getConditionalPort(blockID id) const;
865 
870  portID getTruePort(blockID id) const;
871 
876  portID getFalsePort(blockID id) const;
877 
882  portID getDataPort(blockID id) const;
883 
891  portID getDemuxComplementaryPort(portID port) const;
892 
898  channelID getConnectedChannel(portID port) const;
899 
905  bool isPortConnected(portID port) const;
906 
912  portID getConnectedPort(portID port) const;
913 
922  channelID createChannel(portID src, portID dst, int slots = 0, bool transparent = true);
923 
928  void removeChannel(channelID id);
929 
935  portID getSrcPort(channelID id) const;
936 
942  portID getDstPort(channelID id) const;
943 
949  blockID getSrcBlock(channelID id) const;
950 
956  blockID getDstBlock(channelID id) const;
957 
965  string getChannelName(channelID id, bool full=true) const;
966 
972  channelID getChannelID(portID id); //Carmine 09.03.22 new function
973 
974 
980  int getChannelBufferSize(channelID id) const;
981 
987  void setChannelBufferSize(blockID id, int slots);
988 
994  bool isChannelTransparent(channelID id) const;
995 
1001  void setChannelTransparency(channelID id, bool value);
1002 
1003 
1008  void setChannelEB(channelID id);
1009 
1014  bool getChannelEB(channelID id);
1015 
1016  void setChannelFrequency(channelID id, double value);
1017 
1018  double getChannelFrequency(channelID id);
1019 
1025  bool hasBuffer(channelID id) const;
1026 
1035  blockID insertBuffer(channelID c, int slots, bool transparent);
1036 
1046  blockID insertBuffer(channelID c, int slots, bool transparent, bool EB);
1047 
1053  channelID removeBuffer(blockID buf);
1054 
1059  void setError(const std::string& err);
1060 
1064  const std::string& getError() const;
1065 
1069  std::string& getError();
1070 
1074  void clearError();
1075 
1080  bool hasError() const;
1081 
1085  int numBlocks() const;
1086 
1090  int numChannels() const;
1091 
1095  int numPorts() const;
1096 
1101  bool validPort(portID p) const;
1102 
1108  bool validBlock(blockID id) const;
1109 
1115  bool validChannel(channelID id) const;
1116 
1120  void reduceMerges(); //Carmine 09.03.22 new function
1121 
1122  void execute_reduction(blockID b); //Carmine 09.03.22 function to eliminate a block
1123 
1130  bool writeDot(const std::string& filename = "");
1131 
1137  bool writeDot(std::ostream& of);
1138 
1139  bool writeDotMG(const std::string& filename = "");
1140  bool writeDotMG(std::ostream& s);
1141 
1142  bool writeDotBB(const std::string& filename = "");
1143  bool writeDotBB(std::ostream& of);
1144 
1151  bool writeBasicBlockDot(const std::string& filename = "");
1152 
1158  bool writeBasicBlockDot(std::ostream& s);
1159 
1170  bool addElasticBuffers(double Period = 0, double BufferDelay = 0, bool MaxThroughput = false, double coverage = 0);
1171 
1182  bool addElasticBuffersBB(double Period = 0, double BufferDelay = 0, bool MaxThroughput = false, double coverage = 0, int timeout = -1, bool first_MG = false);
1183  bool addElasticBuffersBB_sc(double Period = 0, double BufferDelay = 0, bool MaxThroughput = false, double coverage = 0, int timeout = -1, bool first_MG = false, const std::string& model_mode = "default", const std::string& lib_path="");
1184 
1185  void addBorderBuffers();
1186  void findMCLSQ_load_channels();
1191  void instantiateElasticBuffers();
1192 
1196  void instantiateAdditionalElasticBuffers(const std::string& filename);
1197 
1198 
1202  void hideElasticBuffers();
1203 
1207  void cleanElasticBuffers();
1208 
1213  void setMilpSolver(const std::string& solver="cbc");
1214 
1220  void eraseNonSCC();
1221 
1228  bool calculateBasicBlocks();
1229 
1236  bool optimize();
1237 
1242  bool removeControl();
1243 
1251  double extractMarkedGraphs(double coverage);
1252 
1260  double extractMarkedGraphsBB(double coverage);
1261 
1262  void printBlockSCCs();
1263  void computeSCCpublic(bool onlyMarked) {
1264  computeSCC(onlyMarked);
1265  }
1266 
1267  setBlocks allBlocks; // Set of blocks (for iterators)
1268  setPorts allPorts; // Set of ports (for iterators)
1269  setChannels allChannels; // Set of channels (for iterators)
1270 
1271  BasicBlockGraph BBG; // Graph of Basic Blocks
1272 
1273 
1274 private:
1275 
1276  struct Block {
1277  blockID id; // Id of the block (redundant, but useful)
1278  std::string name; // Name of the block
1279  BlockType type; // Type of block
1280  longValueType value; // Value (only used for constants)
1281  bool boolValue; // Boolean value (only used for constants)
1282  blockID nextFree; // Next free block in the vector of blocks
1283  bbID basicBlock; // Basic block to which the block belongs to
1284  double delay; // Delay of the block
1285  double delays[8]; // Delays of the block //Andrea
1286  int latency; // Latency of the block (only for Operators)
1287  int II; // Initiation interval of the block (only for Operators)
1288  int slots; // Number of slots (only for EBs)
1289  bool transparent; // Is the buffer transparent? (only for EBs)
1290  setPorts inPorts; // Set of input ports (id's)
1291  setPorts outPorts; // Set of output ports (id's)
1292  setPorts allPorts; // All ports of the block
1293  portID portCond; // Port for condition (for branch/select)
1294  portID portTrue, portFalse; // True and false ports (for branch/select)
1295  portID data; // Port for data (input for branch/demux, output for select)
1296  portID srcCond; // Port that generates the condition for the branch (beyond forks)
1297  double freq; // Execution frequency (obtained from profiling)
1298  double frac; // True/false fraction of select inputs (obtained from profiling)
1299  double retimingDiff; // Axel
1300  bool mark; // Flag used for traversals
1301  int scc_number; // SCC number
1302  int DFSorder; // Post-visit number during DFS traversal
1303  std::deque<portID> listPorts; // Temporary list of input ports (for demux pairing)
1304  std::map<portID,portID> demuxPairs; // Pairs of ports in a demux. The pairs are in both directions.
1305  blockID bbParent; // Disjoint set parent for BB calculation
1306  int bbRank; // Disjoint set rank for BB calculation
1307  std::string operation; // Lana: arithmetic/memory operation (instruction)
1308  int memPortID; // Lana: used to connect load/store to MC/LSQ
1309  int memOffset; // Lana: used to connect load/store to MC/LSQ
1310  int memBBCount; // Lana: number of BBs connected to MC/LSQ
1311  int memLdCount; // Lana: number of loads connected to MC/LSQ
1312  int memStCount; // Lana: number of stores connected to MC/LSQ
1313  std::string memName; // LSQ/MC name
1314  std::string funcName; // Lana: name of called function (for call instruction)
1315  int fifoDepth; // Lana: LSQ depth
1316  // Lana: LSQ json configuration info
1317  std::string numLoads;
1318  std::string numStores;
1319  std::string loadOffsets;
1320  std::string storeOffsets;
1321  std::string loadPorts;
1322  std::string storePorts;
1323  int getptrc; // Lana: constant for getelementpointer dimensions
1324  map<bbID, vector<int>> orderings; //Axel : used by selector to know order of execution
1325  };
1326 
1327  struct Port {
1328  portID id; // Identifier of the port
1329  std::string short_name; // Name of the port
1330  std::string full_name; // Full name of the port (block:port)
1331  blockID block; // Owner of the port
1332  portID nextFree; // Next free slot in the vector of ports
1333  bool isInput; // Direction of the port
1334  int width; // Width of the port (0: control, 1: boolean, >1: data)
1335  double delay; // Delay associated to the port
1336  PortType type; // Type: generic, selection, sel_true or sel_false
1337  channelID channel; // Channel connected to the port
1338  setPorts defs; // Set of definitions (ports) reaching this port
1339  std::string memPortSuffix; // Lana: MC/LSQ port suffix, to distinguish port types of MC/LSQ
1340  };
1341 
1342  struct Channel {
1343  channelID id; // Identifier of the channel
1344  portID src; // Source port (output port)
1345  portID dst; // Destination port (input port)
1346  int slots; // Number of slots (used to insert Elastic Buffers)
1347  bool transparent; // Is the buffer transparent? (used to insert Elastic Buffers)
1348  bool backEdge; // Indicates whether it is a back edge (after calculation of BBs)
1349  channelID nextFree; // Next free slot in the vector of channels
1350  bool mark; // Flag used for traversals
1351  double freq; // number of times this channels is executed
1352  bool EB = false; // boolean to set the presence of an elastic buffer on the channel // Carmine 21.02.22
1353  bool channelMerge = false; // boolean to set the presence of merge after channel during reduceMerges function // Carmine 09.03.22
1354  };
1355 
1356  // Structure to represent a fragment of a netlist.
1357  // It is used for extracting SCCs and Marked Graphs.
1358  struct subNetlist {
1359  setBlocks blocks; // Set of blocks in the subnetlist
1360  setChannels channels; // Set of channels in the subnetlist
1361 
1362  // Constructor
1363  subNetlist() {}
1364 
1365  // Copy
1366  subNetlist(subNetlist const& other) :
1367  blocks(other.blocks), channels(other.channels) {}
1368 
1369  // Assignment
1370  subNetlist& operator=(subNetlist other) {
1371  other.swap(*this);
1372  return *this;
1373  }
1374 
1375  // Swap
1376  void swap(subNetlist& other) {
1377  using std::swap;
1378  swap(blocks, other.blocks);
1379  swap(channels, other.channels);
1380  }
1381 
1382  // Resets the subnetlist
1383  void clear() {
1384  blocks.clear();
1385  channels.clear();
1386  }
1387 
1388  // Is it empty?
1389  bool empty() const {
1390  return channels.empty() and blocks.empty();
1391  }
1392 
1393  // Number of blocks of the subnetlist
1394  int numBlocks() const {
1395  return blocks.size();
1396  }
1397 
1398  // Number of channels of the subnetlist
1399  int numChannels() const {
1400  return channels.size();
1401  }
1402 
1403  // Returns the set of blocks (not modifiable)
1404  const setBlocks& getBlocks() const {
1405  return blocks;
1406  }
1407 
1408  // Returns the set of channels
1409  const setChannels& getChannels() const {
1410  return channels;
1411  }
1412 
1413  // Checks whether a block is in the subnetlist
1414  bool hasBlock(blockID b) const {
1415  return blocks.count(b) > 0;
1416  }
1417 
1418  // Checks whether a channel is in the subnetlist
1419  bool hasChannel(channelID c) const {
1420  return channels.count(c) > 0;
1421  }
1422 
1423  // Inserts a block into the subnetlist
1424  void insertBlock(blockID b) {
1425  blocks.insert(b);
1426  }
1427 
1428  // Inserts a channel into the subnetlist.
1429  // The blocks connected to the channel are also inserted.
1430  void insertChannel(const DFnetlist_Impl& dfn, channelID c) {
1431  channels.insert(c);
1432  insertBlock(dfn.getBlockFromPort(dfn.getSrcPort(c)));
1433  insertBlock(dfn.getBlockFromPort(dfn.getDstPort(c)));
1434  }
1435  };
1436 
1437  struct subNetlistBB {
1438  set <bbID> BasicBlocks;
1439  set <bbArcID> BasicBlockArcs;
1440 
1441  int SCC_no;
1442  int min_freq; //todo: for now we're ignoring this
1443 
1444  int DSU_no;
1445  int DSU_parent;
1446  int DSU_rank;
1447 
1448  subNetlistBB(){
1449  BasicBlocks = {};
1450  BasicBlockArcs = {};
1451  clear();
1452  }
1453 
1454  void clear(){
1455  BasicBlocks.clear();
1456  BasicBlockArcs.clear();
1457  SCC_no = 0;
1458  min_freq = 0;
1459  DSU_rank = -1;
1460  DSU_parent = -1;
1461  DSU_no = -1;
1462  }
1463 
1464  bool empty(){
1465  return BasicBlocks.empty() and BasicBlockArcs.empty();
1466  }
1467 
1468  int numBasicBlocks(){
1469  return BasicBlocks.size();
1470  }
1471 
1472  int numBasicBlockArcs() {
1473  return BasicBlockArcs.size();
1474  }
1475 
1476  const set<bbID>& getBasicBlocks() {
1477  return BasicBlocks;
1478  }
1479 
1480  const set<bbArcID>& getBasicBlockArcs() {
1481  return BasicBlockArcs;
1482  }
1483 
1484  bool hasBasicBlock(bbID b) {
1485  return BasicBlocks.count(b) > 0;
1486  }
1487 
1488  bool hasBasicBlockArc(bbArcID a) {
1489  return BasicBlockArcs.count(a) > 0;
1490  }
1491 
1492  void insertBasicBlock(bbID b) {
1493  BasicBlocks.insert(b);
1494  }
1495 
1496  void insertBasicBlockArc(bbArcID a) {
1497  BasicBlockArcs.insert(a);
1498  }
1499 
1500  void merge(subNetlistBB& other) {
1501  for (bbID bb: other.getBasicBlocks()) {
1502  insertBasicBlock(bb);
1503  }
1504 
1505  for (bbArcID bbArc: other.getBasicBlockArcs()) {
1506  insertBasicBlockArc(bbArc);
1507  }
1508  }
1509 
1510  bool sameSCC(subNetlistBB other) {
1511  return SCC_no == other.getSCCnumber();
1512  }
1513 
1514  int getSCCnumber() {
1515  return SCC_no;
1516  }
1517 
1518  int setSCCnumber(int number) {
1519  SCC_no = number;
1520  }
1521 
1522  int getMinimumFreq() {
1523  return min_freq;
1524  }
1525 
1526  void setMinimumFreq(int freq) {
1527  min_freq = freq;
1528  }
1529 
1530  int getDSUnumber() {
1531  return DSU_no;
1532  }
1533 
1534  void setDSUnumber(int number) {
1535  DSU_no = number;
1536  }
1537 
1538  bool haveCommonBasicBlock(subNetlistBB &other) {
1539  for (bbID bb: other.getBasicBlocks()) {
1540  if (hasBasicBlock(bb)) {
1541  return true;
1542  }
1543  }
1544  return false;
1545  }
1546 
1547  int getDSUParent() {
1548  return DSU_parent;
1549  }
1550 
1551  void setDSUParent(int parent) {
1552  DSU_parent = parent;
1553  }
1554 
1555  int getDSURank() {
1556  return DSU_rank;
1557  }
1558 
1559  void setDSURank(int rank) {
1560  DSU_rank = rank;
1561  }
1562 
1563  void increaseDSURank() {
1564  DSU_rank++;
1565  }
1566  };
1567 
1568  std::string net_name; // Name of the DF net
1569  int default_width; // Default width for the channels
1570  ErrorMgr error; // Error message
1571  int nBlocks; // Number of blocks
1572  int nChannels; // Number of channels
1573  int nPorts; // Number of ports
1574  funcID nextFree; // Next free slot in a library of functions
1575 
1576  std::vector<Block> blocks; // List of blocks
1577  std::vector<Port> ports; // List of ports
1578  std::vector<Channel> channels; // List of channels
1579 
1580  double total_freq;
1581 
1582  //double delays [250][8];
1583 
1584  int freeBlock; // Next free Block in the vector of blocks
1585  int freePort; // Next free Port in the vector of ports
1586  int freeChannel; // Next free Channel in the vector of channels
1587 
1588  //setBlocks allBlocks; // Set of blocks (for iterators)
1589  //setPorts allPorts; // Set of ports (for iterators)
1590  //setChannels allChannels; // Set of channels (for iterators)
1591 
1592  setBlocks parameters; // Set of paramenters of the dataflow netlist (entry)
1593  setBlocks results; // Set of results of the dataflow netlist (exit)
1594  blockID entryControl; // Entry block for control
1595  setBlocks exitControl; // Exit blocks
1596 
1597  //BasicBlockGraph BBG; // Graph of Basic Blocks
1598  bbID entryBB; // Entry basic block
1599 
1600  std::string milpSolver; // Name of the MILP solver
1601 
1602  std::map<std::string,blockID> name2block; // Map to obtain blocks from names
1603  std::map<std::string,portID> name2port; // Map to obtain ports from names (string = "block:port")
1604 
1605  // Maps from/to blokcs/ports to strings
1606  static std::map<BlockType,std::string> BlockType2String;
1607  static std::map<std::string,BlockType> String2BlockType;
1608  static std::map<PortType,std::string> PortType2String;
1609  static std::map<std::string,PortType> String2PortType;
1610 
1611  std::vector<blockID> DFSorder; // DFS order according to the post-visit ordering (tail is an entry node)
1612  std::vector<subNetlist> SCC; // SCCs with at least one channel (in descending order of size)
1613 
1614  std::vector<subNetlist> MG; // Extracted marked graphs in order of importance
1615  std::vector<double> MGfreq; // Execution frequency of Marked Graphs
1616 
1617  setBlocks blocks_in_MGs;
1618  setChannels channels_in_MGs;
1619 
1620  setBlocks blocks_in_borders;
1621  setChannels channels_in_borders;
1622 
1623  setBlocks blocks_in_MC_LSQ;
1624  setChannels channels_in_MC_LSQ;
1625 
1626  std::vector<subNetlist> MG_disjoint; // All marked graphs that make the disjoint sets
1627  std::vector<double> MG_disjoint_freq;
1628 
1629  std::vector<subNetlistBB> CFDFC;
1630  std::vector<double> CFDFCfreq;
1631 
1632  // SHAB_note: should be change this to a map?
1633  std::vector<subNetlistBB> CFDFC_disjoint;
1634  std::vector<double> CFDFC_disjoint_freq;
1635 
1636  std::vector<vector<int> > components; // each index corresponds to the CFDFCs the DSU_CFDFC is built of
1637 
1638  // Structure to store the MILP variables
1639  // Note: the out_retime variables are only used for pipelined units (latency > 0)
1640  struct milpVarsEB {
1641  vector<int> buffer_flop; // Elastic buffer to cut combinational paths
1642  vector<int> buffer_flop_valid; //Carmine 17.02.22 // Elastic buffer to cut combinational valid paths
1643  vector<int> buffer_flop_ready; //Carmine 17.02.22 // Elastic buffer to cut combinational ready paths
1644  vector<int> buffer_slots; // Number of slots of the elastic buffer
1645  vector<int> has_buffer; // Boolean variable to indicate whether there is a buffer
1646  vector<int> time_path; // Combinational arrival time for ports
1647  vector<int> time_valid_path; //Carmine 16.02.22 // Combinational arrival time for valid ports
1648  vector<int> time_ready_path; //Carmine 17.02.22 // Combinational arrival time for ready ports
1649  vector<int> time_elastic; // Arrival time for elasticity (longest rigid fragment)
1650  vector<vector<int>> in_retime_tokens; // Input retiming variables for tokens (indices: [MarkedGraph,block])
1651  vector<vector<int>> out_retime_tokens; // Output retiming variables for tokens (indices: [MarkedGraph,block]).
1652  vector<vector<int>> retime_bubbles; // Retiming variables for bubbles (indices: [MarkedGraph,block])
1653  vector<vector<int>> th_tokens; // Throughput associated to every channel for tokens (indices: [MargedGraph, channel])
1654  vector<vector<int>> th_bubbles; // Throughput associated to every channel for bubbles (indices: [MargedGraph, channel])
1655  vector<int> th_MG; // Throughput variables (one for each marked graph)
1656  };
1657 
1661  void init();
1662 
1666  int vecBlocksSize() const {
1667  return blocks.size();
1668  }
1669 
1673  int vecChannelsSize() const {
1674  return channels.size();
1675  }
1676 
1680  int vecPortsSize() const {
1681  return ports.size();
1682  }
1683 
1691  bool readDataflowDot(const std::string& filename);
1692 
1700  bool readDataflowDot(FILE* f);
1701 
1702  bool readDataflowDotBB(FILE *f);
1703  bool readDataflowDotBB(const std::string& filename);
1704 
1710  std::string genBlockName(BlockType type) const;
1711 
1719  bool checkPortsConnected(blockID id = invalidDataflowID);
1720 
1726  int numInPorts(blockID b) const {
1727  assert(validBlock(b));
1728  return blocks[b].inPorts.size();
1729  }
1730 
1731  int getBlockSCCno(blockID b) const {
1732  assert(validBlock(b));
1733  return blocks[b].scc_number;
1734  }
1740  int numOutPorts(blockID b) const {
1741  assert(validBlock(b));
1742  return blocks[b].outPorts.size();
1743  }
1744 
1750  portID getInPort(blockID b) const {
1751  if (blocks[b].inPorts.empty()) return invalidDataflowID;
1752  return *(blocks[b].inPorts.begin());
1753  }
1754 
1760  portID getOutPort(blockID b) const {
1761  if (blocks[b].outPorts.empty()) return invalidDataflowID;
1762  return *(blocks[b].outPorts.begin());
1763  }
1764 
1769  bool checkElasticBuffer(blockID b);
1770 
1775  bool checkFork(blockID b);
1776 
1781  bool checkBranch(blockID b);
1782 
1787  bool checkMerge(blockID b);
1788 
1793  bool checkSelect(blockID b);
1794 
1799  bool checkFunc(blockID b);
1800 
1805  bool checkConstant(blockID b);
1806 
1812  bool checkFuncEntry(blockID b);
1813 
1819  bool checkFuncExit(blockID b);
1820 
1826  bool checkDemux(blockID b);
1827 
1833  bool checkGenericPorts(blockID b);
1834 
1839  void inferChannelWidth(int default_width);
1840 
1848  bool checkSamePortWidth(portID p1, portID p2);
1849 
1856  bool checkSamePortWidth(const setPorts& P);
1857 
1866  bool checkNumPorts(blockID b, int nin, int nout);
1867 
1868  bool setAllBBFrequencies();
1869  bool determineEntryExitBlock();
1870  void computeChannelFrequencies();
1871  void computeBlockFrequencies();
1872 
1878  void writeBlockDot(std::ostream& s, blockID id);
1879 
1885  void writeChannelDot(std::ostream& s, channelID id);
1886 
1887  //SHAB_note: implement these
1888  void writeBasicBlockDot(std::ostream& s, bbID id);
1889  void writeArcDot(std::ostream& s, bbArcID id);
1890 
1895  void markAllBlocks(bool value) {
1896  ForAllBlocks(b) blocks[b].mark = value;
1897  }
1898 
1903  void markAllChannels(bool value) {
1904  ForAllChannels(c) channels[c].mark = value;
1905  }
1906 
1912  void markBlock(blockID b, bool value) {
1913  assert(validBlock(b));
1914  blocks[b].mark = value;
1915  }
1916 
1922  void setDFSorder(blockID b, int value) {
1923  assert(validBlock(b));
1924  blocks[b].DFSorder = value;
1925  }
1926 
1931  int getDFSorder(blockID b) const {
1932  assert(validBlock(b));
1933  return blocks[b].DFSorder;
1934  }
1935 
1941  void markChannel(channelID c, bool value) {
1942  assert(validChannel(c));
1943  channels[c].mark = value;
1944  }
1945 
1951  bool isBlockMarked(blockID b) const {
1952  assert(validBlock(b));
1953  return blocks[b].mark;
1954  }
1955 
1961  bool isChannelMarked(channelID c) const {
1962  assert(validChannel(c));
1963  return channels[c].mark;
1964  }
1965 
1972  void setBackEdge(channelID c, bool value = true) {
1973  assert(validChannel(c));
1974  channels[c].backEdge = value;
1975  }
1976 
1982  bool isBackEdge(channelID c) const {
1983  assert(validChannel(c));
1984  return channels[c].backEdge;
1985  }
1986 
1995  void DFS(bool forward = true, bool onlyMarked = false);
1996 
2001  void calculateBackEdges();
2002 
2010  void computeSCC(bool onlyMarked = false);
2011 
2015  const std::string& getMilpSolver() const {
2016  return milpSolver;
2017  }
2018 
2025  void createMilpVarsEB(Milp_Model& milp, milpVarsEB& vars, bool max_throughput, bool first_MG= false);
2026  void createMilpVarsEB_sc(Milp_Model& milp, milpVarsEB& vars, bool max_throughput, int mg, bool first_MG= false, string model_mode="default");
2027  void createMilpVars_remaining(Milp_Model& milp, milpVarsEB& vars, string model_mode);
2028 
2038  bool createPathConstraints(Milp_Model& milp, milpVarsEB& Vars, double Period, double BufferDelay);
2039  bool createPathConstraints_sc(Milp_Model& milp, milpVarsEB& Vars, double Period, double BufferDelay, int mg);
2040  bool createPathConstraintsOthers_sc(Milp_Model& milp, milpVarsEB& Vars, double Period, double BufferDelay, int mg, string model_mode, string lib_path);
2041  bool createPathConstraints_remaining(Milp_Model& milp, milpVarsEB& Vars, double Period, double BufferDelay);
2042  bool createPathConstraintsOthers_remaining(Milp_Model& milp, milpVarsEB& Vars, double Period, double BufferDelay, string model_mode, string lib_path);
2043 
2044 
2045  vector< pair<string, vector<double>>> read_lib_file(string lib_file_path); //Carmine 18.02.22 function to read block delays values from library
2054  bool createElasticityConstraints(Milp_Model& milp, milpVarsEB& Vars);
2055  bool createElasticityConstraints_sc(Milp_Model& milp, milpVarsEB& Vars, int mg);
2056  bool createElasticityConstraints_remaining(Milp_Model& milp, milpVarsEB& Vars);
2057 
2066  bool createThroughputConstraints(Milp_Model& milp, milpVarsEB& Vars, bool first_MG= false);
2067  bool createThroughputConstraints_sc(Milp_Model& milp, milpVarsEB& Vars, int mg, bool first_MG= false);
2068 
2069  bool channelIsInMGs(channelID c);
2070  bool blockIsInMGs(blockID b);
2071 
2072  bool channelIsInBorders(channelID c);
2073  bool blockIsInBorders(blockID b);
2074 
2075  bool channelIsInMCLSQ(channelID c);
2076  bool blockIsInMCLSQ(blockID b);
2077 
2078  bool channelIsCovered(channelID c, bool MG, bool borders, bool MC_LSQ);
2079  bool blockIsCovered(blockID b, bool MG, bool borders, bool MC_LSQ);
2085  void dumpMilpSolution(const Milp_Model& milp, const milpVarsEB& vars) const;
2086 
2087  void writeRetimingDiffs(const Milp_Model& milp, const milpVarsEB& vars);
2088 
2096  void makeNonTransparentBuffers();
2097 
2104  bool removeUnreachableBlocksAndPorts();
2105 
2110  bool removeConstantBranchSelect();
2111 
2118  bool removeOneInOneOutMergeForkDemux();
2119 
2124  bool collapseMergeFork();
2125 
2130  void makeDisjointBB(blockID b);
2131 
2137  blockID findDisjointBB(blockID b);
2138 
2146  bool unionDisjointBB(blockID b1, blockID b2);
2147 
2152  void invalidateBasicBlocks();
2153 
2161  void calculateDefinitions();
2162 
2169  subNetlist extractMarkedGraph(const map<blockID, double>& freq);
2170 
2177  subNetlistBB extractMarkedGraphBB(const map<bbID, double>& freq);
2178 
2184  subNetlist getMGfromCFDFC(subNetlistBB &BB_CFDFC);
2185 
2186  void calculateDisjointCFDFCs();
2187  int findCFDFC(int i);
2188  void unionCFDFC(int x, int y);
2189 
2190  void makeMGsfromCFDFCs();
2191 
2192 
2197  void setUnitDelays();
2198 
2199  bool removeFakeBranches();
2200 
2201 public :
2202  //added for convenience, probably remove later
2203  std::vector<Block> & getBlocks(){
2204  return blocks; // List of blocks
2205  }
2206  std::vector<Port> & getPorts(){
2207  return ports;// List of ports
2208  }
2209  std::vector<Channel> & getChannels(){
2210  return channels;// List of channels
2211  }
2212 };
2213 
2215 {
2216 public:
2217 
2222  init();
2223  }
2224 
2229  DFlib_Impl(const string& filename);
2230 
2236  bool add(const string& filename);
2237 
2244  bool writeDot(const std::string& filename = "");
2245 
2251  bool writeDot(std::ostream& s);
2252 
2257  void setError(const std::string& err) {
2258  error.set(err);
2259  }
2260 
2264  const std::string& getError() const {
2265  return error.get();
2266  }
2267 
2271  std::string& getError() {
2272  return error.get();
2273  }
2274 
2278  void clearError() {
2279  error.clear();
2280  }
2281 
2286  bool hasError() const {
2287  return error.exists();
2288  }
2289 
2293  int numFuncs() const {
2294  return nFuncs;
2295  }
2296 
2302  funcID getFuncID(const string& fname) const {
2303  auto it = name2func.find(fname);
2304  if (it == name2func.end()) return invalidDataflowID;
2305  return it->second;
2306  }
2307 
2313  DFnetlist& operator[](const string& fname) {
2314  funcID id = getFuncID(fname);
2315  assert (id != invalidDataflowID);
2316  return funcs[id];
2317  }
2318 
2324  const DFnetlist& operator[](const string& fname) const {
2325  funcID id = getFuncID(fname);
2326  assert (id != invalidDataflowID);
2327  return funcs[id];
2328  }
2329 
2335  DFnetlist& operator[](funcID id) {
2336  assert (allFuncs.count(id) > 0);
2337  return funcs[id];
2338  }
2339 
2345  const DFnetlist& operator[](funcID id) const {
2346  assert (allFuncs.count(id) > 0);
2347  return funcs[id];
2348  }
2349 
2350 private:
2351  std::string libName; // Name of the DF library
2352  ErrorMgr error; // Error manager
2353  int nFuncs; // Number of functions (DF netlists)
2354  int freeDF; // Next free slot in the vector of functions
2355 
2356  vector<DFnetlist> funcs; // Vector of functions (index corresponds to funcID)
2357  map<string, funcID> name2func; // Map from function name to funcID
2358  set<funcID> allFuncs; // Set of all valid funcID's
2359 
2363  void init();
2364 };
2365 
2366 }
2367 
2368 #endif // DATAFLOW_IMPL_H
void setExecTime(bbID bb, double t)
Sets the execution time of a BB.
Definition: DFnetlist.h:263
Definition: Dataflow.h:9
int numFuncs() const
Definition: DFnetlist.h:2293
const DFnetlist & operator[](const string &fname) const
Returns a const reference to the dataflow netlist of a function.
Definition: DFnetlist.h:2324
setBBArcs & successors(bbID bb)
Returns the set of successor arcs.
Definition: DFnetlist.h:236
bbID getEntryBasicBlock() const
Definition: DFnetlist.h:115
bool calculateBasicBlockFrequencies(double back_prob=0.9)
If the BB frequencies are already define, nothing is done. Otherwise, the BB frequencies are calculat...
Definition: DFnetlsit_BasicBlocks.cpp:346
blockID getBlockFromPort(portID p) const
Definition: DFnetlist.cpp:612
funcID getFuncID(const string &fname) const
Gets a funcID from a name function.
Definition: DFnetlist.h:2302
portID getSrcPort(channelID id) const
Returns the source port of a channel.
Definition: DFnetlist.cpp:912
int numBasicBlocks() const
Definition: DFnetlist.h:68
void clear()
Initializes the BB graph (empty).
Definition: DFnetlist.h:59
Definition: DFnetlist.h:45
Definition: DFnetlist.h:417
portID getDstPort(channelID id) const
Returns the destination port of a channel.
Definition: DFnetlist.cpp:918
DFlib_Impl()
Default constructor (empty library).
Definition: DFnetlist.h:2221
std::string & getError()
Definition: DFnetlist.h:2271
setBBArcs & predecessors(bbID bb)
Returns the set of predecessor arcs.
Definition: DFnetlist.h:227
bbID createBasicBlock()
Adds a new BB to the BB graph.
Definition: DFnetlist.h:91
Definition: Dataflow.h:83
Definition: ErrorManager.h:17
Error manager.
DFnetlist & operator[](funcID id)
Returns a reference to the dataflow netlist of a function.
Definition: DFnetlist.h:2335
bool empty() const
Definition: DFnetlist.h:82
void clearError()
Erases the error.
Definition: DFnetlist.h:2278
BasicBlockGraph()
Constructor.
Definition: DFnetlist.h:52
bool hasError() const
Indicates whether there is an error.
Definition: DFnetlist.h:2286
double getProbability(bbArcID arc) const
Returns the probability of an arc.
Definition: DFnetlist.h:184
Definition: MILP_Model.h:26
const DFnetlist & operator[](funcID id) const
Returns a const reference to the dataflow netlist of a function.
Definition: DFnetlist.h:2345
bool isBackArc(bbArcID arc) const
Checks whether an arc is forward or backward.
Definition: DFnetlist.h:218
void setFrequency(bbID bb, double f)
Sets de execution frequency of a BB.
Definition: DFnetlist.h:245
Definition: DFnetlist.h:2214
void setProbability(bbArcID arc, double prob)
Defines the probability of an arc.
Definition: DFnetlist.h:175
void setError(const std::string &err)
Sets an error message for the library.
Definition: DFnetlist.h:2257
bbID getSrcBB(bbArcID arc) const
Returns the src BB of an arc.
Definition: DFnetlist.h:157
double getExecTime(bbID bb) const
Retgurns the execution time of a BB.
Definition: DFnetlist.h:272
void setBackArc(bbArcID arc, bool back=true)
Defines whether an arc is forward or backward.
Definition: DFnetlist.h:209
DFnetlist & operator[](const string &fname)
Returns a reference to the dataflow netlist of a function.
Definition: DFnetlist.h:2313
double getFrequency(bbID bb) const
Returns the execution frequency of a BB.
Definition: DFnetlist.h:254
void setEntryBasicBlock(bbID bb)
Defines the entry BB.
Definition: DFnetlist.h:108
bbArcID findArc(bbID src, bbID dst) const
Returns the arc between two BBs.
Definition: DFnetlsit_BasicBlocks.cpp:245
int numArcs() const
Definition: DFnetlist.h:75
bbID getDstBB(bbArcID arc) const
Returns the dst BB of an arc.
Definition: DFnetlist.h:166
bool calculateBackArcs()
Calculates the back edges using a DFS traversal from the entry basic block.
Definition: DFnetlsit_BasicBlocks.cpp:267
Class to handle few utilities for files.
const std::string & getError() const
Definition: DFnetlist.h:2264
double extractBasicBlockCycles(double coverage=-1.0)
Extracts a set of Basic Block cycles that maximizes the covered execution time.
Definition: DFnetlist_BBcycles.cpp:6
bbArcID findOrAddArc(bbID src, bbID dst, double freq=0)
Creates an arc between two BBs (if it did not exist)
Definition: DFnetlsit_BasicBlocks.cpp:253