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

Private GIT Repository
finished testbench generation
[blast.git] / GroupInterface.cpp
1 #include "GroupInterface.h"
2 #include "FunctionalInterface.h"
3 #include "GroupBlock.h"
4
5 GroupInterface::GroupInterface(AbstractBlock* _owner, const QString& _name, int _direction, int _purpose) throw(Exception) : ConnectedInterface(_owner,_name,_direction,_purpose,"inherited","") {
6   if (! _owner->isGroupBlock()) throw(Exception(BLOCK_INVALID_TYPE));
7
8   connectedFrom = NULL;
9   // force clock and reset to boolean width type instead of inherited
10   if ((purpose == Clock) || (purpose == Reset)) {
11     type = Boolean;
12   }
13   clkIfaceType = InheritedName;
14 }
15
16 bool GroupInterface::isGroupInterface() {
17   return true;
18 }
19
20 AbstractInterface *GroupInterface::clone() {
21     GroupInterface *inter = new GroupInterface(owner,name,direction, purpose);
22     inter->setWidth(width);        
23     return inter;
24 }
25
26 int GroupInterface::getWidth() {
27
28   bool ok;
29   int w = -1;
30
31   QString expr = width;
32
33   if (type == Boolean) {
34     return 1;
35   }
36   else if (type == Inherited) {
37     // must search from which iface it is connected.
38     ConnectedInterface* fromIface = connectedFrom;
39     while ((fromIface != NULL) && (fromIface->getType() == Inherited)) {
40       fromIface = fromIface->getConnectedFrom();
41     }
42     if (fromIface == NULL) return -1;
43     w = fromIface->getWidth();
44   }
45   return w;
46 }
47
48 bool GroupInterface::canConnectTo(AbstractInterface *iface, bool testClock) {
49
50   /* NOTE :
51      necessary conditions :
52         - iface type must be functional or group interface
53         - iface->connectedFrom must be NULL
54
55      valid cases:
56      1 - this is owned by the parent group of the block (group or func) that owns iface
57         1.1 - this is input and iface is input
58         1.2 - both are inout
59      2 - this is owned by a group that has the same parent as the block (group or func) that owns iface
60         2.1 - this is an output, iface is an input of the group
61         2.2 - both are inout
62      3 - this is owned by a group and iface by its parent group
63         2.1 - this is an output, iface is an output of the group
64         2.2 - both are inout
65      
66       NB: testClock is useless since a group interface has always a clkIfaceType inherited.
67       Thus, it is always possible
68
69   */
70   bool ok = false;
71
72   if (iface->isReferenceInterface()) return false;
73   ConnectedInterface* connIface = AI_TO_CON(iface);
74   if (connIface->getConnectedFrom() != NULL) return false;
75
76   if (this->getOwner() == iface->getOwner()->getParent()) {
77     if ((direction == Input) && (iface->getDirection() == Input) && (purpose == iface->getPurpose())) ok = true;
78     if ((direction == InOut) && (iface->getDirection() == InOut) && (purpose == iface->getPurpose())) ok = true;
79
80   }
81   else if (this->getOwner()->getParent() == iface->getOwner()->getParent()) {
82     if ((direction == Output) && (iface->getDirection() == Input) && (purpose == iface->getPurpose())) ok = true;
83     if ((direction == InOut) && (iface->getDirection() == InOut) && (purpose == iface->getPurpose())) ok = true;
84   }
85   else if (this->getOwner()->getParent() == iface->getOwner()) {
86     if ((direction == Output) && (iface->getDirection() == Output) && (purpose == iface->getPurpose())) ok = true;
87     if ((direction == InOut) && (iface->getDirection() == InOut) && (purpose == iface->getPurpose())) ok = true;
88   }
89   
90   if (ok) {
91     if (testClock) {
92       int dom1 = -1,dom2 = -2;
93       try {
94         dom1 = getClockDomain();
95         dom2 = iface->getClockDomain();
96       }
97       catch(Exception e) {
98         cerr << qPrintable(e.getMessage()) << endl;
99         return false;
100       }
101       if (dom1 != dom2) {
102         cout << "cannot connect interface that are in different clock domains" << endl;
103         return false;
104       }
105     }
106     return true;
107   }
108
109   return false;
110 }
111
112 bool GroupInterface::canConnectFrom(AbstractInterface *iface, bool testClock) {
113
114   /* NOTE :
115      necessary conditions :
116         - iface type must be functional or group interface
117         - this->connectedFrom must be NULL
118
119      valid cases:
120      1 - this is owned by the parent group of the block (group or func) that owns iface
121         1.1 - this is output and iface is output
122         1.2 - both are inout
123      2 - this is owned by a group that has the same parent as the block (group or func) that owns iface
124         2.1 - this is an input, iface is an output of the group
125         2.2 - both are inout
126      3 - this is owned by a group and iface by its parent group
127         2.1 - this is an input, iface is an input of the group
128         2.2 - both are inout
129      4 - this is owned by top group and iface is an output of a source block           
130   */
131   bool ok = false;
132
133   if (iface->isReferenceInterface()) return false;
134   if (getConnectedFrom() != NULL) return false;
135
136   if (this->getOwner() == iface->getOwner()->getParent()) {
137     if ((direction == Output) && (iface->getDirection() == Output) && (purpose == iface->getPurpose())) ok = true;
138     if ((direction == InOut) && (iface->getDirection() == InOut) && (purpose == iface->getPurpose())) ok = true;
139
140   }
141   else if (this->getOwner()->getParent() == iface->getOwner()->getParent()) {
142     if ((direction == Input) && (iface->getDirection() == Output) && (purpose == iface->getPurpose())) ok = true;
143     if ((direction == InOut) && (iface->getDirection() == InOut) && (purpose == iface->getPurpose())) ok = true;
144   }
145   else if (this->getOwner()->getParent() == iface->getOwner()) {
146     if ((direction == Input) && (iface->getDirection() == Input) && (purpose == iface->getPurpose())) ok = true;
147     if ((direction == InOut) && (iface->getDirection() == InOut) && (purpose == iface->getPurpose())) ok = true;
148   }
149   else if ((getOwner()->isTopGroupBlock()) && (iface->getOwner()->isStimuliBlock())) {
150     if ((direction == Input) && (iface->getDirection() == Output) && (purpose == iface->getPurpose())) ok = true;
151   }
152
153   if (ok) {
154     if (testClock) {
155       int dom1 = -1,dom2 = -2;
156       try {
157         dom1 = getClockDomain();
158         dom2 = iface->getClockDomain();
159       }
160       catch(Exception e) {
161         cerr << qPrintable(e.getMessage()) << endl;
162         return false;
163       }
164       if (dom1 != dom2) {
165         cout << "cannot connect interface that are in different clock domains" << endl;
166         return false;
167       }
168     }
169     return true;
170   }
171
172   return false;
173 }
174
175 int GroupInterface::getClockDomain() throw(Exception) {
176
177   /* For clk/rst interfaces, the clock domain can be deduced
178      from the interface name.
179      Otherwise, we can search backward/forward for a functional
180      interface. Since a group interface cannot exist if it is not
181      connected to and/or from a functional interface (either directly
182      or through a sequence of subgroups) there is at least such a functional
183      interface.
184    */
185   int idClock = -1;
186   if ((purpose == Clock) || (purpose == Reset)) {
187     QString domName = name;
188     domName.remove(0,8);
189     bool ok;
190     idClock = domName.toInt(&ok);
191     if (!ok) throw(Exception(IFACE_INVALID_CLKFREQ,this));
192   }
193   else {
194     // start by searching backward
195     ConnectedInterface* connFrom = connectedFrom;
196     while ((connFrom != NULL) && (connFrom->isGroupInterface())) {
197       connFrom = connFrom->getConnectedFrom();
198     }
199     if (connFrom != NULL) {
200       idClock = connFrom->getClockDomain();
201     }
202     //searching forward
203     else {
204       QList<ConnectedInterface*> lstIfaces = getForwardFunctionalInterfaces(this);
205       if (lstIfaces.isEmpty()) throw(Exception(IFACE_INVALID_CLKFREQ,this));
206       foreach(ConnectedInterface* iface, lstIfaces) {
207         // test if all ifaces are in the same clock domain
208         if (idClock == -1) {
209           idClock = iface->getClockDomain();
210         }
211         else if (idClock != iface->getClockDomain()) throw(Exception(IFACE_INVALID_CLKFREQ,this));
212       }
213     }
214   }
215
216   return idClock;
217 }
218
219 QList<ConnectedInterface*> GroupInterface::getForwardFunctionalInterfaces(GroupInterface* groupIface) {
220   QList<ConnectedInterface*> lstIfaces;
221   foreach(ConnectedInterface* iface, groupIface->getConnectedTo()) {
222     if (iface->isFunctionalInterface()) {
223       lstIfaces.append(iface);
224     }
225     else if (iface->isGroupInterface()) {
226       lstIfaces.append(getForwardFunctionalInterfaces(AI_TO_GRP(iface)));
227     }
228   }
229   return lstIfaces;
230 }
231
232 void GroupInterface::connectionsValidation(QStack<AbstractInterface*> *interfacetoValidate, QList<AbstractInterface*> *validatedInterfaces) throw(Exception) {
233     cout << "group interface connection validation" << endl;
234 }