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

Private GIT Repository
clkconvert OP compute done
[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 }\r
26 \r
27 bool FunctionalInterface::isFunctionalInterface() {\r
28   return true;\r
29 }\r
30 \r
31 int FunctionalInterface::getInterfaceMultiplicity() {\r
32 \r
33   int i=0;\r
34   int ifaceCount = 0;\r
35   FunctionalInterface* iface = NULL;\r
36 \r
37   if (direction == AbstractInterface::Input) {\r
38     QList<AbstractInterface *> inputs = owner->getInputs();\r
39     for(i=0;i<inputs.size();i++) {\r
40       iface = AI_TO_FUN(inputs.at(i));\r
41       if (iface->getReference() == reference) {\r
42         ifaceCount += 1;\r
43       }\r
44     }\r
45   }\r
46   else if (direction == AbstractInterface::Output) {\r
47     QList<AbstractInterface *> outputs = owner->getOutputs();\r
48     for(i=0;i<outputs.size();i++) {\r
49       iface = AI_TO_FUN(outputs.at(i));\r
50       if (iface->getReference() == reference) {\r
51         ifaceCount += 1;\r
52       }\r
53     }\r
54   }\r
55   else if (direction == AbstractInterface::InOut) {\r
56     QList<AbstractInterface *> bidirs = owner->getBidirs();\r
57     for(i=0;i<bidirs.size();i++) {\r
58       iface = AI_TO_FUN(bidirs.at(i));\r
59       if (iface->getReference() == reference) {\r
60         ifaceCount += 1;\r
61       }\r
62     }\r
63   }\r
64   if (ifaceCount == 0) {\r
65     return -1;\r
66   }\r
67   else if ( reference->getMultiplicity() == -1) {\r
68     return ifaceCount;\r
69   }\r
70   else if ( ifaceCount < reference->getMultiplicity()) {\r
71     return ifaceCount;\r
72   }\r
73   return -1;\r
74 }\r
75 \r
76 AbstractInterface *FunctionalInterface::clone() { \r
77   int id = getInterfaceMultiplicity();\r
78   if (id < 0) return NULL;\r
79   FunctionalInterface *inter = new FunctionalInterface(owner, reference);\r
80   inter->setWidth(width);  \r
81   inter->setName(reference->getName()+"_"+QString::number(id+1));\r
82   return inter;\r
83 }\r
84 \r
85 bool FunctionalInterface::canConnectTo(AbstractInterface *iface) {\r
86 \r
87   /* NOTE :\r
88      necessary conditions :\r
89         - this is an output or in/out interface\r
90         - iface type must be functional or group interface\r
91         - iface->connectedFrom must be NULL\r
92 \r
93      valid "normal" cases:\r
94      1 - iface is owned by a block (group or func) that is within the same group as the block that own this\r
95         1.1 - this is output and iface is input\r
96         1.2 - both are inout\r
97      2 - iface is owned by the parent group of the block that owns this\r
98         2.1 - this is an output, iface is an output of the group\r
99         2.2 - both are inout\r
100      3 - this is owned by a source block and iface is owned by the top group\r
101 \r
102      special case : clk/reset from clkrstgen can connect to stimuli clk/reset\r
103 \r
104   */\r
105   if (direction == Input) return false;\r
106   if (iface->isReferenceInterface()) return false;\r
107   ConnectedInterface* connIface = AI_TO_CON(iface);\r
108   if (connIface->getConnectedFrom() != NULL) return false;\r
109   // special case\r
110   if ((getOwner()->getName().startsWith("clkrstgen")) && (iface->getOwner()->isStimuliBlock())) {\r
111     if ((direction == Output) && (iface->getDirection() == Input)) {\r
112       if ((purpose == AbstractInterface::Clock) && (iface->getPurpose() == AbstractInterface::Clock)) return true;\r
113       else if ((purpose == AbstractInterface::Reset) && (iface->getPurpose() == AbstractInterface::Reset)) return true;\r
114     }\r
115   }\r
116 \r
117   // first case: interface of blocks within the same group\r
118   if (getOwner()->getParent() == iface->getOwner()->getParent()) {\r
119 \r
120     if ((direction == Output) && (iface->getDirection() == Input) && (purpose == iface->getPurpose())) return true;\r
121     if ((direction == InOut) && (iface->getDirection() == InOut) && (purpose == iface->getPurpose())) return true;\r
122   }\r
123   // second case: iface = interface of the group that contains owner of this\r
124   else if (getOwner()->getParent() == iface->getOwner()) {\r
125     if ((direction == Output) && (iface->getDirection() == Output) && (purpose == iface->getPurpose())) return true;\r
126     if ((direction == InOut) && (iface->getDirection() == InOut) && (purpose == iface->getPurpose())) return true;\r
127   }\r
128   else if ((getOwner()->isStimuliBlock()) && (iface->getOwner()->isTopGroupBlock())) {\r
129     if ((direction == Output) && (iface->getDirection() == Input) && (purpose == iface->getPurpose())) return true;\r
130   }\r
131 \r
132   return false;\r
133 \r
134 }\r
135 \r
136 bool FunctionalInterface::canConnectFrom(AbstractInterface *iface) {\r
137 \r
138   /* NOTE :\r
139      necessary conditions :\r
140         - this is an input or in/out interface\r
141         - iface type must be functional or group interface\r
142         - this connectedFrom must be NULL\r
143 \r
144      valid cases:\r
145      1 - iface is owned by a block (group or func) that is within the same group as the block that own this\r
146         1.1 - this is input and iface is output\r
147         1.2 - both are inout\r
148      2 - iface is owned by the parent group of the block that owns this\r
149         2.1 - this is an input, iface is an input of the group\r
150         2.2 - both are inout\r
151 \r
152      special case : clk/reset of stimuli can connect from clk/reset of clkrstgen\r
153   */\r
154   if (direction == Output) return false;\r
155   if (iface->isReferenceInterface()) return false;\r
156   if (connectedFrom != NULL) return false;\r
157 \r
158   // special case\r
159   if ((iface->getOwner()->getName().startsWith("clkrstgen")) && (getOwner()->isStimuliBlock())) {\r
160     if ((direction == Input) && (iface->getDirection() == Output)) {\r
161       if ((purpose == AbstractInterface::Clock) && (iface->getPurpose() == AbstractInterface::Clock)) return true;\r
162       else if ((purpose == AbstractInterface::Reset) && (iface->getPurpose() == AbstractInterface::Reset)) return true;\r
163     }\r
164   }\r
165 \r
166   if (getOwner()->getParent() == iface->getOwner()->getParent()) {\r
167 \r
168     if ((direction == Input) && (iface->getDirection() == Output) && (purpose == iface->getPurpose())) return true;\r
169     if ((direction == InOut) && (iface->getDirection() == InOut) && (purpose == iface->getPurpose())) return true;\r
170   }\r
171   else if (getOwner()->getParent() == iface->getOwner()) {\r
172     if ((direction == Input) && (iface->getDirection() == Input) && (purpose == iface->getPurpose())) return true;\r
173     if ((direction == InOut) && (iface->getDirection() == InOut) && (purpose == iface->getPurpose())) return true;\r
174   }\r
175 \r
176   return false;\r
177 }\r
178 \r
179 int FunctionalInterface::getClockDomain() throw(Exception) {\r
180 \r
181   int idClock = -1;\r
182 \r
183   FunctionalInterface* iface = NULL;\r
184   if (clkIfaceType == ClockName) {\r
185     iface = AI_TO_FUN(getClockIface());\r
186   }\r
187   else if ((direction == Input) && (purpose == Clock)) {\r
188     iface = this;\r
189   }\r
190 \r
191   if ( iface != NULL) {\r
192 \r
193     // if iface is a functional interface, it is connected to clkrstgen_X (in top group) or to ext_clk_X (in subgroup)\r
194     ConnectedInterface* connFrom = iface->getConnectedFrom();\r
195     if (connFrom == NULL) throw(Exception(IFACE_INVALID_CLKFREQ,this));\r
196 \r
197     if (connFrom->getOwner()->isFunctionalBlock()) {\r
198       QString name = connFrom->getOwner()->getName();\r
199       cout << "conn from clkrstgen: searching for clkdomain in " << qPrintable(name) << endl;\r
200       name.remove(0,10);\r
201       bool ok;\r
202       idClock = name.toInt(&ok);\r
203       if (!ok) throw(Exception(IFACE_INVALID_CLKFREQ,this));\r
204     }\r
205     else {\r
206       QString name = connFrom->getName();\r
207       cout << "conn from group: searching for clkdomain in " << qPrintable(name) << endl;\r
208       name.remove(0,8);\r
209       bool ok;\r
210       idClock = name.toInt(&ok);\r
211       if (!ok) throw(Exception(IFACE_INVALID_CLKFREQ,this));\r
212     }\r
213   }\r
214 \r
215   return idClock;\r
216 }\r
217 \r
218 \r
219 void FunctionalInterface::connectionsValidation(QStack<AbstractInterface *> *interfacetoValidate, QList<AbstractInterface *> *validatedInterfaces) throw(Exception) {\r
220 \r
221   /*\r
222   //inputs interfaces\r
223   double widthInput, widthOutput;\r
224   if(getDirection() == AbstractInterface::Input){\r
225     widthInput = getDoubleWidth();\r
226     widthOutput = getConnectedFrom()->getDoubleWidth();\r
227     if(widthInput != widthOutput){\r
228       throw new Exception(WIDTHS_NOT_EQUALS);\r
229     }\r
230     foreach(AbstractInterface *inter, getOwner()->getOutputs()){\r
231       if(inter->isConnectedTo()){\r
232         if((!interfacetoValidate->contains(inter)) && (!validatedInterfaces->contains(inter))){\r
233           interfacetoValidate->push(inter);\r
234         }\r
235       }\r
236     }\r
237   }\r
238   //outputs interfaces\r
239   else if(getDirection() == AbstractInterface::Output){\r
240     widthOutput = getDoubleWidth();\r
241     foreach(AbstractInterface *inter, getConnectedTo()){\r
242       widthInput = inter->getDoubleWidth();\r
243       if(widthInput != widthOutput){\r
244         throw new Exception(WIDTHS_NOT_EQUALS);\r
245       }\r
246     }\r
247     foreach(AbstractInterface *inter, getConnectedTo()){\r
248       if((!interfacetoValidate->contains(inter)) && (!validatedInterfaces->contains(inter))){\r
249         interfacetoValidate->push(inter);\r
250       }\r
251     }\r
252   }\r
253   else if(getDirection() == AbstractInterface::InOut){\r
254 \r
255   }\r
256 \r
257   */\r
258 }\r