From 60c13e8b4c7ea3d595969c1e7c0a28b068a17ca6 Mon Sep 17 00:00:00 2001
From: stephane Domas <stephane.domas@univ-fcomte.fr>
Date: Thu, 3 May 2018 17:24:36 +0200
Subject: [PATCH 1/1] started to code clkconvert output gen

---
 AbstractBlock.h                               | 19 +++---
 AbstractInterface.h                           |  3 +-
 Parameters.cpp                                | 66 +++++++++++++++++++
 Parameters.h                                  |  5 +-
 SpecialBlock.cpp                              | 53 +++++++++++++++
 blast.creator.user                            |  2 +-
 .../clkdomain_convert_1024x8_impl.xml         |  8 +--
 lib/references/apf27-wb-master.xml            |  2 +-
 lib/references/clkdomain_convert_1024x8.xml   |  8 +--
 9 files changed, 143 insertions(+), 23 deletions(-)

diff --git a/AbstractBlock.h b/AbstractBlock.h
index e1c33e4..8f09410 100644
--- a/AbstractBlock.h
+++ b/AbstractBlock.h
@@ -35,14 +35,24 @@ public:
   inline int getSpecialType() { return specialType; }
   inline QString getVersion() { return version; }
   inline int nbParameters() { return params.size(); }
-  inline QList<BlockParameter *> getParameters() { return params; }
+
   inline QList<AbstractInterface*> getInputs() { return inputs; }
   inline QList<AbstractInterface*> getOutputs() { return outputs; }
   inline QList<AbstractInterface*> getBidirs() { return bidirs; }  
+  QList<AbstractInterface *> getInterfaces(int direction = AbstractInterface::AnyDirection, int purpose = AbstractInterface::AnyPurpose);
+  QList<AbstractInterface *> getDataInputs(); //! return all inputs of type data
+  QList<AbstractInterface *> getDataOutputs(); //! return all inputs of type data
+  QList<AbstractInterface *> getControlInputs(); //! return all inputs of type control
+  QList<AbstractInterface *> getControlOutputs(); //! return all outputs of type control
+  AbstractInterface* getIfaceFromName(QString name);
+
+  inline QList<BlockParameter *> getParameters() { return params; }
+  BlockParameter* getParameterFromName(QString name);
   QList<BlockParameter *> getUserParameters();
   QList<BlockParameter *> getGenericParameters();
   QList<BlockParameter *> getPortParameters();
   QList<BlockParameter *> getWishboneParameters();
+
   inline AbstractBlock* getParent() { return parent; }
   inline bool getOutputPatternComputed() { return outputPatternComputed; }
   inline int getTraversalLevel() { return traversalLevel; }
@@ -90,13 +100,6 @@ public:
   void removeAllInterfaces();
   void defineBlockParam(BlockParameter *param);
 
-  QList<AbstractInterface *> getInterfaces(int direction = AbstractInterface::AnyDirection, int purpose = AbstractInterface::AnyPurpose);
-  QList<AbstractInterface *> getDataInputs(); //! return all inputs of type data
-  QList<AbstractInterface *> getDataOutputs(); //! return all inputs of type data
-  QList<AbstractInterface *> getControlInputs(); //! return all inputs of type control
-  QList<AbstractInterface *> getControlOutputs(); //! return all outputs of type control
-  AbstractInterface* getIfaceFromName(QString name);
-  BlockParameter* getParameterFromName(QString name);
 
   // patterns
   virtual void checkInputPatternCompatibility() throw(Exception) = 0;
diff --git a/AbstractInterface.h b/AbstractInterface.h
index 95ad4bb..8a509fb 100644
--- a/AbstractInterface.h
+++ b/AbstractInterface.h
@@ -56,8 +56,7 @@ public :
   inline AbstractInterface* getAssociatedIface() { return associatedIface; }
   inline QString getClockIfaceString() { return clkIface; }
   inline int getClockIfaceType() { return clkIfaceType; }
-  AbstractInterface* getClockIface();
-
+  AbstractInterface* getClockIface();  
 
   double getDoubleWidth() throw(QException);
   
diff --git a/Parameters.cpp b/Parameters.cpp
index 98ea7eb..1195f51 100644
--- a/Parameters.cpp
+++ b/Parameters.cpp
@@ -95,6 +95,72 @@ ReferenceBlock* Parameters::getHiddenReferenceBlock(QString blockName) {
   return ref;
 }
 
+double Parameters::getFeedingClockFrequency(AbstractInterface *iface) {
+
+  int idClock = 0;
+
+  if (iface->isReferenceInterface()) return 0.0;
+
+  if (iface->getClockIfaceType() == AbstractInterface::ParameterName) {
+    BlockParameter* param = iface->getOwner()->getParameterFromName(iface->getClockIfaceString());
+    if (!param->isUserParameter()) return 0.0;
+    bool ok;
+    double freq = param->getDoubleValue(&ok);
+    if (!ok) {
+      cerr << "Abnormal case: cannot retrieve clock id from parameter  " << qPrintable(param->getName()) << endl;
+    }
+    return freq;
+  }
+  else if ( (iface->getClockIfaceType() == AbstractInterface::ClockName) || ((iface->getDirection() == AbstractInterface::Input) && (iface->getPurpose() == AbstractInterface::Clock))) {
+
+    // if iface is not clock, retrieve the clock related to it
+    if (iface->getClockIfaceType() == AbstractInterface::ClockName) {
+      iface = iface->getClockIface();
+    }
+    // if iface is a group interface, then iface name is ext_clk_X, thus extract the X
+    if (iface->isGroupInterface()) {
+      QString name = iface->getName();
+      name.remove(0,8);
+      bool ok;
+      idClock = name.toInt(&ok);
+      if (!ok) {
+        cerr << "Abnormal case: cannot retrieve clock id from iface name " << qPrintable(iface->getName()) << endl;
+        return 0.0;
+      }
+    }
+    // if iface is a functional interface, it is connected to clkrstgen_X (in top group) or to ext_clk_X (in subgroup)
+    else if (iface->isFunctionalInterface()) {
+      FunctionalInterface* funIface = AI_TO_FUN(iface);
+      ConnectedInterface* connFrom = funIface->getConnectedFrom();
+      if (connFrom == NULL) {
+        cerr << "Abnormal case: input clock " << qPrintable(iface->getName()) << " is not connected" << endl;
+        return 0.0;
+      }
+      if (iface->getOwner()->isTopGroupBlock()) {
+        QString name = connFrom->getOwner()->getName();
+        name.remove(0,10);
+        bool ok;
+        idClock = name.toInt(&ok);
+        if (!ok) {
+          cerr << "Abnormal case: cannot retrieve clock id for " << qPrintable(iface->getName()) << endl;
+          return 0.0;
+        }
+      }
+      else {
+        QString name = connFrom->getName();
+        name.remove(0,8);
+        bool ok;
+        idClock = name.toInt(&ok);
+        if (!ok) {
+          cerr << "Abnormal case: cannot retrieve clock id for " << qPrintable(iface->getName()) << endl;
+          return 0.0;
+        }
+      }
+    }
+  }
+  return clocks.at(idClock);
+}
+
 void Parameters::createDelayBlock() {
   delayRef = new ReferenceBlock("no.xml");
   delayRef->addCategory(100);
diff --git a/Parameters.h b/Parameters.h
index a541ee6..bf679fc 100644
--- a/Parameters.h
+++ b/Parameters.h
@@ -145,9 +145,8 @@ public :
   void destroyGraph();
   inline Graph* getGraph() { return graph; }  
   ReferenceBlock* getReferenceBlock(int idCategory, int idBlock); // get the reference block from its category and index
-  ReferenceBlock* getHiddenReferenceBlock(QString blockName); // get a hidden block by name, i.e. in category 100
-  FunctionalBlock* duplicateFunctionalBlock(FunctionalBlock* block); // adding a copy of a functional block to current group
-
+  ReferenceBlock* getHiddenReferenceBlock(QString blockName); // get a hidden block by name, i.e. in category 100  
+  double getFeedingClockFrequency(AbstractInterface* iface); // determine at which freq. is synchronized iface
 
   void clear();
 
diff --git a/SpecialBlock.cpp b/SpecialBlock.cpp
index 8c7cc10..8f2271d 100644
--- a/SpecialBlock.cpp
+++ b/SpecialBlock.cpp
@@ -79,8 +79,61 @@ 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 " << 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-
+
+  // in case of inputPattern not created, do it
+  if (lengthIP <= 0) {
+
+    cout << "Strange case: input pattern is not created while it is time to compute output pattern !" << endl;
+    // collect the input patterns for each input
+    try {
+      createInputPattern();
+    }
+    catch(Exception e) {
+      throw(e);
+    }
+    cout << "input pattern array initialized with min. len " << lengthIP << endl;
+  }
+
+  // initialize the output pattern
+  lengthOP = 0;
+  foreach(AbstractInterface* iface, getControlOutputs()) {
+    FunctionalInterface* connIface = AI_TO_FUN(iface);
+    lengthOP = lengthIP+productionPattern.value(connIface)->size();
+    QList<char>* pattern = new QList<char>();
+    for(int i=0;i<lengthOP;i++) pattern->append(0);
+    connIface->setOutputPattern(pattern);
+    outputPattern.insert(connIface,pattern);
+  }
+  cout << "output pattern array initialized" << endl;
+
+  int clock = 0;
+
 }
 
 
diff --git a/blast.creator.user b/blast.creator.user
index eb750a8..b2e76dd 100644
--- a/blast.creator.user
+++ b/blast.creator.user
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE QtCreatorProject>
-<!-- Written by QtCreator 4.2.0, 2018-05-03T15:15:26. -->
+<!-- Written by QtCreator 4.2.0, 2018-05-03T17:24:00. -->
 <qtcreator>
  <data>
   <variable>EnvironmentId</variable>
diff --git a/lib/implementations/clkdomain_convert_1024x8_impl.xml b/lib/implementations/clkdomain_convert_1024x8_impl.xml
index f5c5ead..6046ebe 100644
--- a/lib/implementations/clkdomain_convert_1024x8_impl.xml
+++ b/lib/implementations/clkdomain_convert_1024x8_impl.xml
@@ -37,8 +37,8 @@ begin
 clkdconvert_1024x8_1 : clkdconvert_1024x8
 port map (
 rst => @{reset},
-wr_clk => @{clk_wr},
-rd_clk => @{clk_rd},
+wr_clk => @{clk_in},
+rd_clk => @{clk_out},
 din => @{data_in},
 wr_en => @{data_in_enb},
 rd_en => rd_en,
@@ -49,11 +49,11 @@ empty => empty
 
 rd_en &lt;= not empty;
 
-read_fifo : process(@{clk_rd}, @{reset})
+read_fifo : process(@{clk_out}, @{reset})
 begin
 if @{reset} = '1' then
 @{data_out_enb} &lt;= '0';
-elsif rising_edge(@{clk_rd}) then
+elsif rising_edge(@{clk_out}) then
 @{data_out_enb} &lt;= '0';
 if empty = '0' then
 @{data_out_enb} &lt;= '1';
diff --git a/lib/references/apf27-wb-master.xml b/lib/references/apf27-wb-master.xml
index 83a8a04..781914c 100644
--- a/lib/references/apf27-wb-master.xml
+++ b/lib/references/apf27-wb-master.xml
@@ -11,7 +11,7 @@
   </informations>
 
   <parameters>
-    <parameter name="imx_clk" type="positive" value="133" context="user"/>
+    <parameter name="imx_clk" type="real" value="133" context="user"/>
   </parameters>
 
   <interfaces>
diff --git a/lib/references/clkdomain_convert_1024x8.xml b/lib/references/clkdomain_convert_1024x8.xml
index b980f69..b6e19c4 100644
--- a/lib/references/clkdomain_convert_1024x8.xml
+++ b/lib/references/clkdomain_convert_1024x8.xml
@@ -13,14 +13,14 @@
   </parameters>
   <interfaces>
     <inputs>
-      <input width="1" multiplicity="1" endian="little" type="boolean" name="clk_rd" purpose="clock"/>
-      <input width="1" multiplicity="1" endian="little" type="boolean" name="clk_wr" purpose="clock"/>
+      <input width="1" multiplicity="1" endian="little" type="boolean" name="clk_in" purpose="clock"/>
+      <input width="1" multiplicity="1" endian="little" type="boolean" name="clk_out" purpose="clock"/>
       <input width="1" multiplicity="1" endian="little" type="boolean" name="reset" purpose="reset"/>
-      <input width="8" multiplicity="1" endian="little" type="natural" name="data_in" purpose="data" clock="clk_rd"/>
+      <input width="8" multiplicity="1" endian="little" type="natural" name="data_in" purpose="data" clock="clk_in"/>
       <control iface="data_in"/>
     </inputs>
     <outputs>
-      <output width="8" multiplicity="1" endian="little" type="natural" name="data_out" purpose="data" clock="clk_wr"/>
+      <output width="8" multiplicity="1" endian="little" type="natural" name="data_out" purpose="data" clock="clk_out"/>
       <control iface="data_out"/>
     </outputs>
   </interfaces>
-- 
2.39.5