]> AND Private Git Repository - blast.git/blob - Graph.cpp
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
moved clocks list to graph
[blast.git] / Graph.cpp
1 #include "Graph.h"
2 #include "GroupBlock.h"
3 #include "ReferenceBlock.h"
4 #include "FunctionalBlock.h"
5 #include "SpecialBlock.h"
6
7 Graph::Graph() {
8   topGroup = NULL;
9 }
10
11 Graph::~Graph() {
12   
13   delete topGroup;
14 }
15
16 void Graph::createTopGroup(bool createTopGroupIfaces) {
17   topGroup = new GroupBlock(NULL, createTopGroupIfaces);
18   topGroup->setName("top group");
19   groups.append(topGroup);
20 }
21
22 QList<AbstractInterface *> Graph::getOutsideInterfaces() {
23   return topGroup->getInterfaces();
24 }
25
26 GroupBlock* Graph::createChildGroupBlock(GroupBlock* parent, bool createGroupIface) {
27   GroupBlock* b = new GroupBlock(parent, createGroupIface);
28   groups.append(b);
29   return b;
30 }
31
32 void Graph::removeGroupBlock(GroupBlock *group) {
33   group->removeAllBlocks();
34   GroupBlock* parent = AB_TO_GRP(group->getParent());
35   parent->removeBlock(group);
36   groups.removeAll(group);
37 }
38
39 GroupBlock* Graph::getGroupBlockByName(QString name) {
40   foreach(GroupBlock* group, groups) {
41     if (group->getName() == name) return group;
42   }
43   return NULL;
44 }
45
46 FunctionalBlock* Graph::createFunctionalBlock(GroupBlock* group, ReferenceBlock* ref, bool createIfaces) {
47
48   FunctionalBlock* newBlock = NULL;
49   if (ref->getSpecialType() != -1) {
50     newBlock = new SpecialBlock(ref->getSpecialType(), group,ref, createIfaces);
51   }
52   else {
53     newBlock = new FunctionalBlock(group,ref, createIfaces);
54   }
55   group->addBlock(newBlock);
56
57   return newBlock;
58 }
59
60 FunctionalBlock* Graph::duplicateFunctionalBlock(FunctionalBlock *block) {
61
62   ReferenceBlock* ref = block->getReference();
63   GroupBlock* group = AB_TO_GRP(block->getParent());
64
65   // adding to the graph
66   FunctionalBlock* newBlock = createFunctionalBlock(group,ref, true);
67   return newBlock;
68 }
69
70
71 bool Graph::removeFunctionalBlock(FunctionalBlock* block) {
72   GroupBlock* group = AB_TO_GRP(block->getParent());
73   group->removeBlock(block);
74   return true;
75 }
76
77 FunctionalBlock* Graph::getFunctionalBlockByName(QString name, GroupBlock* parent) {
78   FunctionalBlock* block = NULL;
79   if (parent != NULL) {
80     block = AB_TO_FUN(parent->getFunctionalBlockByName(name));
81   }
82   else {
83     foreach(GroupBlock* group, groups) {
84       block = AB_TO_FUN(group->getFunctionalBlockByName(name));
85       if (block != NULL) return block;
86     }
87   }
88   return block;
89 }
90
91 FunctionalBlock* Graph::createStimuliBlock(ReferenceBlock* ref, bool createIfaces) {
92   /* A stimuli block is always a special block with idSpecial = 1 */
93
94   FunctionalBlock* newBlock = new SpecialBlock(AbstractBlock::Source, NULL,ref, createIfaces);
95   stimulis.append(newBlock);
96   return newBlock;
97 }
98
99 FunctionalBlock* Graph::duplicateStimuliBlock(FunctionalBlock *block) {
100
101   ReferenceBlock* ref = block->getReference();  
102
103   // adding to the graph
104   FunctionalBlock* newBlock = createStimuliBlock(ref, true);
105   return newBlock;
106 }
107
108 FunctionalBlock* Graph::getStimuliBlockByName(QString name) {
109   foreach(FunctionalBlock* block, stimulis) {
110     if (block->getName() == name) return block;
111   }
112   return NULL;
113 }
114
115 bool Graph::removeStimuliBlock(FunctionalBlock *block) {
116   stimulis.removeAll(block);
117   return true;
118 }
119
120 void Graph::createPatterns() throw(Exception) {
121   
122   foreach(AbstractBlock* block, stimulis) {
123     FunctionalBlock* funBlock = AB_TO_FUN(block);
124     try {
125       funBlock->createPatterns();
126     }
127     catch(Exception e) {
128       throw(e);      
129     }
130   }
131   
132   foreach(AbstractBlock* block, groups) {
133     GroupBlock* group = AB_TO_GRP(block);    
134     foreach(AbstractBlock* inBlock, group->getBlocks()) {
135       if (inBlock->isFunctionalBlock()) {
136         FunctionalBlock* funBlock = AB_TO_FUN(inBlock);
137         try {
138           funBlock->createPatterns();
139         }
140         catch(Exception e) {
141           throw(e);
142         }
143       }
144     }
145   }  
146 }
147
148 void Graph::resetPatternComputed() {
149   foreach(AbstractBlock* block, stimulis) {
150     block->setOutputPatternComputed(false);
151     block->resetTraversalLevel();
152   }
153   foreach(AbstractBlock* block, groups) {
154     GroupBlock* group = AB_TO_GRP(block);
155     group->setOutputPatternComputed(false);
156     block->resetTraversalLevel();
157     foreach(AbstractBlock* inBlock, group->getBlocks()) {
158       inBlock->setOutputPatternComputed(false);
159       block->resetTraversalLevel();
160     }
161   }
162 }
163
164 void Graph::computeOutputPatterns(int nbExec) throw(Exception) {
165   
166   try {
167     createPatterns();
168   }
169   catch(Exception e) {
170     throw(e);    
171   }
172
173   resetPatternComputed();
174   // search for all block that are source.
175   QList<FunctionalBlock*> sources;
176   sources.append(stimulis);
177   foreach(AbstractBlock* block, groups) {    
178     GroupBlock* group = AB_TO_GRP(block);    
179     foreach(AbstractBlock* inBlock, group->getBlocks()) {
180       FunctionalBlock* funBlock = AB_TO_FUN(inBlock);
181       if (inBlock->isSourceBlock()) {
182         sources.append(funBlock);
183       }
184     }    
185   }
186   // search for maximum PP length
187   int maxPP = 0;
188   foreach(FunctionalBlock* block, sources) {
189     if (block->getProductionPatternLength() > maxPP) maxPP = block->getProductionPatternLength();
190   }
191   // compute output for generators
192   int maxExecLen = maxPP*nbExec;
193   foreach(FunctionalBlock* block, sources) {
194     int d = block->getProductionPatternLength();
195     block->computeOutputPattern((maxExecLen+d-1)/d);
196   }
197   // compute output for top group
198   try {
199     topGroup->computeOutputPattern();
200   }
201   catch(Exception e) {
202     throw(e);
203   }
204 }
205
206 void Graph::generateVHDL(const QString &path) throw(Exception) {
207   try {
208     topGroup->generateVHDL(path);
209   }
210   catch(Exception e) {
211     throw(e);
212   }
213 }
214
215 QList<QString> Graph::getExternalResources() {
216   QList<QString> list = topGroup->getExternalResources();
217   return list;
218 }