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
8 FunctionalInterface::FunctionalInterface(AbstractBlock* _owner, ReferenceInterface *_reference) throw(Exception) : ConnectedInterface(_owner) {
\r
10 if (_owner == NULL) throw(Exception(BLOCK_NULL));
\r
11 if (_reference == NULL) throw(Exception(IFACE_NULL));
\r
13 if (! _owner->isFunctionalBlock()) throw(Exception(BLOCK_INVALID_TYPE));
\r
14 if (! _reference->isReferenceInterface()) throw(Exception(IFACE_INVALID_TYPE));
\r
16 reference = _reference;
\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
29 bool FunctionalInterface::isFunctionalInterface() {
\r
33 int FunctionalInterface::getInterfaceMultiplicity() {
\r
37 FunctionalInterface* iface = NULL;
\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
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
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
66 if (ifaceCount == 0) {
\r
69 else if ( reference->getMultiplicity() == -1) {
\r
72 else if ( ifaceCount < reference->getMultiplicity()) {
\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
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
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
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
109 + if testClock is true, must test if both ifaces are in the same clock domain. Note that a group interface
\r
111 special case : clk/reset from clkrstgen can connect to stimuli clk/reset
\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
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
129 // first case: interface of blocks within the same group
\r
130 if (getOwner()->getParent() == iface->getOwner()->getParent()) {
\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
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
142 else if ((getOwner()->isStimuliBlock()) && (iface->getOwner()->isTopGroupBlock())) {
\r
143 if ((direction == Output) && (iface->getDirection() == Input) && (purpose == iface->getPurpose())) ok = true;
\r
148 int dom1 = -1,dom2 = -2;
\r
150 dom1 = getClockDomain();
\r
151 dom2 = iface->getClockDomain();
\r
153 catch(Exception e) {
\r
154 cerr << qPrintable(fctName) << " - " << qPrintable(e.getMessage()) << endl;
\r
157 if (dom1 != dom2) {
\r
158 cout << "cannot connect interface that are in different clock domains" << endl;
\r
168 bool FunctionalInterface::canConnectFrom(AbstractInterface *iface, bool testClock) {
\r
170 static QString fctName = "FunctionalInterface::canConnectFrom()";
\r
171 #ifdef DEBUG_FCTNAME
\r
172 cout << "call to " << qPrintable(fctName) << endl;
\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
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
189 special case : clk/reset of stimuli can connect from clk/reset of clkrstgen
\r
193 if (direction == Output) return false;
\r
194 if (iface->isReferenceInterface()) return false;
\r
195 if (connectedFrom != NULL) return false;
\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
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
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
216 int dom1 = -1,dom2 = -2;
\r
218 dom1 = getClockDomain();
\r
219 dom2 = iface->getClockDomain();
\r
221 catch(Exception e) {
\r
222 cerr << qPrintable(e.getMessage()) << endl;
\r
225 if (dom1 != dom2) {
\r
226 cout << "cannot connect interfaces that are in different clock domains" << endl;
\r
236 int FunctionalInterface::getClockDomain() throw(Exception) {
\r
240 FunctionalInterface* iface = NULL;
\r
241 if (clkIfaceType == ClockName) {
\r
242 iface = AI_TO_FUN(getClockIface());
\r
244 else if ((direction == Input) && (purpose == Clock)) {
\r
248 if ( iface != NULL) {
\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
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
260 idClock = domName.toInt(&ok);
\r
261 cout << "id clock = " << idClock << endl;
\r
262 if (!ok) throw(Exception(IFACE_INVALID_CLKFREQ,this));
\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
270 idClock = domName.toInt(&ok);
\r
271 if (!ok) throw(Exception(IFACE_INVALID_CLKFREQ,this));
\r
274 cout << "abnormal case while searching for clkdomain" << endl;
\r
282 void FunctionalInterface::connectionsValidation(QStack<AbstractInterface *> *interfacetoValidate, QList<AbstractInterface *> *validatedInterfaces) throw(Exception) {
\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
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
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
310 foreach(AbstractInterface *inter, getConnectedTo()){
\r
311 if((!interfacetoValidate->contains(inter)) && (!validatedInterfaces->contains(inter))){
\r
312 interfacetoValidate->push(inter);
\r
316 else if(getDirection() == AbstractInterface::InOut){
\r