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

Private GIT Repository
finished testbench generation
[blast.git] / FunctionalInterface.cpp
1 #include "ArithmeticEvaluator.h"\r
2 #include "FunctionalInterface.h"\r
3 #include "ReferenceInterface.h"\r
4 #include "GroupInterface.h"\r
5 #include "FunctionalBlock.h"\r
6 #include "GroupBlock.h"\r
7 \r
8 FunctionalInterface::FunctionalInterface(AbstractBlock* _owner, ReferenceInterface *_reference) throw(Exception) : ConnectedInterface(_owner) {\r
9 \r
10   if (_owner == NULL) throw(Exception(BLOCK_NULL));\r
11   if (_reference == NULL) throw(Exception(IFACE_NULL));\r
12 \r
13   if (! _owner->isFunctionalBlock()) throw(Exception(BLOCK_INVALID_TYPE));\r
14   if (! _reference->isReferenceInterface()) throw(Exception(IFACE_INVALID_TYPE));\r
15 \r
16   reference = _reference;\r
17 \r
18   name = reference->getName();\r
19   type = reference->getType();\r
20   endianess = reference->getEndianess();\r
21   width = reference->getWidthString();\r
22   direction = reference->getDirection();\r
23   purpose = reference->getPurpose();  \r
24   connectedFrom = NULL;\r
25   clkIfaceName = reference->getClockIfaceString();\r
26   clkIfaceType = reference->getClockIfaceType();\r
27 }\r
28 \r
29 bool FunctionalInterface::isFunctionalInterface() {\r
30   return true;\r
31 }\r
32 \r
33 int FunctionalInterface::getInterfaceMultiplicity() {\r
34 \r
35   int i=0;\r
36   int ifaceCount = 0;\r
37   FunctionalInterface* iface = NULL;\r
38 \r
39   if (direction == AbstractInterface::Input) {\r
40     QList<AbstractInterface *> inputs = owner->getInputs();\r
41     for(i=0;i<inputs.size();i++) {\r
42       iface = AI_TO_FUN(inputs.at(i));\r
43       if (iface->getReference() == reference) {\r
44         ifaceCount += 1;\r
45       }\r
46     }\r
47   }\r
48   else if (direction == AbstractInterface::Output) {\r
49     QList<AbstractInterface *> outputs = owner->getOutputs();\r
50     for(i=0;i<outputs.size();i++) {\r
51       iface = AI_TO_FUN(outputs.at(i));\r
52       if (iface->getReference() == reference) {\r
53         ifaceCount += 1;\r
54       }\r
55     }\r
56   }\r
57   else if (direction == AbstractInterface::InOut) {\r
58     QList<AbstractInterface *> bidirs = owner->getBidirs();\r
59     for(i=0;i<bidirs.size();i++) {\r
60       iface = AI_TO_FUN(bidirs.at(i));\r
61       if (iface->getReference() == reference) {\r
62         ifaceCount += 1;\r
63       }\r
64     }\r
65   }\r
66   if (ifaceCount == 0) {\r
67     return -1;\r
68   }\r
69   else if ( reference->getMultiplicity() == -1) {\r
70     return ifaceCount;\r
71   }\r
72   else if ( ifaceCount < reference->getMultiplicity()) {\r
73     return ifaceCount;\r
74   }\r
75   return -1;\r
76 }\r
77 \r
78 AbstractInterface *FunctionalInterface::clone() { \r
79   int id = getInterfaceMultiplicity();\r
80   if (id < 0) return NULL;\r
81   FunctionalInterface *inter = new FunctionalInterface(owner, reference);\r
82   inter->setWidth(width);  \r
83   inter->setName(reference->getName()+"_"+QString::number(id+1));\r
84   return inter;\r
85 }\r
86 \r
87 bool FunctionalInterface::canConnectTo(AbstractInterface *iface, bool testClock) {\r
88   static QString fctName = "FunctionalInterface::canConnectTo()";\r
89 #ifdef DEBUG_FCTNAME\r
90   cout << "call to " << qPrintable(fctName) << endl;\r
91 #endif\r
92 \r
93 \r
94   /* NOTE :\r
95      necessary conditions :\r
96         - this is an output or in/out interface\r
97         - iface type must be functional or group interface\r
98         - iface->connectedFrom must be NULL\r
99 \r
100      valid "normal" cases:\r
101      1 - iface is owned by a block (group or func) that is within the same group as the block that own this\r
102         1.1 - this is output and iface is input\r
103         1.2 - both are inout\r
104      2 - iface is owned by the parent group of the block that owns this\r
105         2.1 - this is an output, iface is an output of the group\r
106         2.2 - both are inout\r
107      3 - this is owned by a source block and iface is owned by the top group\r
108 \r
109      + if testClock is true, must test if both ifaces are in the same clock domain. Note that a group interface\r
110      has always\r
111      special case : clk/reset from clkrstgen can connect to stimuli clk/reset\r
112 \r
113   */\r
114   bool ok = false;\r
115 \r
116   if (direction == Input) return false;\r
117   if (iface->isReferenceInterface()) return false;\r
118   ConnectedInterface* connIface = AI_TO_CON(iface);\r
119   if (connIface->getConnectedFrom() != NULL) return false;\r
120 \r
121   // special case, NB: never tests clocks\r
122   if ((getOwner()->getName().startsWith("clkrstgen")) && (iface->getOwner()->isStimuliBlock())) {\r
123     if ((direction == Output) && (iface->getDirection() == Input)) {\r
124       if ((purpose == AbstractInterface::Clock) && (iface->getPurpose() == AbstractInterface::Clock)) return true;\r
125       else if ((purpose == AbstractInterface::Reset) && (iface->getPurpose() == AbstractInterface::Reset)) return true;\r
126     }\r
127   }\r
128 \r
129   // first case: interface of blocks within the same group\r
130   if (getOwner()->getParent() == iface->getOwner()->getParent()) {\r
131 \r
132 \r
133 \r
134     if ((direction == Output) && (iface->getDirection() == Input) && (purpose == iface->getPurpose())) ok = true;\r
135     if ((direction == InOut) && (iface->getDirection() == InOut) && (purpose == iface->getPurpose())) ok = true;\r
136   }\r
137   // second case: iface = interface of the group that contains owner of this\r
138   else if (getOwner()->getParent() == iface->getOwner()) {\r
139     if ((direction == Output) && (iface->getDirection() == Output) && (purpose == iface->getPurpose())) ok = true;\r
140     if ((direction == InOut) && (iface->getDirection() == InOut) && (purpose == iface->getPurpose())) ok = true;\r
141   }\r
142   else if ((getOwner()->isStimuliBlock()) && (iface->getOwner()->isTopGroupBlock())) {\r
143     if ((direction == Output) && (iface->getDirection() == Input) && (purpose == iface->getPurpose())) ok = true;\r
144   }\r
145 \r
146   if (ok) {\r
147     if (testClock) {\r
148       int dom1 = -1,dom2 = -2;\r
149       try {\r
150         dom1 = getClockDomain();\r
151         dom2 = iface->getClockDomain();\r
152       }\r
153       catch(Exception e) {\r
154         cerr << qPrintable(fctName) << " - " << qPrintable(e.getMessage()) << endl;\r
155         return false;\r
156       }\r
157       if (dom1 != dom2) {\r
158         cout << "cannot connect interface that are in different clock domains" << endl;\r
159         return false;\r
160       }\r
161     }\r
162     return true;\r
163   }\r
164   return false;\r
165 \r
166 }\r
167 \r
168 bool FunctionalInterface::canConnectFrom(AbstractInterface *iface, bool testClock) {\r
169 \r
170   static QString fctName = "FunctionalInterface::canConnectFrom()";\r
171 #ifdef DEBUG_FCTNAME\r
172   cout << "call to " << qPrintable(fctName) << endl;\r
173 #endif\r
174 \r
175   /* NOTE :\r
176      necessary conditions :\r
177         - this is an input or in/out interface\r
178         - iface type must be functional or group interface\r
179         - this connectedFrom must be NULL\r
180 \r
181      valid cases:\r
182      1 - iface is owned by a block (group or func) that is within the same group as the block that own this\r
183         1.1 - this is input and iface is output\r
184         1.2 - both are inout\r
185      2 - iface is owned by the parent group of the block that owns this\r
186         2.1 - this is an input, iface is an input of the group\r
187         2.2 - both are inout\r
188 \r
189      special case : clk/reset of stimuli can connect from clk/reset of clkrstgen\r
190   */\r
191   bool ok = false;\r
192 \r
193   if (direction == Output) return false;\r
194   if (iface->isReferenceInterface()) return false;\r
195   if (connectedFrom != NULL) return false;\r
196 \r
197   // special case, NB: never tests clock\r
198   if ((iface->getOwner()->getName().startsWith("clkrstgen")) && (getOwner()->isStimuliBlock())) {\r
199     if ((direction == Input) && (iface->getDirection() == Output)) {\r
200       if ((purpose == AbstractInterface::Clock) && (iface->getPurpose() == AbstractInterface::Clock)) return true;\r
201       else if ((purpose == AbstractInterface::Reset) && (iface->getPurpose() == AbstractInterface::Reset)) return true;\r
202     }\r
203   }\r
204 \r
205   if (getOwner()->getParent() == iface->getOwner()->getParent()) {    \r
206     if ((direction == Input) && (iface->getDirection() == Output) && (purpose == iface->getPurpose())) ok = true;\r
207     if ((direction == InOut) && (iface->getDirection() == InOut) && (purpose == iface->getPurpose())) ok = true;\r
208   }\r
209   else if (getOwner()->getParent() == iface->getOwner()) {\r
210     if ((direction == Input) && (iface->getDirection() == Input) && (purpose == iface->getPurpose())) ok = true;\r
211     if ((direction == InOut) && (iface->getDirection() == InOut) && (purpose == iface->getPurpose())) ok = true;\r
212   }\r
213 \r
214   if (ok) {\r
215     if (testClock) {\r
216       int dom1 = -1,dom2 = -2;\r
217       try {\r
218         dom1 = getClockDomain();\r
219         dom2 = iface->getClockDomain();\r
220       }\r
221       catch(Exception e) {\r
222         cerr << qPrintable(e.getMessage()) << endl;\r
223         return false;\r
224       }\r
225       if (dom1 != dom2) {\r
226         cout << "cannot connect interfaces that are in different clock domains" << endl;\r
227         return false;\r
228       }\r
229     }\r
230     return true;\r
231   }\r
232 \r
233   return false;\r
234 }\r
235 \r
236 int FunctionalInterface::getClockDomain() throw(Exception) {\r
237 \r
238   int idClock = -1;\r
239 \r
240   FunctionalInterface* iface = NULL;\r
241   if (clkIfaceType == ClockName) {\r
242     iface = AI_TO_FUN(getClockIface());\r
243   }\r
244   else if ((direction == Input) && (purpose == Clock)) {\r
245     iface = this;\r
246   }\r
247 \r
248   if ( iface != NULL) {\r
249 \r
250     // if iface is a functional interface, it is connected to clkrstgen_X (in top group) or to ext_clk_X (in subgroup)\r
251     ConnectedInterface* connFrom = iface->getConnectedFrom();\r
252     if (connFrom == NULL) throw(Exception(IFACE_INVALID_CLKFREQ,this));\r
253 \r
254     if (connFrom->getOwner()->isFunctionalBlock()) {\r
255       QString domName = connFrom->getOwner()->getName();\r
256       domName.remove(0,10);\r
257       cout << "conn from clkrstgen: searching for clkdomain in " << qPrintable(domName) << endl;\r
258 \r
259       bool ok = true;\r
260       idClock = domName.toInt(&ok);\r
261       cout << "id clock = " << idClock << endl;\r
262       if (!ok) throw(Exception(IFACE_INVALID_CLKFREQ,this));\r
263     }\r
264     else if (connFrom->getOwner()->isGroupBlock()) {\r
265       QString domName = connFrom->getName();\r
266       domName.remove(0,8);\r
267       cout << "conn from group: searching for clkdomain in " << qPrintable(domName) << endl;\r
268 \r
269       bool ok = true;\r
270       idClock = domName.toInt(&ok);\r
271       if (!ok) throw(Exception(IFACE_INVALID_CLKFREQ,this));\r
272     }\r
273     else {\r
274       cout << "abnormal case while searching for clkdomain" << endl;\r
275     }\r
276   }\r
277 \r
278   return idClock;\r
279 }\r
280 \r
281 \r
282 void FunctionalInterface::connectionsValidation(QStack<AbstractInterface *> *interfacetoValidate, QList<AbstractInterface *> *validatedInterfaces) throw(Exception) {\r
283 \r
284   /*\r
285   //inputs interfaces\r
286   double widthInput, widthOutput;\r
287   if(getDirection() == AbstractInterface::Input){\r
288     widthInput = getDoubleWidth();\r
289     widthOutput = getConnectedFrom()->getDoubleWidth();\r
290     if(widthInput != widthOutput){\r
291       throw new Exception(WIDTHS_NOT_EQUALS);\r
292     }\r
293     foreach(AbstractInterface *inter, getOwner()->getOutputs()){\r
294       if(inter->isConnectedTo()){\r
295         if((!interfacetoValidate->contains(inter)) && (!validatedInterfaces->contains(inter))){\r
296           interfacetoValidate->push(inter);\r
297         }\r
298       }\r
299     }\r
300   }\r
301   //outputs interfaces\r
302   else if(getDirection() == AbstractInterface::Output){\r
303     widthOutput = getDoubleWidth();\r
304     foreach(AbstractInterface *inter, getConnectedTo()){\r
305       widthInput = inter->getDoubleWidth();\r
306       if(widthInput != widthOutput){\r
307         throw new Exception(WIDTHS_NOT_EQUALS);\r
308       }\r
309     }\r
310     foreach(AbstractInterface *inter, getConnectedTo()){\r
311       if((!interfacetoValidate->contains(inter)) && (!validatedInterfaces->contains(inter))){\r
312         interfacetoValidate->push(inter);\r
313       }\r
314     }\r
315   }\r
316   else if(getDirection() == AbstractInterface::InOut){\r
317 \r
318   }\r
319 \r
320   */\r
321 }\r