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

Private GIT Repository
808dbda2f18486c8e247651e4290cea3fdebd109
[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(this, 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(this, 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     cout << "Graph: create special block from " << qPrintable(ref->getName()) << endl;
51     newBlock = new SpecialBlock(this, ref->getSpecialType(), group,ref, createIfaces);
52   }
53   else {
54     cout << "Graph: create normal block from " << qPrintable(ref->getName()) << endl;
55     newBlock = new FunctionalBlock(this, group,ref, createIfaces);
56   }
57   group->addBlock(newBlock);
58
59   return newBlock;
60 }
61
62 FunctionalBlock* Graph::duplicateFunctionalBlock(FunctionalBlock *block) {
63
64   ReferenceBlock* ref = block->getReference();
65   GroupBlock* group = AB_TO_GRP(block->getParent());
66
67   // adding to the graph
68   FunctionalBlock* newBlock = createFunctionalBlock(group,ref, true);
69   return newBlock;
70 }
71
72
73 bool Graph::removeFunctionalBlock(FunctionalBlock* block) {
74   GroupBlock* group = AB_TO_GRP(block->getParent());
75   group->removeBlock(block);
76   return true;
77 }
78
79 FunctionalBlock* Graph::getFunctionalBlockByName(QString name, GroupBlock* parent) {
80   FunctionalBlock* block = NULL;
81   if (parent != NULL) {
82     block = AB_TO_FUN(parent->getFunctionalBlockByName(name));
83   }
84   else {
85     foreach(GroupBlock* group, groups) {
86       block = AB_TO_FUN(group->getFunctionalBlockByName(name));
87       if (block != NULL) return block;
88     }
89   }
90   return block;
91 }
92
93 FunctionalBlock* Graph::createStimuliBlock(ReferenceBlock* ref, bool createIfaces) {
94   /* A stimuli block is always a special block with idSpecial = 1 */
95
96   FunctionalBlock* newBlock = new SpecialBlock(this, AbstractBlock::Source, NULL,ref, createIfaces);
97   stimulis.append(newBlock);
98   return newBlock;
99 }
100
101 FunctionalBlock* Graph::duplicateStimuliBlock(FunctionalBlock *block) {
102
103   ReferenceBlock* ref = block->getReference();  
104
105   // adding to the graph
106   FunctionalBlock* newBlock = createStimuliBlock(ref, true);
107   return newBlock;
108 }
109
110 FunctionalBlock* Graph::getStimuliBlockByName(QString name) {
111   foreach(FunctionalBlock* block, stimulis) {
112     if (block->getName() == name) return block;
113   }
114   return NULL;
115 }
116
117 bool Graph::removeStimuliBlock(FunctionalBlock *block) {
118   stimulis.removeAll(block);
119   return true;
120 }
121
122 void Graph::createPatterns() throw(Exception) {
123   
124   foreach(AbstractBlock* block, stimulis) {
125     FunctionalBlock* funBlock = AB_TO_FUN(block);
126     try {
127       funBlock->createPatterns();
128     }
129     catch(Exception e) {
130       throw(e);      
131     }
132   }
133   
134   foreach(AbstractBlock* block, groups) {
135     GroupBlock* group = AB_TO_GRP(block);    
136     foreach(AbstractBlock* inBlock, group->getBlocks()) {
137       if (inBlock->isFunctionalBlock()) {
138         FunctionalBlock* funBlock = AB_TO_FUN(inBlock);
139         try {
140           funBlock->createPatterns();
141         }
142         catch(Exception e) {
143           throw(e);
144         }
145       }
146     }
147   }  
148 }
149
150 void Graph::resetPatternComputed() {
151   foreach(AbstractBlock* block, stimulis) {
152     block->setOutputPatternComputed(false);
153     block->resetTraversalLevel();
154   }
155   foreach(AbstractBlock* block, groups) {
156     GroupBlock* group = AB_TO_GRP(block);
157     group->setOutputPatternComputed(false);
158     block->resetTraversalLevel();
159     foreach(AbstractBlock* inBlock, group->getBlocks()) {
160       inBlock->setOutputPatternComputed(false);
161       block->resetTraversalLevel();
162     }
163   }
164 }
165
166 void Graph::computeOutputPatterns(int nbExec) throw(Exception) {
167   
168   try {
169     createPatterns();
170   }
171   catch(Exception e) {
172     throw(e);    
173   }
174
175   resetPatternComputed();
176   // search for all block that are source.
177   QList<FunctionalBlock*> sources;
178   sources.append(stimulis);
179   foreach(AbstractBlock* block, groups) {    
180     GroupBlock* group = AB_TO_GRP(block);    
181     foreach(AbstractBlock* inBlock, group->getBlocks()) {
182       FunctionalBlock* funBlock = AB_TO_FUN(inBlock);
183       if (inBlock->isSourceBlock()) {
184         sources.append(funBlock);
185       }
186     }    
187   }
188   // search for maximum PP length
189   int maxPP = 0;
190   foreach(FunctionalBlock* block, sources) {
191     if (block->getProductionPatternLength() > maxPP) maxPP = block->getProductionPatternLength();
192   }
193   // compute output for generators
194   int maxExecLen = maxPP*nbExec;
195   foreach(FunctionalBlock* block, sources) {
196     int d = block->getProductionPatternLength();
197     block->computeOutputPattern((maxExecLen+d-1)/d);
198   }
199   // compute output for top group
200   try {
201     topGroup->computeOutputPattern();
202   }
203   catch(Exception e) {
204     throw(e);
205   }
206 }
207
208 void Graph::generateVHDL(const QString &path) throw(Exception) {
209   try {
210     topGroup->generateVHDL(path);
211   }
212   catch(Exception e) {
213     throw(e);
214   }
215 }
216
217 QList<QString> Graph::getExternalResources() {
218   QList<QString> list = topGroup->getExternalResources();
219   return list;
220 }