From 60c13e8b4c7ea3d595969c1e7c0a28b068a17ca6 Mon Sep 17 00:00:00 2001 From: stephane Domas Date: Thu, 3 May 2018 17:24:36 +0200 Subject: [PATCH] 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 getParameters() { return params; } + inline QList getInputs() { return inputs; } inline QList getOutputs() { return outputs; } inline QList getBidirs() { return bidirs; } + QList getInterfaces(int direction = AbstractInterface::AnyDirection, int purpose = AbstractInterface::AnyPurpose); + QList getDataInputs(); //! return all inputs of type data + QList getDataOutputs(); //! return all inputs of type data + QList getControlInputs(); //! return all inputs of type control + QList getControlOutputs(); //! return all outputs of type control + AbstractInterface* getIfaceFromName(QString name); + + inline QList getParameters() { return params; } + BlockParameter* getParameterFromName(QString name); QList getUserParameters(); QList getGenericParameters(); QList getPortParameters(); QList 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 getInterfaces(int direction = AbstractInterface::AnyDirection, int purpose = AbstractInterface::AnyPurpose); - QList getDataInputs(); //! return all inputs of type data - QList getDataOutputs(); //! return all inputs of type data - QList getControlInputs(); //! return all inputs of type control - QList 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* pattern = new QList(); + for(int i=0;iappend(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 @@ - + EnvironmentId 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 <= not empty; -read_fifo : process(@{clk_rd}, @{reset}) +read_fifo : process(@{clk_out}, @{reset}) begin if @{reset} = '1' then @{data_out_enb} <= '0'; -elsif rising_edge(@{clk_rd}) then +elsif rising_edge(@{clk_out}) then @{data_out_enb} <= '0'; if empty = '0' then @{data_out_enb} <= '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 @@ - + 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 @@ - - + + - + - + -- 2.39.5