From 6e2b3026c6a496e81642c373796bd39dad33d2a6 Mon Sep 17 00:00:00 2001 From: stephane Domas Date: Thu, 29 Mar 2018 17:20:07 +0200 Subject: [PATCH 1/1] started VHDL generation of GroupBlock --- AbstractBlock.cpp | 21 ++ AbstractBlock.h | 11 +- AbstractInterface.cpp | 237 ++++++++++--- AbstractInterface.h | 5 +- BlockParameterGeneric.cpp | 3 + BoxItem.cpp | 2 +- FunctionalBlock.cpp | 70 ++-- FunctionalBlock.h | 5 +- FunctionalInterface.cpp | 2 +- GroupBlock.cpp | 102 ++++-- GroupBlock.h | 7 +- GroupInterface.cpp | 25 ++ GroupInterface.h | 1 + InterfacePropertiesWindow.cpp | 11 +- ReferenceBlock.cpp | 16 +- ReferenceBlock.h | 5 +- VHDLConverter.cpp | 10 +- blast.creator.user | 6 +- boxfilter_3x3.vhd | 421 ----------------------- checker.vhd | 94 ----- deserializer_3x1.vhd | 96 ------ lib/implementations/impls.bmf | Bin 0 -> 5807 bytes lib/references/boxfilter_3x3.xml | 4 +- lib/references/references.bmf | Bin 0 -> 21052 bytes lib/references/rgb3sx8_to_gs.xml | 4 +- lib/references/rgb3sx8_to_ycbcr_3DSP.xml | 4 +- logical_AND_3.vhd | 65 ---- rgb3sx8_to_gs.vhd | 102 ------ rgb3sx8_to_ycbcr_3DSP.vhd | 337 ------------------ 29 files changed, 399 insertions(+), 1267 deletions(-) delete mode 100644 boxfilter_3x3.vhd delete mode 100644 checker.vhd delete mode 100644 deserializer_3x1.vhd create mode 100644 lib/implementations/impls.bmf create mode 100644 lib/references/references.bmf delete mode 100644 logical_AND_3.vhd delete mode 100644 rgb3sx8_to_gs.vhd delete mode 100644 rgb3sx8_to_ycbcr_3DSP.vhd 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 0000000000000000000000000000000000000000..cba0a1de5960b384f217ea5989e951606c2567df GIT binary patch literal 5807 zcmd6rzit~x5XOf}kQgomB@hk*VWMaoCr+_fz@Q3_w$UPj|jXJoFOiVU#Or2Vht6#=^siVxHYPtMTj5u!X$&1s;{Z_fuYBQeb4 zKz?MO+~$3PsKGDW+$QxV|7geeNsC5^@?I%C8nT%V@;Wm73xKEbvl>kT}X z+AeW;UI7UY;6RtM`FKh|J*Ae&oKhL9p-jHQkwumWmr*F2%k_{%CbNXxS|C%T#mCS> zZPkMfTX24!JYLFd{)zmHN?_{)+0bOvN>j;g?92!yQhq$s&h*IrN z9V*HN4smum;#JHHC_F8ES7Z)n<;OaNt*Wf?W)UaWu;v+X;yQ~}%42jL18U!JS49g| zkPckTwcic!S=(rg1?vvbvTOmkRb2Hg)J$*BQY+O)>(g3U*7H?3)C^l`-6fmV;dyP< zwB-7oyI(6vE`|09X>Z-ASdTt;aN2qRVJw+`!+|#yIWTfb)Pu7+eg5n|S%1G7Wyz*< zYmrvqEPfFq?HTHJy6}DiKlE4RBd$7I*l?z^o=+=3l3jA6l`p|wQV)AR$>!fky7SiV za*is7Ei2MC^ZInvTBdVJxo~f|x%k)xEl+QgFN7f@Z8d5?U?{A2_{ookCzXOak?I%` z)1J&mq>i&XZ(CE8pQT6q`M-ea$D8wlY4Qay_mZ<$-c)p+RiL*POtgxQGJct|to#jU z&&?_9{=oT!>_PYK%kMN{uW;TAr)LetvU~Bl_+50Kzvx}8sXoT5Du~s`zeDozz?IFG zd__y$!|V9F=>|MV$rp%a4NWPLPa9gW=3jP9DwnWIU7lof2|HL>Li0YCDwojtDfSPf zs~G;ZiR!zjj(i=5MzPsut`X-l0j#lxyHycyhOnj$OGeBLw{b)(e2ZtJs8btMg_L~Y zAie}mc6F*$yuFN1+P;JV&%+YtIm()H5;40E;=1r`W|eBubTL<9Y7c;-ib+_%c+!{35&s9&8m%&2l5~vwV?M_iw#mw3ttedj^+M*p V$LR76Mlnqdu=J#y1A5M~{Q-F;#t#4h literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..925725ebf4bac753a45a7c5e2720040f86612e78 GIT binary patch literal 21052 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 Qt|sG$oK#24lNAg91+5-yiU0rr literal 0 HcmV?d00001 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; - -- 2.39.5