X-Git-Url: https://bilbo.iut-bm.univ-fcomte.fr/and/gitweb/blast.git/blobdiff_plain/3bcfe4df6fdde086eb1b59f7a0173358170174a1..4327c2b8817b627249d98d889835726217c81a4e:/SpecialBlock.cpp?ds=inline

diff --git a/SpecialBlock.cpp b/SpecialBlock.cpp
index 2d225e2..be9452e 100644
--- a/SpecialBlock.cpp
+++ b/SpecialBlock.cpp
@@ -1,18 +1,31 @@
 #include "SpecialBlock.h"
+#include "FunctionalInterface.h"
 
-SpecialBlock::SpecialBlock(SpecialType _type, GroupBlock* _parent, ReferenceBlock* _reference, bool createIfaces) throw(Exception) : FunctionalBlock(_parent, _reference, createIfaces) {
-  type = _type;  
+SpecialBlock::SpecialBlock(Graph *_graph, int _type, GroupBlock* _parent, ReferenceBlock* _reference, bool createIfaces) throw(Exception) : FunctionalBlock(_graph, _parent, _reference, createIfaces) {
+  specialType = _type;
 }
 
 SpecialBlock::~SpecialBlock() {
 }
 
+bool SpecialBlock::isSpecialBlock() {
+  return true;
+}
+
 void SpecialBlock::checkInputPatternCompatibility() throw(Exception) {
   try {
-    switch(type) {
-    case ClockConvert :
+    switch(specialType) {
+    case Source :
+      checkInputPatternCompatibilitySource();
+      break;
+    case Sink :
+      checkInputPatternCompatibilitySink();
+      break;
+    case ClkConvert :
       checkInputPatternCompatibilityClockConvert();
-      break;    
+      break;
+    default:
+      break;
     }
   }
   catch(Exception e) {
@@ -22,10 +35,18 @@ void SpecialBlock::checkInputPatternCompatibility() throw(Exception) {
 
 void SpecialBlock::computeOutputPattern(int nbExec) throw(Exception) {
   try {
-    switch(type) {
-    case ClockConvert :
+    switch(specialType) {
+    case Source :
+      computeOutputPatternSource(nbExec);
+      break;
+    case Sink :
+      computeOutputPatternSink(nbExec);
+      break;
+    case ClkConvert :
       computeOutputPatternClockConvert(nbExec);
       break;    
+    default:
+      break;
     }
   }
   catch(Exception e) {
@@ -33,9 +54,112 @@ void SpecialBlock::computeOutputPattern(int nbExec) throw(Exception) {
   }
 }
 
+void SpecialBlock::checkInputPatternCompatibilitySource() throw(Exception) {
+}
+void SpecialBlock::computeOutputPatternSource(int nbExec) throw(Exception) {
+
+  cout << "computing output pattern of special block " << qPrintable(name) << " for " << nbExec << " executions" << endl;
+  foreach(AbstractInterface* iface, getControlOutputs()) {
+    FunctionalInterface* connIface = AI_TO_FUN(iface);
+    // create output pattern
+    QList<char>* pp = productionPattern.value(connIface);
+    QList<char>* pattern = new QList<char>(*pp);
+    for(int i=1;i<nbExec;i++) pattern->append(*pp);
+    // assign pattern to interface
+    connIface->setOutputPattern(pattern);
+    // store it in QMap
+    outputPattern.insert(connIface,pattern);    
+  }
+  setOutputPatternComputed(true);
+}
+
+void SpecialBlock::checkInputPatternCompatibilitySink() throw(Exception) {
+}
+void SpecialBlock::computeOutputPatternSink(int nbExec) throw(Exception) {
+}
+
 void SpecialBlock::checkInputPatternCompatibilityClockConvert() throw(Exception) {
+  static QString fctName = "SpecialBlock::checkInputPatternCompatibilityClockConvert()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
+  // just create input pattern
+  try {
+    createInputPattern();
+  }
+  catch(Exception e) {
+    throw(e);
+  }
 }
+
 void SpecialBlock::computeOutputPatternClockConvert(int nbExec) throw(Exception) {
+  static QString fctName = "SpecialBlock::computeOutputPatternClockConvert()";
+#ifdef DEBUG_FCTNAME
+  cout << "call to " << qPrintable(fctName) << endl;
+#endif
+  cout << "computing output pattern of special block " << qPrintable(name) << endl;
+
+  /* CAUTION: it is assumed that all clock domain converters are using
+   * a clk_in and clk_out signals for input and output clocks.
+   */
+  AbstractInterface* clkIn = getIfaceFromName("clk_in");
+  AbstractInterface* clkOut = getIfaceFromName("clk_out");
+  cout << "freq clk_in = " << clkIn->getClockFrequency() << endl;
+  cout << "freq clk_out = " << clkOut->getClockFrequency() << endl;  
+  double periodIn = 1000.0/clkIn->getClockFrequency();
+  double periodOut = 1000.0/clkOut->getClockFrequency();
+  cout << "period clk_in = " << periodIn << endl;
+  cout << "period clk_out = " << periodOut << endl;
+  // starts with 1 data in FIFO
+  int latency = 1+(int)((periodIn+5.0*periodOut)/periodOut);
+  QList<char> pattern;
+  for(int i=0;i<latency;i++) {
+    pattern.append(0);
+  }
+  int inFifo = 1;
+  int idIn = 1;
+  int idOut = 1;
+  while (idIn < lengthIP) {
+    double tIn = (double)idIn * periodIn;
+    double tOut = (double)idOut * periodOut;
+    if (fabs(tIn-tOut) < 0.001) {
+      if (inFifo > 0) {
+        pattern.append(1);
+      }
+      else {
+        pattern.append(0);
+        inFifo ++;
+      }
+      idIn ++;
+      idOut ++;
+    }
+    else if (tIn < tOut) {
+      inFifo++;
+      idIn ++;
+    }
+    else {
+      if (inFifo > 0) {
+        pattern.append(1);
+        inFifo--;
+      }
+      else {
+        pattern.append(0);
+      }
+      idOut++;
+    }
+  }
+  foreach(char c, pattern) cout << (int)c;
+  cout << endl;
+
+  // initialize the output pattern
+  lengthOP = pattern.size();
+  foreach(AbstractInterface* iface, getControlOutputs()) {
+    FunctionalInterface* connIface = AI_TO_FUN(iface);    
+    QList<char>* pat = new QList<char>(pattern);
+    connIface->setOutputPattern(pat);
+    outputPattern.insert(connIface,pat);
+  }
+  cout << "output pattern computed" << endl;
 }