From: stephane Domas Date: Thu, 29 Mar 2018 15:20:07 +0000 (+0200) Subject: started VHDL generation of GroupBlock X-Git-Url: https://bilbo.iut-bm.univ-fcomte.fr/and/gitweb/blast.git/commitdiff_plain/6e2b3026c6a496e81642c373796bd39dad33d2a6?ds=sidebyside started VHDL generation of GroupBlock --- diff --git a/AbstractBlock.cpp b/AbstractBlock.cpp index b78a1e1..3bb808e 100644 --- a/AbstractBlock.cpp +++ b/AbstractBlock.cpp @@ -285,9 +285,30 @@ void AbstractBlock::connectClkReset() throw(Exception) { fromClk->connectTo(toClk); fromRst->connectTo(toRst); } +} +void AbstractBlock::generateEntity(QTextStream& out, bool hasController) throw(Exception) { + out << "entity " << name << " is" << endl; + try { + generateEntityOrComponentBody(out, 0, hasController); + } + catch(Exception e) { + throw(e); + } + out << "end entity " << name << ";" << endl << endl; } +void AbstractBlock::generateComponent(QTextStream& out, bool hasController) throw(Exception) { + + out << " component " << name << " is" << endl; + try { + generateEntityOrComponentBody(out, 2, hasController); + } + catch(Exception e) { + throw(e); + } + out << " end component " << endl << endl; +} diff --git a/AbstractBlock.h b/AbstractBlock.h index 37cd35a..5f2acb5 100644 --- a/AbstractBlock.h +++ b/AbstractBlock.h @@ -21,6 +21,8 @@ class AbstractBlock { public: + enum BlockVHDLContext {AnyContext = 0, Entity = 1, Component = 2, Architecture = 3 }; // NB : 3 is when creating an instance of the block that owns this iface + AbstractBlock(); //AbstractBlock(const QString& _name); virtual ~AbstractBlock(); @@ -57,10 +59,11 @@ public: bool isWBConfigurable(); // others - void connectClkReset() throw(Exception); + void connectClkReset() throw(Exception); virtual void generateVHDL(const QString& path) throw(Exception) = 0; // main entry to generate the VHDL code - + void generateComponent(QTextStream& out, bool hasController=false) throw(Exception); // generate the component using reference + void generateEntity(QTextStream& out, bool hasController=false) throw(Exception); // generate the entity using reference virtual void parametersValidation(QList* checkedBlocks, QList* blocksToConfigure) = 0; // ugly but usefull @@ -106,10 +109,10 @@ protected: AbstractBlock* parent; virtual void generateComments(QTextStream& out, QDomElement &elt, QString coreFile) throw(Exception) = 0; // generates comments from element - virtual void generateLibraries(QTextStream& out, QDomElement &elt) throw(Exception) = 0; // generates libraries from element - virtual void generateEntity(QTextStream& out, bool hasController=false) throw(Exception) = 0; // generate the entity using reference + virtual void generateLibraries(QTextStream& out, QDomElement &elt) throw(Exception) = 0; // generates libraries from element virtual void generateArchitecture(QTextStream& out, QDomElement &elt ) throw(Exception) = 0; // generate the architecture using element virtual void generateController(QTextStream& out) throw(Exception) = 0; // generate the wishbone controller of the block + virtual void generateEntityOrComponentBody(QTextStream& out, int indentLevel, bool hasController=false) throw(Exception) = 0; // generate the entity/compo body using reference }; diff --git a/AbstractInterface.cpp b/AbstractInterface.cpp index a32f78e..6c51907 100644 --- a/AbstractInterface.cpp +++ b/AbstractInterface.cpp @@ -59,6 +59,79 @@ bool AbstractInterface::isGroupInterface() { return false; } +int AbstractInterface::getWidth() { + + bool ok; + int w = -1; + + QString expr = width; + + /* CAUTION : + + Since VHDL allows to write std_logic_vector(O downto 0) + which is different from std_logic, we have to differentiate + a size of 1 that is really a boolean and thus a std_logic, from + a std_logic_vector of size 1. + + For this reason, if it is boolean, 0 is returned instead of 1. + */ + if (type == Boolean) { + return 0; + } + else if (type == Natural) { + w = width.toInt(&ok); + if (!ok) return -1; + } + else if (type == Expression) { + + QList listGenerics = owner->getGenericParameters(); + QList listUsers = owner->getUserParameters(); + QList listPorts = owner->getPortParameters(); + + foreach(BlockParameter* p, listUsers) { + QString var = "$"; + var += p->getName(); + if (width.contains(var)) { + int tmp = p->getValue().toInt(&ok); + if (!ok) return -1; // user parameter cannot be converted to an int + expr.replace(var,p->getValue().toString()); + } + } + foreach(BlockParameter* p, listPorts) { + QString var = "$"; + var += p->getName(); + if (width.contains(var)) { + expr.replace(var,p->toVHDL(0,0)); + } + } + foreach(BlockParameter* p, listGenerics) { + QString var = "$"; + var += p->getName(); + if (width.contains(var)) { + int tmp = p->getValue().toInt(&ok); + if (!ok) return -1; + QString s=""; + s.setNum(tmp); + expr.replace(var,s); + } + } + // now evaluate the whole expression + ArithmeticEvaluator evaluator; + + try { + evaluator.setVariableMarkers("$"); + evaluator.setExpression(expr); + w = (int)(evaluator.evaluate()); + cout << "iface size :" << w << endl; + } + catch(int e) { + cerr << "invalid expression in size of interface " << qPrintable(name) << " at character " << e << endl; + w = -1; + } + } + return w; +} + QString AbstractInterface::getEndianessString() { QString str="unknown"; switch(endianess){ @@ -191,6 +264,9 @@ QString AbstractInterface::getTypeString() { else if (type == Expression) { return "expression"; } + else if (type == Inherited) { + return "inherited"; + } return "invalid_type"; } @@ -217,83 +293,130 @@ QString AbstractInterface::toVHDL(int context, int flags) throw(Exception) { if (isReferenceInterface()) throw(Exception(IFACE_INVALID_TYPE)); - QString msb = width; + int w; + QString wStr = ""; QString ret=""; - bool ok; - cout << "iface " << qPrintable(name) << " must be evaluated to vhdl :" << qPrintable(msb) << " with type = " << qPrintable(getTypeString()) << endl; - if ((context == BlockParameter::Entity) || (context == BlockParameter::Component)) { + bool ok; + cout << "iface " << qPrintable(name) << " must be evaluated to vhdl :" << qPrintable(width) << " with type = " << qPrintable(getTypeString()) << endl; - QString formatBool = "%1 : %2 std_logic"; - QString formatVector = ""; - if (endianess == LittleEndian) formatVector = "%1 : %2 std_logic_vector(%3 downto %4)"; - else formatVector = "%1 : %2 std_logic_vector(%4 to %3)"; + // create the width part + QString widthStr = ""; + if (type == Boolean) { + widthStr = "std_logic"; + } + else { + QString formatWidth = ""; + if (endianess == LittleEndian) formatWidth = "std_logic_vector(%1 downto %2)"; + else formatWidth = "std_logic_vector(%2 to %1)"; - if ((flags & BlockParameter::NoComma) == 0) { - formatBool.append(";"); - formatVector.append(";"); - } - QString orientation=""; - if (direction == Input) { - orientation = "in"; - } - else if (direction == Output) { - orientation = "out"; - } - else { - orientation = "inout"; - } - if (type == Boolean) { - ret = formatBool.arg(name).arg(orientation); - } - else if (type == Natural) { - int w = width.toInt(&ok); + if (type == Natural) { + w = width.toInt(&ok); if (!ok) { throw(Exception(INVALID_VALUE)); } else { w -= 1; - ret = formatVector.arg(name).arg(orientation).arg(w).arg("0"); + wStr.setNum(w); + widthStr = formatWidth.arg(wStr).arg(0); } } else if (type == Expression) { - - /* must check the following conditions : - - if it contains user/port parameters : must evaluate their numeric value - - if it contains generic parameters : just remove the $ -> the expression is not arithmetically evaluated. - */ - QList listGenerics = owner->getGenericParameters(); - QList listUsers = owner->getUserParameters(); - QList listPorts = owner->getPortParameters(); - foreach(BlockParameter* p, listUsers) { - QString var = "$"; - var += p->getName(); - if (width.contains(var)) { - int w = p->getValue().toInt(&ok); - if (!ok) throw(Exception(INVALID_VALUE)); - msb.replace(var,p->getValue().toString()); + // NB: if for signal, must retrieve the real size, not the one with generics + if (context == Signal) { + w = getWidth(); + if (w == -1) throw(Exception(INVALID_VALUE)); + if (w == 0) { + widthStr = "std_logic"; } - } - foreach(BlockParameter* p, listPorts) { - QString var = "$"; - var += p->getName(); - if (width.contains(var)) { - msb.replace(var,p->toVHDL(0,0)); + else { + w--; + wStr.setNum(w); + widthStr = formatWidth.arg(wStr).arg(0); } } - foreach(BlockParameter* p, listGenerics) { - QString var = "$"; - var += p->getName(); - if (width.contains(var)) { - msb.replace(var,p->getName()); + else { + + /* must check the following conditions : + - if it contains user/port parameters : must evaluate their numeric value + - if it contains generic parameters : just remove the $ -> the expression is not arithmetically evaluated. + */ + wStr = width; + QList listGenerics = owner->getGenericParameters(); + QList listUsers = owner->getUserParameters(); + QList listPorts = owner->getPortParameters(); + foreach(BlockParameter* p, listUsers) { + QString var = "$"; + var += p->getName(); + if (width.contains(var)) { + w = p->getValue().toInt(&ok); + if (!ok) throw(Exception(INVALID_VALUE)); + wStr.replace(var,p->getValue().toString()); + } + } + foreach(BlockParameter* p, listPorts) { + QString var = "$"; + var += p->getName(); + if (width.contains(var)) { + wStr.replace(var,p->toVHDL(0,0)); + } } + foreach(BlockParameter* p, listGenerics) { + QString var = "$"; + var += p->getName(); + if (width.contains(var)) { + wStr.replace(var,p->getName()); + } + } + wStr += "-1"; + widthStr = formatWidth.arg(wStr).arg(0); + } + } + else if (type == Inherited) { + w = getWidth(); + if (w == -1) throw(Exception(INVALID_VALUE)); + if (w == 0) { + widthStr = "std_logic"; + } + else { + w--; + wStr.setNum(w); + widthStr = formatWidth.arg(wStr).arg(0); } - msb += "-1"; - cout << "iface size :" << qPrintable(msb) << endl; - ret = formatVector.arg(name).arg(orientation).arg(msb).arg("0"); } } + + if ((flags & NoComma) == 0) { + widthStr.append(";"); + } + + // generate for an Entity or Component port + if ((context == Entity) || (context == Component)) { + + QString formatPort = "%1 : %2 "; + + QString orientation=""; + if (direction == Input) { + orientation = "in"; + } + else if (direction == Output) { + orientation = "out"; + } + else { + orientation = "inout"; + } + + ret = formatPort.arg(name).arg(orientation); + ret += widthStr; + } + else if (context == Signal) { + ret = widthStr; + } + else if (context == Architecture) { + + } + return ret; } diff --git a/AbstractInterface.h b/AbstractInterface.h index a214831..1f6dd6f 100644 --- a/AbstractInterface.h +++ b/AbstractInterface.h @@ -28,7 +28,7 @@ public : enum IfaceWidthDir { LittleEndian = 1, BigEndian}; //! LittleEndian = X downto 0, BigEndian = 0 to X enum IfacePurpose { AnyPurpose = 0, Data = 1, Control, Clock, Reset, Wishbone }; enum IfaceDirection { AnyDirection = 0, Input = 1, Output = 2, InOut = 3 }; - enum IfaceVHDLContext {AnyContext = 0, Entity = 1, Component = 2, Architecture = 3 }; // NB : 3 is when creating an instance of the block that owns this iface + enum IfaceVHDLContext {AnyContext = 0, Entity = 1, Component = 2, Architecture = 3, Signal = 4 }; // NB : 3 is when creating an instance of the block that owns this iface enum IfaceVHDLFlags { NoComma = 1 }; static int getIntDirection(QString str); @@ -45,7 +45,8 @@ public : QString getTypeString(); inline int getEndianess() { return endianess; } QString getEndianessString(); - inline QString getWidth() { return width;} + inline QString getWidthString() { return width;} + virtual int getWidth(); // return -1 if size cannot be determine inline int getPurpose() { return purpose;} QString getPurposeString(); inline int getDirection() { return direction;} diff --git a/BlockParameterGeneric.cpp b/BlockParameterGeneric.cpp index 5b694fc..b5b5186 100644 --- a/BlockParameterGeneric.cpp +++ b/BlockParameterGeneric.cpp @@ -7,6 +7,9 @@ BlockParameterGeneric::BlockParameterGeneric() : BlockParameter() { } BlockParameterGeneric::BlockParameterGeneric(AbstractBlock* _owner, const QString &_name, const QString &_type, const QString &_value) : BlockParameter(_owner, _name, _type, _value) { + /* CAUTION: no check done on the type parameter ! + * It must never be "expression" but something that is numeric/boolean + */ userValue = defaultValue; } diff --git a/BoxItem.cpp b/BoxItem.cpp index 4471c86..85a1c9f 100644 --- a/BoxItem.cpp +++ b/BoxItem.cpp @@ -720,7 +720,7 @@ void BoxItem::loadFunctional(QDomElement funcElement) throw(Exception) { throw(Exception(PROJECTFILE_CORRUPTED)); } if (referenceMd5 != referenceXml) { - throw(Exception(PROJECTFILE_CORRUPTED)); + reference = referenceXml; } else { reference = referenceMd5; diff --git a/FunctionalBlock.cpp b/FunctionalBlock.cpp index 1ec0c11..3ea8253 100644 --- a/FunctionalBlock.cpp +++ b/FunctionalBlock.cpp @@ -1451,57 +1451,61 @@ void FunctionalBlock::generateLibraries(QTextStream& out, QDomElement &elt) thro } } -void FunctionalBlock::generateEntity(QTextStream& out, bool hasController) throw(Exception) { + +void FunctionalBlock::generateEntityOrComponentBody(QTextStream& out, int indentLevel, bool hasController) throw(Exception) { int i=0; + QString indent = ""; + for(i=0;i listParams = reference->getParameters(); QList listInputs = getInputs(); QList listOutputs = getOutputs(); - QList listBidirs = getBidirs(); - QString typePort, namePort; - - out << "entity " << name << " is" << endl; - - - /* TODO : rewrite the generation to take into acocunt the new object hierarchy */ + QList listBidirs = getBidirs(); // Generation of the generics QList listGenerics = getGenericParameters(); if ((!listGenerics.isEmpty()) || (hasController)) { - out << " generic (" << endl; + out << indent << " generic (" << endl; if (hasController) { - out << " wb_data_width : integer = 16;" << endl; - out << " wb_addr_width : integer = 12"; - if (!listGenerics.isEmpty()) out << ";"; + out << indent << " wb_data_width : integer = 16;" << endl; + out << indent << " wb_addr_width : integer = 12"; + if (!listGenerics.isEmpty()) out << indent << ";"; out << endl; } for(i=0;itoVHDL(BlockParameter::Entity, 0) << endl; + out << indent << " " << listGenerics.at(i)->toVHDL(BlockParameter::Entity, 0) << endl; } - out << " " << listGenerics.at(i)->toVHDL(BlockParameter::Entity,BlockParameter::NoComma) << endl; + out << indent << " " << listGenerics.at(i)->toVHDL(BlockParameter::Entity,BlockParameter::NoComma) << endl; - out << " );" << endl; + out << indent << " );" << endl; } - out << " port (" << endl; + out << indent << " port (" << endl; // Generation of the clk & rst signals - out << " -- clk/rst" << endl; + out << indent << " -- clk/rst" << endl; foreach(AbstractInterface* iface, listInputs) { if(iface->getPurpose() == AbstractInterface::Clock || iface->getPurpose() == AbstractInterface::Reset) { - out << " " << iface->getName() << " : in std_logic;" << endl; + out << indent << " " << iface->getName() << " : in std_logic;" << endl; + } + } + foreach(AbstractInterface* iface, listOutputs) { + if(iface->getPurpose() == AbstractInterface::Clock || iface->getPurpose() == AbstractInterface::Reset) { + out << indent << " " << iface->getName() << " : out std_logic;" << endl; } } if (hasController) { // Generation of the wishbone signals - out << " -- registers r/w via wishbone" << endl; + out << indent << " -- registers r/w via wishbone" << endl; QList listWB = reference->getWishboneParameters(); for(i=0;itoVHDL(BlockParameter::Entity, 0) << endl; + out << indent << " " << listWB.at(i)->toVHDL(BlockParameter::Entity, 0) << endl; } - out << " " << listWB.at(i)->toVHDL(BlockParameter::Entity,BlockParameter::NoComma) << endl; + out << indent << " " << listWB.at(i)->toVHDL(BlockParameter::Entity,BlockParameter::NoComma) << endl; } @@ -1517,64 +1521,64 @@ void FunctionalBlock::generateEntity(QTextStream& out, bool hasController) throw foreach(AbstractInterface* iface, listInputs) { if(iface->getPurpose() == AbstractInterface::Data) { if (first) { - out << " -- input data ports" << endl; + out << indent << " -- input data ports" << endl; first = false; } count--; if (count == 0) flag = AbstractInterface::NoComma; - out << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl; + out << indent << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl; } } first = true; foreach(AbstractInterface* iface, listInputs) { if(iface->getPurpose() == AbstractInterface::Control) { if (first) { - out << " -- input control ports" << endl; + out << indent << " -- input control ports" << endl; first = false; } count--; if (count == 0) flag = AbstractInterface::NoComma; - out << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl; + out << indent << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl; } } first = true; foreach(AbstractInterface* iface, listOutputs) { if(iface->getPurpose() == AbstractInterface::Data) { if (first) { - out << " -- output data ports" << endl; + out << indent << " -- output data ports" << endl; first = false; } count--; if (count == 0) flag = AbstractInterface::NoComma; - out << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl; + out << indent << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl; } } first = true; foreach(AbstractInterface* iface, listOutputs) { if(iface->getPurpose() == AbstractInterface::Control) { if (first) { - out << " -- output control ports" << endl; + out << indent << " -- output control ports" << endl; first = false; } count--; if (count == 0) flag = AbstractInterface::NoComma; - out << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl; + out << indent << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl; } } first = true; foreach(AbstractInterface* iface, listBidirs) { if(iface->getPurpose() == AbstractInterface::Data) { if (first) { - out << " -- bidirs data ports" << endl; + out << indent << " -- bidirs data ports" << endl; first = false; } count--; if (count == 0) flag = AbstractInterface::NoComma; - out << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl; + out << indent << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl; } } - out << " );" << endl << endl; - out << "end " << name << ";" << endl << endl; + out << indent << " );" << endl << endl; + } void FunctionalBlock::generateArchitecture(QTextStream& out, QDomElement &elt ) throw(Exception) { diff --git a/FunctionalBlock.h b/FunctionalBlock.h index d3bd581..7bba2c8 100644 --- a/FunctionalBlock.h +++ b/FunctionalBlock.h @@ -51,7 +51,8 @@ public: // others void populate(); // create parameters and interface from reference block - void generateVHDL(const QString& path) throw(Exception); // main entry to generate the VHDL code + void generateVHDL(const QString& path) throw(Exception); // main entry to generate the VHDL code + void parametersValidation(QList *checkedBlocks, QList* blocksToConfigure); QString getReferenceXmlFile(); @@ -156,9 +157,9 @@ private: void generateComments(QTextStream& out, QDomElement &elt, QString coreFile) throw(Exception); // generates comments from element void generateLibraries(QTextStream& out, QDomElement &elt) throw(Exception); // generates libraries from element - void generateEntity(QTextStream& out, bool hasController=false) throw(Exception); // generate the entity using reference void generateArchitecture(QTextStream& out, QDomElement &elt ) throw(Exception); // generate the architecture using element void generateController(QTextStream& out) throw(Exception); // generate the wishbone controller of the block + void generateEntityOrComponentBody(QTextStream& out, int indentLevel, bool hasController=false) throw(Exception); // generate the entity/compo body using reference QMap* > consumptionPattern; QMap admittanceCyclic; // the admittance expressed as prologue-cyclic part-epilogue, deduced from admittance diff --git a/FunctionalInterface.cpp b/FunctionalInterface.cpp index 23fd482..1237e74 100644 --- a/FunctionalInterface.cpp +++ b/FunctionalInterface.cpp @@ -19,7 +19,7 @@ FunctionalInterface::FunctionalInterface(AbstractBlock* _owner, ReferenceInterfa name = reference->getName(); type = reference->getType(); endianess = reference->getEndianess(); - width = reference->getWidth(); + width = reference->getWidthString(); direction = reference->getDirection(); purpose = reference->getPurpose(); connectedFrom = NULL; diff --git a/GroupBlock.cpp b/GroupBlock.cpp index f618789..9a8bb0f 100644 --- a/GroupBlock.cpp +++ b/GroupBlock.cpp @@ -311,11 +311,13 @@ void GroupBlock::generateLibraries(QTextStream& out, QDomElement &elt) throw(Exc } -void GroupBlock::generateEntity(QTextStream& out, bool hasController) throw(Exception) { +void GroupBlock::generateEntityOrComponentBody(QTextStream& out, int indentLevel, bool hasController) throw(Exception) { int i; - - out << "entity " << name << " is " << endl; + QString indent = ""; + for(i=0;i listGenerics = getGenericParameters(); QList listInputs = getInputs(); @@ -323,21 +325,21 @@ void GroupBlock::generateEntity(QTextStream& out, bool hasController) throw(Exce QList listBidirs = getBidirs(); if (!listGenerics.isEmpty()) { - out << " generic (" << endl; + out << indent << " generic (" << endl; for(i=0;itoVHDL(BlockParameter::Entity, 0) << endl; + out << indent << " " << listGenerics.at(i)->toVHDL(BlockParameter::Entity, 0) << endl; } - out << " " << listGenerics.at(i)->toVHDL(BlockParameter::Entity,BlockParameter::NoComma) << endl; - out << " );" << endl; + out << indent << " " << listGenerics.at(i)->toVHDL(BlockParameter::Entity,BlockParameter::NoComma) << endl; + out << indent << " );" << endl; } - out << " port (" << endl; + out << indent << " port (" << endl; // Generation of the clk & rst signals - out << " -- clk/rst" << endl; + out << indent << " -- clk/rst" << endl; foreach(AbstractInterface* iface, listInputs) { if(iface->getPurpose() == AbstractInterface::Clock || iface->getPurpose() == AbstractInterface::Reset) { - out << " " << iface->getName() << " : in std_logic;" << endl; + out << indent << " " << iface->getName() << " : in std_logic;" << endl; } } @@ -353,69 +355,123 @@ void GroupBlock::generateEntity(QTextStream& out, bool hasController) throw(Exce foreach(AbstractInterface* iface, listInputs) { if(iface->getPurpose() == AbstractInterface::Data) { if (first) { - out << " -- input data ports" << endl; + out << indent << " -- input data ports" << endl; first = false; } count--; if (count == 0) flag = AbstractInterface::NoComma; - out << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl; + out << indent << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl; } } first = true; foreach(AbstractInterface* iface, listInputs) { if(iface->getPurpose() == AbstractInterface::Control) { if (first) { - out << " -- input control ports" << endl; + out << indent << " -- input control ports" << endl; first = false; } count--; if (count == 0) flag = AbstractInterface::NoComma; - out << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl; + out << indent << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl; } } first = true; foreach(AbstractInterface* iface, listOutputs) { if(iface->getPurpose() == AbstractInterface::Data) { if (first) { - out << " -- output data ports" << endl; + out << indent << " -- output data ports" << endl; first = false; } count--; if (count == 0) flag = AbstractInterface::NoComma; - out << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl; + out << indent << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl; } } first = true; foreach(AbstractInterface* iface, listOutputs) { if(iface->getPurpose() == AbstractInterface::Control) { if (first) { - out << " -- output control ports" << endl; + out << indent << " -- output control ports" << endl; first = false; } count--; if (count == 0) flag = AbstractInterface::NoComma; - out << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl; + out << indent << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl; } } first = true; foreach(AbstractInterface* iface, listBidirs) { if(iface->getPurpose() == AbstractInterface::Data) { if (first) { - out << " -- bidirs data ports" << endl; + out << indent << " -- bidirs data ports" << endl; first = false; } count--; if (count == 0) flag = AbstractInterface::NoComma; - out << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl; + out << indent << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl; } } - out << " );" << endl << endl; - out << "end " << name << ";" << endl << endl; - + out << indent << " );" << endl << endl; } void GroupBlock::generateArchitecture(QTextStream& out, QDomElement &elt) throw(Exception) { + int i; + + out << "architecture rtl of " << name << " is " << endl << endl; + + // generate the components + foreach(AbstractBlock* block, blocks) { + try { + block->generateComponent(out,false); + } + catch(Exception e) { + throw(e); + } + } + + out << endl; + // generate signals + out << " ----------------------------" << endl; + out << " SIGNALS" << endl; + out << " ----------------------------" << endl << endl; + + out << " -- signals from input ports of " << name << endl; + QList listInputs = getInputs(); + foreach(AbstractInterface* iface, listInputs) { + if ((iface->getPurpose() == AbstractInterface::Data)||(iface->getPurpose() == AbstractInterface::Control)) { + ConnectedInterface* connIface = AI_TO_CON(iface); + QString prefixName = name+"_"+iface->getName()+"_TO_"; + foreach(ConnectedInterface* toIface, connIface->getConnectedTo()) { + QString sigName = prefixName+toIface->getOwner()->getName()+"_"+toIface->getName(); + out << " signal " << sigName << " : " << iface->toVHDL(AbstractInterface::Signal,0) << endl; + } + } + } + out << endl; + foreach(AbstractBlock* block, blocks) { + try { + out << " -- signals from output ports of " << block->getName() << endl; + QList listOutputs = block->getOutputs(); + foreach(AbstractInterface* iface, listOutputs) { + if ((iface->getPurpose() == AbstractInterface::Data)||(iface->getPurpose() == AbstractInterface::Control)) { + ConnectedInterface* connIface = AI_TO_CON(iface); + QString prefixName = block->getName()+"_"+iface->getName()+"_TO_"; + foreach(ConnectedInterface* toIface, connIface->getConnectedTo()) { + QString sigName = prefixName+toIface->getOwner()->getName()+"_"+toIface->getName(); + out << " signal " << sigName << " : " << iface->toVHDL(AbstractInterface::Signal,0) << endl; + } + } + } + } + catch(Exception e) { + throw(e); + } + out << endl; + } + + + out << "end architecture rtl;" << endl; } void GroupBlock::generateController(QTextStream &out) throw(Exception) { diff --git a/GroupBlock.h b/GroupBlock.h index bb5e771..23a8ce2 100644 --- a/GroupBlock.h +++ b/GroupBlock.h @@ -46,7 +46,7 @@ public: void computeOutputPattern(int nbExec = -1) throw(Exception); void computeAdmittanceDelays() throw(Exception); - void generateVHDL(const QString& path) throw(Exception); // main entry to generate the VHDL code + void generateVHDL(const QString& path) throw(Exception); // main entry to generate the VHDL code private: // patterns @@ -66,11 +66,10 @@ private: void createInputPattern(); void generateComments(QTextStream& out, QDomElement &elt, QString coreFile) throw(Exception); // generates comments from element - void generateLibraries(QTextStream& out, QDomElement &elt) throw(Exception); // generates libraries from element - void generateEntity(QTextStream& out, bool hasController=false) throw(Exception); // generate the entity using reference + void generateLibraries(QTextStream& out, QDomElement &elt) throw(Exception); // generates libraries from element void generateArchitecture(QTextStream& out, QDomElement &elt ) throw(Exception); // generate the architecture using element void generateController(QTextStream& out) throw(Exception); // generate the wishbone controller of the block - + void generateEntityOrComponentBody(QTextStream& out, int indentLevel, bool hasController=false) throw(Exception); // generate the entity/compo body using reference bool topGroup; QList blocks; // contains instances of FunctionalBlock or GroupBlock that are children of this group diff --git a/GroupInterface.cpp b/GroupInterface.cpp index e87c14a..c611ecf 100644 --- a/GroupInterface.cpp +++ b/GroupInterface.cpp @@ -6,6 +6,10 @@ GroupInterface::GroupInterface(AbstractBlock* _owner, const QString& _name, int if (! _owner->isGroupBlock()) throw(Exception(BLOCK_INVALID_TYPE)); connectedFrom = NULL; + // force clock and reset to boolean width type instead of inherited + if ((purpose == Clock) || (purpose == Reset)) { + type = Boolean; + } } bool GroupInterface::isGroupInterface() { @@ -18,6 +22,27 @@ AbstractInterface *GroupInterface::clone() { return inter; } +int GroupInterface::getWidth() { + + bool ok; + int w = -1; + + QString expr = width; + + if (type == Boolean) { + return 1; + } + else if (type == Inherited) { + // must search from which iface it is connected. + ConnectedInterface* fromIface = connectedFrom; + while ((fromIface != NULL) && (fromIface->getType() == Inherited)) { + fromIface = fromIface->getConnectedFrom(); + } + if (fromIface == NULL) return -1; + w = fromIface->getWidth(); + } + return w; +} bool GroupInterface::canConnectTo(AbstractInterface *iface) { diff --git a/GroupInterface.h b/GroupInterface.h index 49b4957..2f7ac60 100644 --- a/GroupInterface.h +++ b/GroupInterface.h @@ -37,6 +37,7 @@ public : GroupInterface(AbstractBlock* _owner, const QString& _name, int _direction, int _purpose) throw (Exception); // getters + int getWidth(); // setters diff --git a/InterfacePropertiesWindow.cpp b/InterfacePropertiesWindow.cpp index 6999a16..5a571c0 100644 --- a/InterfacePropertiesWindow.cpp +++ b/InterfacePropertiesWindow.cpp @@ -9,6 +9,15 @@ InterfacePropertiesWindow::InterfacePropertiesWindow(InterfaceItem *_inter, QWid layout = new QGridLayout; + int w = inter->refInter->getWidth(); + QString wStr = ""; + if (w == -1) { + wStr = "invalid_size"; + } + else { + if (w == 0) w++; // 0 means a boolean thus, size of 1 bit + wStr.setNum(w); + } layout->addWidget(new QLabel("Interface properties"), 0, 0); layout->addWidget(new QLabel(" "), 1, 0); @@ -16,7 +25,7 @@ InterfacePropertiesWindow::InterfacePropertiesWindow(InterfaceItem *_inter, QWid layout->addWidget(new QLabel("Name :"), 2, 0); layout->addWidget(new QLabel(inter->getName()), 2, 1); layout->addWidget(new QLabel("Width :"), 3, 0); - layout->addWidget(new QLabel(inter->refInter->getWidth()), 3, 1); + layout->addWidget(new QLabel(wStr), 3, 1); layout->addWidget(new QLabel("Direction :"), 4, 0); layout->addWidget(new QLabel(inter->refInter->getDirectionString()), 4, 1); layout->addWidget(new QLabel("Purpose :"), 5, 0); diff --git a/ReferenceBlock.cpp b/ReferenceBlock.cpp index 70677df..9d6eb53 100644 --- a/ReferenceBlock.cpp +++ b/ReferenceBlock.cpp @@ -424,7 +424,7 @@ QDataStream& operator<<(QDataStream &out, const ReferenceBlock &b) { if (iface->getPurpose() == AbstractInterface::Control) { toWrite << iface->getName(); toWrite << iface->getType(); - toWrite << iface->getWidth(); + toWrite << iface->getWidthString(); toWrite << iface->getPurpose(); toWrite << iface->getDirection(); toWrite << iface->getMultiplicity(); @@ -436,7 +436,7 @@ QDataStream& operator<<(QDataStream &out, const ReferenceBlock &b) { if (iface->getPurpose() != AbstractInterface::Control) { toWrite << iface->getName(); toWrite << iface->getType(); - toWrite << iface->getWidth(); + toWrite << iface->getWidthString(); toWrite << iface->getPurpose(); toWrite << iface->getDirection(); toWrite << iface->getMultiplicity(); @@ -449,7 +449,7 @@ QDataStream& operator<<(QDataStream &out, const ReferenceBlock &b) { if (iface->getPurpose() == AbstractInterface::Control) { toWrite << iface->getName(); toWrite << iface->getType(); - toWrite << iface->getWidth(); + toWrite << iface->getWidthString(); toWrite << iface->getPurpose(); toWrite << iface->getDirection(); toWrite << iface->getMultiplicity(); @@ -461,7 +461,7 @@ QDataStream& operator<<(QDataStream &out, const ReferenceBlock &b) { if (iface->getPurpose() != AbstractInterface::Control) { toWrite << iface->getName(); toWrite << iface->getType(); - toWrite << iface->getWidth(); + toWrite << iface->getWidthString(); toWrite << iface->getPurpose(); toWrite << iface->getDirection(); toWrite << iface->getMultiplicity(); @@ -472,7 +472,7 @@ QDataStream& operator<<(QDataStream &out, const ReferenceBlock &b) { ReferenceInterface *iface = (ReferenceInterface *)(b.bidirs.at(i)); toWrite << iface->getName(); toWrite << iface->getType(); - toWrite << iface->getWidth(); + toWrite << iface->getWidthString(); toWrite << iface->getPurpose(); toWrite << iface->getDirection(); toWrite << iface->getMultiplicity(); @@ -648,15 +648,15 @@ void ReferenceBlock::generateLibraries(QTextStream& out, QDomElement &elt) throw throw(Exception(INVALID_REFBLOCK_USE)); } -void ReferenceBlock::generateEntity(QTextStream& out, bool hasController) throw(Exception) { +void ReferenceBlock::generateArchitecture(QTextStream& out, QDomElement &elt ) throw(Exception) { throw(Exception(INVALID_REFBLOCK_USE)); } -void ReferenceBlock::generateArchitecture(QTextStream& out, QDomElement &elt ) throw(Exception) { +void ReferenceBlock::generateController(QTextStream& out) throw(Exception) { throw(Exception(INVALID_REFBLOCK_USE)); } -void ReferenceBlock::generateController(QTextStream& out) throw(Exception) { +void ReferenceBlock::generateEntityOrComponentBody(QTextStream &out, int indentLevel, bool hasController) throw(Exception) { throw(Exception(INVALID_REFBLOCK_USE)); } diff --git a/ReferenceBlock.h b/ReferenceBlock.h index 79db803..5dfcbd1 100644 --- a/ReferenceBlock.h +++ b/ReferenceBlock.h @@ -71,10 +71,11 @@ private: void computeAdmittanceDelays() throw(Exception); void generateComments(QTextStream& out, QDomElement &elt, QString coreFile) throw(Exception); // generates comments from element - void generateLibraries(QTextStream& out, QDomElement &elt) throw(Exception); // generates libraries from element - void generateEntity(QTextStream& out, bool hasController=false) throw(Exception); // generate the entity using reference + void generateLibraries(QTextStream& out, QDomElement &elt) throw(Exception); // generates libraries from element void generateArchitecture(QTextStream& out, QDomElement &elt ) throw(Exception); // generate the architecture using element void generateController(QTextStream& out) throw(Exception); // generate the wishbone controller of the block + void generateEntityOrComponentBody(QTextStream& out, int indentLevel, bool hasController=false) throw(Exception); // generate the entity/compo body using reference + }; #endif // __REFERENCEBLOCK_H__ diff --git a/VHDLConverter.cpp b/VHDLConverter.cpp index d3938b2..88b371f 100644 --- a/VHDLConverter.cpp +++ b/VHDLConverter.cpp @@ -459,12 +459,12 @@ void VHDLConverter::loadVHDLFile() { else { widthStr = "std_logic_vector("; if (iface->getEndianess() == AbstractInterface::LittleEndian) { - widthStr += iface->getWidth(); + widthStr += iface->getWidthString(); widthStr += " downto 0)"; } else { widthStr += "0 to "; - widthStr += iface->getWidth(); + widthStr += iface->getWidthString(); widthStr += ")"; } } @@ -651,7 +651,7 @@ void VHDLConverter::generateRefXml(QDomDocument& doc) { QDomElement input = doc.createElement("input"); input.setAttribute("name",iface->getName()); input.setAttribute("type",iface->getTypeString()); - input.setAttribute("width",iface->getWidth()); + input.setAttribute("width",iface->getWidthString()); input.setAttribute("multiplicity","1"); input.setAttribute("purpose",iface->getPurposeString()); input.setAttribute("endian",iface->getEndianessString()); @@ -673,7 +673,7 @@ void VHDLConverter::generateRefXml(QDomDocument& doc) { QDomElement output = doc.createElement("output"); output.setAttribute("name",iface->getName()); output.setAttribute("type",iface->getTypeString()); - output.setAttribute("width",iface->getWidth()); + output.setAttribute("width",iface->getWidthString()); output.setAttribute("multiplicity","1"); output.setAttribute("purpose",iface->getPurposeString()); output.setAttribute("endian",iface->getEndianessString()); @@ -695,7 +695,7 @@ void VHDLConverter::generateRefXml(QDomDocument& doc) { QDomElement bidir = doc.createElement("bidir"); bidir.setAttribute("name",iface->getName()); bidir.setAttribute("type",iface->getTypeString()); - bidir.setAttribute("width",iface->getWidth()); + bidir.setAttribute("width",iface->getWidthString()); bidir.setAttribute("multiplicity","1"); bidir.setAttribute("purpose",iface->getPurposeString()); bidir.setAttribute("endian",iface->getEndianessString()); diff --git a/blast.creator.user b/blast.creator.user index d62fe35..af36049 100644 --- a/blast.creator.user +++ b/blast.creator.user @@ -1,10 +1,10 @@ - + EnvironmentId - {eddbf04f-e5ee-4f36-bc65-6ab7f2b6d4ec} + {3701e197-5b6c-48ea-9e98-a6cf6de18672} ProjectExplorer.Project.ActiveTarget @@ -61,7 +61,7 @@ Desktop Desktop - {72d0832a-d73b-473a-b29c-d1c0737451fe} + {ed04208c-8774-456b-99b9-4a02094ca7a4} 0 0 0 diff --git a/boxfilter_3x3.vhd b/boxfilter_3x3.vhd deleted file mode 100644 index 2998a41..0000000 --- a/boxfilter_3x3.vhd +++ /dev/null @@ -1,421 +0,0 @@ -------------------------------------------------------------------------------- --- --- File : boxfilter_3x3.vhd --- Related files : --- --- Author(s) : stephane Domas (sdomas@univ-fcomte.fr) --- --- Creation Date : 2017/10/16 --- --- Description : This IP does a box (i.e. average) filter with a 3x3 mask --- on a grayscale image. The width of the image must be <= 1024. --- Image size must be provided via generics --- --- Note : --- CP = 1{$img_width*$img_height} --- PP = 0{$img_width+7}1{$img_width*$img_height} --- PC = {$img_width+2:$img_width*$img_height-($img_width+2):1},{$img_width*$img_height:$img_width+2,0} --- delta = $img_width*$img_height --- -------------------------------------------------------------------------------- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -entity boxfilter_3x3 is - generic( - img_width : natural := 128; - img_height : natural := 128; - dsp_in_width : natural := 18; - dsp_out_width : natural := 36 - ); - port( - clk : in std_logic; - reset : in std_logic; - pix_in : in std_logic_vector(7 downto 0); - pix_in_enb : in std_logic; - pix_out : out std_logic_vector(7 downto 0); - pix_out_enb : out std_logic - ); -end boxfilter_3x3; - - -architecture rtl of boxfilter_3x3 is - - component ram_dp_1024x8 - port ( - clka : in std_logic; - wea : in std_logic_vector(0 downto 0); - addra : in std_logic_vector(9 downto 0); - dina : in std_logic_vector(7 downto 0); - douta : out std_logic_vector(7 downto 0); - clkb : in std_logic; - web : in std_logic_vector(0 downto 0); - addrb : in std_logic_vector(9 downto 0); - dinb : in std_logic_vector(7 downto 0); - doutb : out std_logic_vector(7 downto 0) - ); - end component; - - -- Signals - - -- constant signal set tup to img limits - signal count_col_end : unsigned (9 downto 0); - signal count_row_end : unsigned (9 downto 0); - - -- for storing image rows - signal sel_mem : unsigned (1 downto 0); -- the current memorize row - signal wea_0 : std_logic_vector(0 downto 0); -- we for memorized row 0 - signal wea_1 : std_logic_vector(0 downto 0); -- we for memorized row 1 - signal wea_2 : std_logic_vector(0 downto 0); -- we for memorized row 2 - - signal dina_0 : std_logic_vector(7 downto 0); - signal dina_1 : std_logic_vector(7 downto 0); - signal dina_2 : std_logic_vector(7 downto 0); - signal dina : std_logic_vector(7 downto 0); - - signal addra_w : std_logic_vector(9 downto 0); - signal addra_w_s : unsigned (9 downto 0); - signal wea : std_logic; - - - signal addrb_r : std_logic_vector(9 downto 0); -- addr where to store - signal addrb_r_s : unsigned (9 downto 0); -- addr where to store - - signal doutb_0 : std_logic_vector(7 downto 0); - signal doutb_1 : std_logic_vector(7 downto 0); - signal doutb_2 : std_logic_vector(7 downto 0); - - signal count_row_w : unsigned (10 downto 0); -- row counter while storing - signal store_last_pix : std_logic; -- to be sure that last pixel is stored - signal first_row_w : std_logic; -- '1' when the first row is read so that - -- mem_0 is filled with zeroes - signal all_pix_stored : std_logic; -- '1' when all pixels have been stored - - -- for reading image rows - signal start_read : std_logic; - signal do_read : std_logic; - signal count_row_r : unsigned (10 downto 0); - signal count_row_r_dly : unsigned (10 downto 0); - signal wea_dly : std_logic; - signal end_read : std_logic; - - -- for doing sums - signal do_sum : std_logic; - signal sum1 : unsigned (9 downto 0); - signal sum2 : unsigned (9 downto 0); - signal sum3 : unsigned (9 downto 0); - - -- for doing total - signal do_total : std_logic; - signal sum : unsigned (dsp_in_width-1 downto 0); - signal count_col_total : unsigned (10 downto 0); - signal count_row_total : unsigned (10 downto 0); - signal jump_first_sum : std_logic; - - -- for doing final division - signal do_div : std_logic; - signal do_out : std_logic; - signal end_filter : std_logic; - signal cst_mult : unsigned(dsp_in_width-1 downto 0); -- eq. 14564 (=2^17/9) - signal mult_result : unsigned (dsp_out_width-1 downto 0); - - -begin - - img_row_0 : ram_dp_1024x8 - port map ( - clka => clk, - wea => wea_0, - addra => addra_w, - dina => dina_0, - clkb => clk, - web => (others => '0'), - addrb => addrb_r, - dinb => (others => '0'), - doutb => doutb_0 - ); - img_row_1 : ram_dp_1024x8 - port map ( - clka => clk, - wea => wea_1, - addra => addra_w, - dina => dina_1, - clkb => clk, - web => (others => '0'), - addrb => addrb_r, - dinb => (others => '0'), - doutb => doutb_1 - ); - img_row_2 : ram_dp_1024x8 - port map ( - clka => clk, - wea => wea_2, - addra => addra_w, - dina => dina_2, - clkb => clk, - web => (others => '0'), - addrb => addrb_r, - dinb => (others => '0'), - doutb => doutb_2 - ); - - - cst_mult <= to_unsigned(14564, dsp_in_width); - count_col_end <= to_unsigned(img_width-1, 10); - count_row_end <= to_unsigned(img_height-1, 10); - - addra_w <= std_logic_vector(addra_w_s); - addrb_r <= std_logic_vector(addrb_r_s); - - wea_0 <= "1" when ((sel_mem = 0 or first_row_w = '1') and wea = '1') else - "0"; - wea_1 <= "1" when (sel_mem = 1 and wea = '1') else - "0"; - wea_2 <= "1" when (sel_mem = 2 and wea = '1') else - "0"; - - dina_0 <= (others => '0') when (first_row_w = '1') else - dina; - - dina_1 <= dina; - dina_2 <= dina; - - store_row_process : process (clk, reset) - begin - if reset = '1' then - - sel_mem <= to_unsigned(0, 2); - addra_w_s <= to_unsigned(img_width-1, 10); - dina <= (others => '0'); - - wea <= '0'; - count_row_w <= to_unsigned(0, 11); - - start_read <= '0'; - first_row_w <= '1'; - store_last_pix <= '0'; - all_pix_stored <= '0'; - - elsif rising_edge(clk) then - - wea <= '0'; - start_read <= '0'; - dina <= (others => '0'); - store_last_pix <= '0'; - - -- reset all when filter has ended - if end_filter = '1' then - - count_row_w <= to_unsigned(0, 11); - sel_mem <= to_unsigned(0, 2); - addra_w_s <= to_unsigned(img_width-1, 10); - first_row_w <= '1'; - all_pix_stored <= '0'; - - elsif store_last_pix = '1' then - addra_w_s <= to_unsigned(0, 10); - -- select next ram - if sel_mem = 2 then - sel_mem <= to_unsigned(0, 2); - else - sel_mem <= sel_mem + 1; - end if; - all_pix_stored <= '1'; -- all pixels are stored - - elsif pix_in_enb = '1' then - - -- prepare to write - wea <= '1'; - -- take input - dina <= pix_in; - -- check if this is the last pixel - if addra_w_s = img_width-2 and count_row_w = img_height then - store_last_pix <= '1'; - end if; - -- if at line end - if addra_w_s = img_width-1 then - -- back to 0 - addra_w_s <= to_unsigned(0, 10); - -- select next ram - if sel_mem = 2 then - sel_mem <= to_unsigned(0, 2); - else - sel_mem <= sel_mem + 1; - end if; - -- end of first line to store - if count_row_w = 1 then - first_row_w <= '0'; - start_read <= '1'; - end if; - count_row_w <= count_row_w + 1; - else - addra_w_s <= addra_w_s + 1; - end if; - end if; - end if; - - end process store_row_process; - - read_rows_process : process (clk, reset) - begin - if reset = '1' then - - addrb_r_s <= to_unsigned(0, 10); - do_read <= '0'; - wea_dly <= '0'; - - count_row_r <= to_unsigned(0, 11); - end_read <= '0'; - - do_sum <= '0'; - - elsif rising_edge(clk) then - - wea_dly <= wea; - do_sum <= '0'; - end_read <= '0'; - - if end_read = '1' then - do_sum <= '1'; - end if; - - if start_read = '1' then - do_read <= '1'; - - elsif do_read = '1' and (all_pix_stored = '1' or wea_dly = '1') then - - do_sum <= '1'; - -- whatever the case inc addr if not at end - if addrb_r_s = img_width-1 then - addrb_r_s <= to_unsigned(0, 10); - if count_row_r = img_height-1 then - count_row_r <= to_unsigned(0, 11); - do_read <= '0'; - end_read <= '1'; - else - count_row_r <= count_row_r+1; - end if; - else - addrb_r_s <= addrb_r_s + 1; - end if; - end if; - end if; - - end process read_rows_process; - - sum_process : process (clk, reset) - begin - if reset = '1' then - - sum1 <= to_unsigned(0, 10); - sum2 <= to_unsigned(0, 10); - sum3 <= to_unsigned(0, 10); - count_row_r_dly <= to_unsigned(0, 11); - do_total <= '0'; - - elsif rising_edge(clk) then - - do_total <= '0'; - count_row_r_dly <= count_row_r; - - if end_filter = '1' then - sum1 <= to_unsigned(0, 10); - sum2 <= to_unsigned(0, 10); - sum3 <= to_unsigned(0, 10); - end if; - if do_sum = '1' then - - sum3 <= sum2; - sum2 <= sum1; - if count_row_r_dly = img_height-1 then - if sel_mem = 0 then - sum1 <= unsigned("00" & doutb_1) + unsigned("00" & doutb_2); - elsif sel_mem = 1 then - sum1 <= unsigned("00" & doutb_0) + unsigned("00" & doutb_2); - elsif sel_mem = 2 then - sum1 <= unsigned("00" & doutb_0) + unsigned("00" & doutb_1); - end if; - else - sum1 <= unsigned("00" & doutb_0) + unsigned("00" & doutb_1) + unsigned("00" & doutb_2); - end if; - do_total <= '1'; - end if; - end if; - - end process sum_process; - - total_process : process (clk, reset) - begin - if reset = '1' then - - sum <= to_unsigned(0, dsp_in_width); - - jump_first_sum <= '0'; - count_row_total <= to_unsigned(0, 11); - count_col_total <= to_unsigned(0, 11); - do_div <= '0'; - end_filter <= '0'; - - elsif rising_edge(clk) then - - do_div <= '0'; - end_filter <= '0'; - - if do_total = '1' then - - if jump_first_sum = '1' then - -- sum for the end of the line - if count_col_total = img_width-1 then - sum <= resize(sum2, dsp_in_width) + resize(sum3, dsp_in_width); - count_col_total <= to_unsigned(0, 11); - if count_row_total = img_height-1 then - end_filter <= '1'; - count_row_total <= to_unsigned(0, 11); - jump_first_sum <= '0'; - else - count_row_total <= count_row_total + 1; - end if; - -- sum for the begining of the line - elsif count_col_total = 0 then - sum <= resize(sum1, dsp_in_width) + resize(sum2, dsp_in_width); - count_col_total <= to_unsigned(1, 11); - else - sum <= resize(sum1, dsp_in_width) + resize(sum2, dsp_in_width) + resize(sum3, dsp_in_width); - count_col_total <= count_col_total + 1; - end if; - do_div <= '1'; - else - jump_first_sum <= '1'; - end if; - end if; - - - end if; - - end process total_process; - - final_div_process : process (clk, reset) - begin - if reset = '1' then - - mult_result <= to_unsigned(0, dsp_out_width); - do_out <= '0'; - - elsif rising_edge(clk) then - - do_out <= '0'; - - if do_div = '1' then - mult_result <= sum * cst_mult; - do_out <= '1'; - end if; - end if; - end process final_div_process; - - pix_out <= std_logic_vector(mult_result(24 downto 17)); - pix_out_enb <= do_out; - -end rtl; - diff --git a/checker.vhd b/checker.vhd deleted file mode 100644 index 82ca1d3..0000000 --- a/checker.vhd +++ /dev/null @@ -1,94 +0,0 @@ -------------------------------------------------------------------------------- --- --- File : checker.vhd --- Related files : --- --- Author(s) : stephane Domas (sdomas@univ-fcomte.fr) --- --- Creation Date : 2017/10/16 --- --- Description : This IP does a threshold on an input --- --- --- Note : The input is compared to one (or two) values and depending --- on the result and the type of the comparison, the check output --- is asserted to 1 or not. --- The values are fixed by generic parameter. --- The type of check is fixed by a generic paramter --- type 1 : test if lesser or equal than X --- type 2 : test if gretar or equal than X --- type 3 : test if greater or equal than X and lesser or equal than Y --- --- -------------------------------------------------------------------------------- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -entity checker is - generic( - in_width : natural := 8; - check_type : natural := 1; - inf_value : natural := 0; - sup_value : natural := 0 - ); - port( - clk : in std_logic; - reset : in std_logic; - data_in : in std_logic_vector(in_width-1 downto 0); - data_in_enb : in std_logic; - data_out : out std_logic_vector(in_width-1 downto 0); - data_out_enb : out std_logic; - check_out : out std_logic; - check_out_enb : out std_logic - ); -end checker; - - -architecture rtl of checker is - -begin - - check_process : process (clk, reset) - begin - if reset = '1' then - - check_out <= '0'; - data_out <= (others => '0'); - data_out_enb <= '0'; - check_out_enb <= '0'; - - elsif rising_edge(clk) then - - check_out <= '0'; - data_out <= (others => '0'); - data_out_enb <= '0'; - check_out_enb <= '0'; - - if data_in_enb = '1' then - - data_out <= data_in; - data_out_enb <= '1'; - check_out_enb <= '1'; - - if check_type = 1 then - if unsigned(data_in) <= inf_value then - check_out <= '1'; - end if; - elsif check_type = 2 then - if unsigned(data_in) >= inf_value then - check_out <= '1'; - end if; - elsif check_type = 3 then - if unsigned(data_in) >= inf_value and unsigned(data_in) <= sup_value then - check_out <= '1'; - end if; - end if; - end if; - end if; - - end process check_process; - -end rtl; - diff --git a/deserializer_3x1.vhd b/deserializer_3x1.vhd deleted file mode 100644 index aaccecc..0000000 --- a/deserializer_3x1.vhd +++ /dev/null @@ -1,96 +0,0 @@ -------------------------------------------------------------------------------- --- --- File : deserializer_3x1.vhd --- Related files : --- --- Author(s) : stephane Domas (sdomas@univ-fcomte.fr) --- --- Creation Date : 2017/10/16 --- --- Description : This IP does a deserialization of 3 element into --- 3 parallel outputs --- --- --- Note : --- -------------------------------------------------------------------------------- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -entity deserializer_3x1 is - generic( - in_width : natural := 8 - ); - port( - clk : in std_logic; - reset : in std_logic; - data_in : in std_logic_vector(in_width-1 downto 0); - data_in_enb : in std_logic; - data1_out : out std_logic_vector(in_width-1 downto 0); - data1_out_enb : out std_logic; - data2_out : out std_logic_vector(in_width-1 downto 0); - data2_out_enb : out std_logic; - data3_out : out std_logic_vector(in_width-1 downto 0); - data3_out_enb : out std_logic - - ); -end deserializer_3x1; - - -architecture rtl of deserializer_3x1 is - - -- Signals - signal do_out : std_logic; - signal data1_reg : std_logic_vector(in_width-1 downto 0); - signal data2_reg : std_logic_vector(in_width-1 downto 0); - - signal count : unsigned(1 downto 0); - -begin - - deser_process : process (clk, reset) - begin - if reset = '1' then - count <= to_unsigned(0, 2); - data1_reg <= (others => '0'); - data2_reg <= (others => '0'); - data1_out <= (others => '0'); - data2_out <= (others => '0'); - data3_out <= (others => '0'); - do_out <= '0'; - - elsif rising_edge(clk) then - - do_out <= '0'; - data1_out <= (others => '0'); - data2_out <= (others => '0'); - data3_out <= (others => '0'); - - if data_in_enb = '1' then - - if count = 0 then - data1_reg <= data_in; - count <= count + 1; - elsif count = 1 then - data2_reg <= data_in; - count <= count + 1; - elsif count = 2 then - data1_out <= data1_reg; - data2_out <= data2_reg; - data3_out <= data_in; - do_out <= '1'; - count <= to_unsigned(0, 2); - end if; - end if; - end if; - - end process deser_process; - - data1_out_enb <= do_out; - data2_out_enb <= do_out; - data3_out_enb <= do_out; - -end rtl; - diff --git a/lib/implementations/impls.bmf b/lib/implementations/impls.bmf new file mode 100644 index 0000000..cba0a1d Binary files /dev/null and b/lib/implementations/impls.bmf differ diff --git a/lib/references/boxfilter_3x3.xml b/lib/references/boxfilter_3x3.xml index 5e163ad..e604bbd 100644 --- a/lib/references/boxfilter_3x3.xml +++ b/lib/references/boxfilter_3x3.xml @@ -18,11 +18,11 @@ - + - + diff --git a/lib/references/references.bmf b/lib/references/references.bmf new file mode 100644 index 0000000..925725e Binary files /dev/null and b/lib/references/references.bmf differ diff --git a/lib/references/rgb3sx8_to_gs.xml b/lib/references/rgb3sx8_to_gs.xml index 9271adc..10cea03 100644 --- a/lib/references/rgb3sx8_to_gs.xml +++ b/lib/references/rgb3sx8_to_gs.xml @@ -16,11 +16,11 @@ - + - + diff --git a/lib/references/rgb3sx8_to_ycbcr_3DSP.xml b/lib/references/rgb3sx8_to_ycbcr_3DSP.xml index 5bbc856..17d1870 100644 --- a/lib/references/rgb3sx8_to_ycbcr_3DSP.xml +++ b/lib/references/rgb3sx8_to_ycbcr_3DSP.xml @@ -13,11 +13,11 @@ - + - + diff --git a/logical_AND_3.vhd b/logical_AND_3.vhd deleted file mode 100644 index 720b733..0000000 --- a/logical_AND_3.vhd +++ /dev/null @@ -1,65 +0,0 @@ -------------------------------------------------------------------------------- --- --- File : logical_AND_3.vhd --- Related files : --- --- Author(s) : stephane Domas (sdomas@univ-fcomte.fr) --- --- Creation Date : 2017/10/16 --- --- Description : This IP does a logical AND on three inputs. --- --- --- Note : --- -------------------------------------------------------------------------------- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -entity logical_AND_3 is - port( - clk : in std_logic; - reset : in std_logic; - data1_in : in std_logic; - data1_in_enb : in std_logic; - data2_in : in std_logic; - data2_in_enb : in std_logic; - data3_in : in std_logic; - data3_in_enb : in std_logic; - - data_out : out std_logic; - data_out_enb : out std_logic -- the control signal, common to all output - ); -end logical_AND_3; - - -architecture rtl of logical_AND_3 is - -begin - - and_process : process (clk, reset) - begin - if reset = '1' then - - data_out <= '0'; - data_out_enb <= '0'; - - elsif rising_edge(clk) then - - data_out <= '0'; - data_out_enb <= '0'; - - if data1_in_enb = '1' and data2_in_enb = '1' and data3_in_enb = '1' then - - data_out <= data1_in and data2_in and data3_in; - data_out_enb <= '1'; - - end if; - end if; - - end process and_process; - -end rtl; - diff --git a/rgb3sx8_to_gs.vhd b/rgb3sx8_to_gs.vhd deleted file mode 100644 index 06abc7b..0000000 --- a/rgb3sx8_to_gs.vhd +++ /dev/null @@ -1,102 +0,0 @@ -------------------------------------------------------------------------------- --- --- File : rgb3sx8_to_gs.vhd --- Related files : --- --- Author(s) : stephane Domas (sdomas@univ-fcomte.fr) --- --- Creation Date : 2017/10/16 --- --- Description : This IP does a conversion from rgb24 (8 bits/serial) to grayscale --- --- Note : rgb24 (8 bits/serial) pixels are composed of three 8 bits --- values that are consumed on port rgb_in, in the following --- order : blue, green, red. --- output value on gs_out is computed with (red+green+blue)/3 --- -------------------------------------------------------------------------------- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -entity rgb3sx8_to_gs is - generic( - dsp_in_width : natural := 18; - dsp_out_width : natural := 36 - ); - port( - clk : in std_logic; - reset : in std_logic; - rgb_in : in std_logic_vector(7 downto 0); - rgb_in_enb : in std_logic; - gs_out : out std_logic_vector(7 downto 0); - gs_out_enb : out std_logic - - ); -end rgb3sx8_to_gs; - - -architecture rtl of rgb3sx8_to_gs is - - -- Signals - signal do_mult : std_logic; - signal do_out : std_logic; - signal count : unsigned (2 downto 0); - signal accum : unsigned(dsp_in_width-1 downto 0); - signal result : unsigned(dsp_out_width-1 downto 0); - signal cst_mult : unsigned(dsp_in_width-1 downto 0); -- eq. 87382 to do /3 - -begin - - cst_mult <= to_unsigned(87382, 18); - - accum_process : process (clk, reset) - begin - if reset = '1' then - count <= to_unsigned(0, 3); - accum <= to_unsigned(0, dsp_in_width); - do_mult <= '0'; - - elsif rising_edge(clk) then - - do_mult <= '0'; - - if rgb_in_enb = '1' then - - if count = 0 then - accum <= resize(unsigned(rgb_in), dsp_in_width); - count <= to_unsigned(1, 3); - elsif count = 1 then - accum <= accum + resize(unsigned(rgb_in), dsp_in_width); - count <= to_unsigned(2, 3); - elsif count = 2 then - accum <= accum + resize(unsigned(rgb_in), dsp_in_width); - count <= to_unsigned(0, 3); - do_mult <= '1'; - end if; - end if; - end if; - - end process accum_process; - - mult_process : process (clk, reset) - begin - if reset = '1' then - result <= to_unsigned(0, dsp_out_width); - do_out <= '0'; - elsif rising_edge(clk) then - - do_out <= '0'; - if do_mult = '1' then - result <= accum * cst_mult; - do_out <= '1'; - end if; - end if; - end process mult_process; - - gs_out <= std_logic_vector(result(dsp_in_width+7 downto dsp_in_width)); - gs_out_enb <= do_out; - -end rtl; - diff --git a/rgb3sx8_to_ycbcr_3DSP.vhd b/rgb3sx8_to_ycbcr_3DSP.vhd deleted file mode 100644 index c2320fe..0000000 --- a/rgb3sx8_to_ycbcr_3DSP.vhd +++ /dev/null @@ -1,337 +0,0 @@ -------------------------------------------------------------------------------- --- --- File : rgb3sx8_to_ycbcr_3DSP.vhd --- Related files : --- --- Author(s) : stephane Domas (sdomas@univ-fcomte.fr) --- --- Creation Date : 2017/10/16 --- --- Description : This IP does a conversion from rgb24 (8 bits/serial) to YCrCb --- --- Note : rgb24 (8 bits/serial) pixels are composed of three 8 bits --- values that are consumed on port rgb_in, in the following --- order : blue, green, red. --- output values on ycrcb_out are produced in the following --- order: cb, cr, y --- They are computed using ITU-R BT.601 conversion principles, --- assuming that RGB component are digital and thus rangin --- from 0 to 255. Formulas are: --- Y = 16 + 65.738R/256 + 129.057G/256 + 25.064B/256 --- Cb = 128 - 37.945R/256 - 74.494G/256 + 112.439B/256 --- Cr = 128 + 112.439R/256 - 94.154G/256 - 18.285B/256 --- -------------------------------------------------------------------------------- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -entity rgb3sx8_to_ycbcr_3DSP is - port( - clk : in std_logic; - reset : in std_logic; - rgb_in : in std_logic_vector(7 downto 0); - rgb_in_enb : in std_logic; - ycbcr_out : out std_logic_vector(7 downto 0); - ycbcr_out_enb : out std_logic - - ); -end rgb3sx8_to_ycbcr_3DSP; - - -architecture rtl of rgb3sx8_to_ycbcr_3DSP is - - component mult_accum - port ( - clk : in std_logic; - ce : in std_logic; - sclr : in std_logic; - bypass : in std_logic; - a : in std_logic_vector(17 downto 0); - b : in std_logic_vector(17 downto 0); - s : out std_logic_vector(47 downto 0) - ); - end component; - --- Signals - signal do_sum_y : std_logic; - signal do_sum_y_dly : std_logic; - signal do_sum_cr : std_logic; - signal do_sum_cr_dly : std_logic; - signal do_sum_cb : std_logic; - signal do_sum_cb_dly : std_logic; - signal do_out : std_logic; - signal do_out_cr : std_logic; - signal do_out_cb : std_logic; - signal do_out_y : std_logic; - signal count_y : unsigned (2 downto 0); - signal count_cr : unsigned (2 downto 0); - signal count_cb : unsigned (2 downto 0); - signal y : signed(8 downto 0); - signal y_dly1 : signed(8 downto 0); - signal y_dly2 : signed(8 downto 0); - signal cb : signed(8 downto 0); - signal cb_dly1 : signed(8 downto 0); - signal cr : signed(8 downto 0); - signal cst_y_r : signed(17 downto 0); - signal cst_y_g : signed(17 downto 0); - signal cst_y_b : signed(17 downto 0); - signal cst_cb_r : signed(17 downto 0); - signal cst_cb_g : signed(17 downto 0); - signal cst_cb_b : signed(17 downto 0); - signal cst_cr_r : signed(17 downto 0); - signal cst_cr_g : signed(17 downto 0); - signal cst_cr_b : signed(17 downto 0); - - signal bypass_y : std_logic; - signal a_y : std_logic_vector(17 downto 0); - signal b_y : std_logic_vector(17 downto 0); - signal s_y : std_logic_vector(47 downto 0); - signal bypass_cr : std_logic; - signal a_cr : std_logic_vector(17 downto 0); - signal b_cr : std_logic_vector(17 downto 0); - signal s_cr : std_logic_vector(47 downto 0); - signal bypass_cb : std_logic; - signal a_cb : std_logic_vector(17 downto 0); - signal b_cb : std_logic_vector(17 downto 0); - signal s_cb : std_logic_vector(47 downto 0); - - signal compo_out : std_logic_vector(7 downto 0); - -begin - - y_multiplier : mult_accum - port map ( - clk => clk, - ce => '1', - sclr => '0', - bypass => bypass_y, - a => a_y, - b => b_y, - s => s_y - ); - cr_multiplier : mult_accum - port map ( - clk => clk, - ce => '1', - sclr => '0', - bypass => bypass_cr, - a => a_cr, - b => b_cr, - s => s_cr - ); - cb_multiplier : mult_accum - port map ( - clk => clk, - ce => '1', - sclr => '0', - bypass => bypass_cb, - a => a_cb, - b => b_cb, - s => s_cb - ); - - - cst_y_r <= to_signed(33658, 18); - cst_y_g <= to_signed(66077, 18); - cst_y_b <= to_signed(12833, 18); - cst_cb_r <= to_signed(-19428, 18); - cst_cb_g <= to_signed(-38141, 18); - cst_cb_b <= to_signed(57569, 18); - cst_cr_r <= to_signed(57569, 18); - cst_cr_g <= to_signed(-48207, 18); - cst_cr_b <= to_signed(-9362, 18); - - multy_process : process (clk, reset) - begin - if reset = '1' then - a_y <= (others => '0'); - b_y <= (others => '0'); - - count_y <= to_unsigned(0, 3); - do_sum_y <= '0'; - - elsif rising_edge(clk) then - - do_sum_y <= '0'; - - a_y <= (others => '0'); - b_y <= (others => '0'); - - if rgb_in_enb = '1' then - - a_y <= "0000000000" & rgb_in; - - if count_y = 0 then - b_y <= std_logic_vector(cst_y_b); - - count_y <= to_unsigned(1, 3); - - elsif count_y = 1 then - b_y <= std_logic_vector(cst_y_g); - count_y <= to_unsigned(2, 3); - - elsif count_y = 2 then - b_y <= std_logic_vector(cst_y_r); - count_y <= to_unsigned(0, 3); - do_sum_y <= '1'; - end if; - end if; - end if; - end process multy_process; - - sumy_process : process (clk, reset) - begin - if reset = '1' then - bypass_y <= '0'; - y <= to_signed(0, 9); - y_dly1 <= to_signed(0, 9); - y_dly2 <= to_signed(0, 9); - - elsif rising_edge(clk) then - bypass_y <= do_sum_y; - do_sum_y_dly <= do_sum_y; - y_dly1 <= y; - y_dly2 <= y_dly1; - - if do_sum_y_dly = '1' then - y <= to_signed(16, 9) + signed(s_y(25 downto 17)); - end if; - end if; - - end process sumy_process; - - multcb_process : process (clk, reset) - begin - if reset = '1' then - a_cb <= (others => '0'); - b_cb <= (others => '0'); - - count_cb <= to_unsigned(0, 3); - do_sum_cb <= '0'; - - elsif rising_edge(clk) then - - do_sum_cb <= '0'; - - a_cb <= (others => '0'); - b_cb <= (others => '0'); - - if rgb_in_enb = '1' then - - a_cb <= "0000000000" & rgb_in; - - if count_cb = 0 then - b_cb <= std_logic_vector(cst_cb_b); - - count_cb <= to_unsigned(1, 3); - - elsif count_cb = 1 then - b_cb <= std_logic_vector(cst_cb_g); - count_cb <= to_unsigned(2, 3); - - elsif count_cb = 2 then - b_cb <= std_logic_vector(cst_cb_r); - count_cb <= to_unsigned(0, 3); - do_sum_cb <= '1'; - end if; - end if; - end if; - end process multcb_process; - - sumcb_process : process (clk, reset) - begin - if reset = '1' then - bypass_cb <= '0'; - cb <= to_signed(0, 9); - cb_dly1 <= to_signed(0, 9); - elsif rising_edge(clk) then - bypass_cb <= do_sum_cb; - do_sum_cb_dly <= do_sum_cb; - cb_dly1 <= cb; - - if do_sum_cb_dly = '1' then - cb <= to_signed(128, 9) + signed(s_cb(25 downto 17)); - end if; - end if; - - end process sumcb_process; - - multcr_process : process (clk, reset) - begin - if reset = '1' then - a_cr <= (others => '0'); - b_cr <= (others => '0'); - - count_cr <= to_unsigned(0, 3); - do_sum_cr <= '0'; - - elsif rising_edge(clk) then - - do_sum_cr <= '0'; - - a_cr <= (others => '0'); - b_cr <= (others => '0'); - - if rgb_in_enb = '1' then - - a_cr <= "0000000000" & rgb_in; - - if count_cr = 0 then - b_cr <= std_logic_vector(cst_cr_b); - - count_cr <= to_unsigned(1, 3); - - elsif count_cr = 1 then - b_cr <= std_logic_vector(cst_cr_g); - count_cr <= to_unsigned(2, 3); - - elsif count_cr = 2 then - b_cr <= std_logic_vector(cst_cr_r); - count_cr <= to_unsigned(0, 3); - do_sum_cr <= '1'; - end if; - end if; - end if; - end process multcr_process; - - sumcr_process : process (clk, reset) - begin - if reset = '1' then - bypass_cr <= '0'; - cr <= to_signed(0, 9); - do_out_cr <= '0'; - - elsif rising_edge(clk) then - bypass_cr <= do_sum_cr; - do_sum_cr_dly <= do_sum_cr; - do_out_cr <= '0'; - - if do_sum_cr_dly = '1' then - do_out_cr <= '1'; - cr <= to_signed(128, 9) + signed(s_cr(25 downto 17)); - end if; - end if; - end process sumcr_process; - - out_process : process (clk, reset) - begin - if reset = '1' then - do_out_y <= '0'; - do_out_cb <= '0'; - elsif rising_edge(clk) then - do_out_cb <= do_out_cr; - do_out_y <= do_out_cb; - end if; - end process out_process; - - - ycbcr_out <= std_logic_vector(y_dly2(7 downto 0)) when do_out_y = '1' else - std_logic_vector(cb_dly1(7 downto 0)) when do_out_cb = '1' else - std_logic_vector(cr(7 downto 0)) when do_out_cr = '1' else - (others => '0'); - ycbcr_out_enb <= do_out_y or do_out_cb or do_out_cr; - -end rtl; -