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

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