fromClk->connectTo(toClk);\r
fromRst->connectTo(toRst);\r
}\r
+}\r
\r
+void AbstractBlock::generateEntity(QTextStream& out, bool hasController) throw(Exception) {\r
\r
+ out << "entity " << name << " is" << endl;\r
+ try {\r
+ generateEntityOrComponentBody(out, 0, hasController);\r
+ }\r
+ catch(Exception e) {\r
+ throw(e);\r
+ }\r
+ out << "end entity " << name << ";" << endl << endl;\r
}\r
\r
+void AbstractBlock::generateComponent(QTextStream& out, bool hasController) throw(Exception) {\r
+\r
+ out << " component " << name << " is" << endl;\r
+ try {\r
+ generateEntityOrComponentBody(out, 2, hasController);\r
+ }\r
+ catch(Exception e) {\r
+ throw(e);\r
+ }\r
+ out << " end component " << endl << endl;\r
+}\r
\r
\r
\r
public: \r
\r
+ enum BlockVHDLContext {AnyContext = 0, Entity = 1, Component = 2, Architecture = 3 }; // NB : 3 is when creating an instance of the block that owns this iface\r
+\r
AbstractBlock();\r
//AbstractBlock(const QString& _name);\r
virtual ~AbstractBlock();\r
bool isWBConfigurable();\r
\r
// others\r
- void connectClkReset() throw(Exception);\r
+ void connectClkReset() throw(Exception); \r
\r
virtual void generateVHDL(const QString& path) throw(Exception) = 0; // main entry to generate the VHDL code\r
-\r
+ void generateComponent(QTextStream& out, bool hasController=false) throw(Exception); // generate the component using reference\r
+ void generateEntity(QTextStream& out, bool hasController=false) throw(Exception); // generate the entity using reference\r
\r
virtual void parametersValidation(QList<AbstractBlock*>* checkedBlocks, QList<AbstractBlock*>* blocksToConfigure) = 0; // ugly but usefull \r
\r
AbstractBlock* parent;\r
\r
virtual void generateComments(QTextStream& out, QDomElement &elt, QString coreFile) throw(Exception) = 0; // generates comments from <comments> element\r
- virtual void generateLibraries(QTextStream& out, QDomElement &elt) throw(Exception) = 0; // generates libraries from <libraries> element\r
- virtual void generateEntity(QTextStream& out, bool hasController=false) throw(Exception) = 0; // generate the entity using reference\r
+ virtual void generateLibraries(QTextStream& out, QDomElement &elt) throw(Exception) = 0; // generates libraries from <libraries> element \r
virtual void generateArchitecture(QTextStream& out, QDomElement &elt ) throw(Exception) = 0; // generate the architecture using <architecture> element\r
virtual void generateController(QTextStream& out) throw(Exception) = 0; // generate the wishbone controller of the block\r
+ virtual void generateEntityOrComponentBody(QTextStream& out, int indentLevel, bool hasController=false) throw(Exception) = 0; // generate the entity/compo body using reference\r
\r
};\r
\r
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<BlockParameter*> listGenerics = owner->getGenericParameters();
+ QList<BlockParameter*> listUsers = owner->getUserParameters();
+ QList<BlockParameter*> 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){
else if (type == Expression) {
return "expression";
}
+ else if (type == Inherited) {
+ return "inherited";
+ }
return "invalid_type";
}
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<BlockParameter*> listGenerics = owner->getGenericParameters();
- QList<BlockParameter*> listUsers = owner->getUserParameters();
- QList<BlockParameter*> 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<BlockParameter*> listGenerics = owner->getGenericParameters();
+ QList<BlockParameter*> listUsers = owner->getUserParameters();
+ QList<BlockParameter*> 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;
}
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);
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;}
}\r
\r
BlockParameterGeneric::BlockParameterGeneric(AbstractBlock* _owner, const QString &_name, const QString &_type, const QString &_value) : BlockParameter(_owner, _name, _type, _value) {\r
+ /* CAUTION: no check done on the type parameter !\r
+ * It must never be "expression" but something that is numeric/boolean\r
+ */\r
userValue = defaultValue;\r
}\r
\r
throw(Exception(PROJECTFILE_CORRUPTED));
}
if (referenceMd5 != referenceXml) {
- throw(Exception(PROJECTFILE_CORRUPTED));
+ reference = referenceXml;
}
else {
reference = referenceMd5;
}\r
}\r
\r
-void FunctionalBlock::generateEntity(QTextStream& out, bool hasController) throw(Exception) {\r
+\r
+void FunctionalBlock::generateEntityOrComponentBody(QTextStream& out, int indentLevel, bool hasController) throw(Exception) {\r
\r
int i=0;\r
+ QString indent = "";\r
+ for(i=0;i<indentLevel;i++) {\r
+ indent += " ";\r
+ }\r
\r
//QList<BlockParameter*> listParams = reference->getParameters();\r
QList<AbstractInterface*> listInputs = getInputs();\r
QList<AbstractInterface*> listOutputs = getOutputs();\r
- QList<AbstractInterface*> listBidirs = getBidirs();\r
- QString typePort, namePort;\r
-\r
- out << "entity " << name << " is" << endl;\r
-\r
-\r
- /* TODO : rewrite the generation to take into acocunt the new object hierarchy */\r
+ QList<AbstractInterface*> listBidirs = getBidirs(); \r
\r
// Generation of the generics\r
QList<BlockParameter*> listGenerics = getGenericParameters();\r
if ((!listGenerics.isEmpty()) || (hasController)) {\r
- out << " generic (" << endl;\r
+ out << indent << " generic (" << endl;\r
if (hasController) {\r
- out << " wb_data_width : integer = 16;" << endl;\r
- out << " wb_addr_width : integer = 12";\r
- if (!listGenerics.isEmpty()) out << ";";\r
+ out << indent << " wb_data_width : integer = 16;" << endl;\r
+ out << indent << " wb_addr_width : integer = 12";\r
+ if (!listGenerics.isEmpty()) out << indent << ";";\r
out << endl;\r
}\r
for(i=0;i<listGenerics.size()-1;i++) {\r
- out << " " << listGenerics.at(i)->toVHDL(BlockParameter::Entity, 0) << endl;\r
+ out << indent << " " << listGenerics.at(i)->toVHDL(BlockParameter::Entity, 0) << endl;\r
}\r
- out << " " << listGenerics.at(i)->toVHDL(BlockParameter::Entity,BlockParameter::NoComma) << endl;\r
+ out << indent << " " << listGenerics.at(i)->toVHDL(BlockParameter::Entity,BlockParameter::NoComma) << endl;\r
\r
- out << " );" << endl;\r
+ out << indent << " );" << endl;\r
}\r
\r
- out << " port (" << endl;\r
+ out << indent << " port (" << endl;\r
\r
// Generation of the clk & rst signals\r
- out << " -- clk/rst" << endl;\r
+ out << indent << " -- clk/rst" << endl;\r
foreach(AbstractInterface* iface, listInputs) {\r
if(iface->getPurpose() == AbstractInterface::Clock || iface->getPurpose() == AbstractInterface::Reset) {\r
- out << " " << iface->getName() << " : in std_logic;" << endl;\r
+ out << indent << " " << iface->getName() << " : in std_logic;" << endl;\r
+ }\r
+ }\r
+ foreach(AbstractInterface* iface, listOutputs) {\r
+ if(iface->getPurpose() == AbstractInterface::Clock || iface->getPurpose() == AbstractInterface::Reset) {\r
+ out << indent << " " << iface->getName() << " : out std_logic;" << endl;\r
}\r
}\r
\r
if (hasController) {\r
// Generation of the wishbone signals\r
- out << " -- registers r/w via wishbone" << endl;\r
+ out << indent << " -- registers r/w via wishbone" << endl;\r
QList<BlockParameter*> listWB = reference->getWishboneParameters();\r
for(i=0;i<listWB.size()-1;i++) {\r
- out << " " << listWB.at(i)->toVHDL(BlockParameter::Entity, 0) << endl;\r
+ out << indent << " " << listWB.at(i)->toVHDL(BlockParameter::Entity, 0) << endl;\r
}\r
- out << " " << listWB.at(i)->toVHDL(BlockParameter::Entity,BlockParameter::NoComma) << endl;\r
+ out << indent << " " << listWB.at(i)->toVHDL(BlockParameter::Entity,BlockParameter::NoComma) << endl;\r
}\r
\r
\r
foreach(AbstractInterface* iface, listInputs) {\r
if(iface->getPurpose() == AbstractInterface::Data) {\r
if (first) {\r
- out << " -- input data ports" << endl;\r
+ out << indent << " -- input data ports" << endl;\r
first = false;\r
}\r
count--;\r
if (count == 0) flag = AbstractInterface::NoComma;\r
- out << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl;\r
+ out << indent << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl;\r
}\r
}\r
first = true;\r
foreach(AbstractInterface* iface, listInputs) {\r
if(iface->getPurpose() == AbstractInterface::Control) {\r
if (first) {\r
- out << " -- input control ports" << endl;\r
+ out << indent << " -- input control ports" << endl;\r
first = false;\r
}\r
count--;\r
if (count == 0) flag = AbstractInterface::NoComma;\r
- out << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl;\r
+ out << indent << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl;\r
}\r
}\r
first = true;\r
foreach(AbstractInterface* iface, listOutputs) {\r
if(iface->getPurpose() == AbstractInterface::Data) {\r
if (first) {\r
- out << " -- output data ports" << endl;\r
+ out << indent << " -- output data ports" << endl;\r
first = false;\r
}\r
count--;\r
if (count == 0) flag = AbstractInterface::NoComma;\r
- out << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl;\r
+ out << indent << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl;\r
}\r
}\r
first = true;\r
foreach(AbstractInterface* iface, listOutputs) {\r
if(iface->getPurpose() == AbstractInterface::Control) {\r
if (first) {\r
- out << " -- output control ports" << endl;\r
+ out << indent << " -- output control ports" << endl;\r
first = false;\r
}\r
count--;\r
if (count == 0) flag = AbstractInterface::NoComma;\r
- out << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl;\r
+ out << indent << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl;\r
}\r
}\r
first = true;\r
foreach(AbstractInterface* iface, listBidirs) {\r
if(iface->getPurpose() == AbstractInterface::Data) {\r
if (first) {\r
- out << " -- bidirs data ports" << endl;\r
+ out << indent << " -- bidirs data ports" << endl;\r
first = false;\r
}\r
count--;\r
if (count == 0) flag = AbstractInterface::NoComma;\r
- out << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl;\r
+ out << indent << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl;\r
}\r
}\r
- out << " );" << endl << endl;\r
- out << "end " << name << ";" << endl << endl;\r
+ out << indent << " );" << endl << endl;\r
+\r
}\r
\r
void FunctionalBlock::generateArchitecture(QTextStream& out, QDomElement &elt ) throw(Exception) {\r
// others\r
\r
void populate(); // create parameters and interface from reference block\r
- void generateVHDL(const QString& path) throw(Exception); // main entry to generate the VHDL code\r
+ void generateVHDL(const QString& path) throw(Exception); // main entry to generate the VHDL code \r
+\r
void parametersValidation(QList<AbstractBlock *> *checkedBlocks, QList<AbstractBlock*>* blocksToConfigure);\r
\r
QString getReferenceXmlFile();\r
\r
void generateComments(QTextStream& out, QDomElement &elt, QString coreFile) throw(Exception); // generates comments from <comments> element\r
void generateLibraries(QTextStream& out, QDomElement &elt) throw(Exception); // generates libraries from <libraries> element\r
- void generateEntity(QTextStream& out, bool hasController=false) throw(Exception); // generate the entity using reference\r
void generateArchitecture(QTextStream& out, QDomElement &elt ) throw(Exception); // generate the architecture using <architecture> element\r
void generateController(QTextStream& out) throw(Exception); // generate the wishbone controller of the block\r
+ void generateEntityOrComponentBody(QTextStream& out, int indentLevel, bool hasController=false) throw(Exception); // generate the entity/compo body using reference\r
\r
QMap<AbstractInterface*, QList<char>* > consumptionPattern;\r
QMap<AbstractInterface*, QString > admittanceCyclic; // the admittance expressed as prologue-cyclic part-epilogue, deduced from admittance\r
name = reference->getName();\r
type = reference->getType();\r
endianess = reference->getEndianess();\r
- width = reference->getWidth();\r
+ width = reference->getWidthString();\r
direction = reference->getDirection();\r
purpose = reference->getPurpose(); \r
connectedFrom = NULL; \r
}
-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<indentLevel;i++) {
+ indent += " ";
+ }
QList<BlockParameter*> listGenerics = getGenericParameters();
QList<AbstractInterface*> listInputs = getInputs();
QList<AbstractInterface*> listBidirs = getBidirs();
if (!listGenerics.isEmpty()) {
- out << " generic (" << endl;
+ out << indent << " generic (" << endl;
for(i=0;i<listGenerics.size()-1;i++) {
- out << " " << listGenerics.at(i)->toVHDL(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;
}
}
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<AbstractInterface*> 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<AbstractInterface*> 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) {
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
void createInputPattern();
void generateComments(QTextStream& out, QDomElement &elt, QString coreFile) throw(Exception); // generates comments from <comments> element
- void generateLibraries(QTextStream& out, QDomElement &elt) throw(Exception); // generates libraries from <libraries> 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 <libraries> element
void generateArchitecture(QTextStream& out, QDomElement &elt ) throw(Exception); // generate the architecture using <architecture> 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<AbstractBlock*> blocks; // contains instances of FunctionalBlock or GroupBlock that are children of this group
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() {
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) {
GroupInterface(AbstractBlock* _owner, const QString& _name, int _direction, int _purpose) throw (Exception);
// getters
+ int getWidth();
// setters
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);
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);
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();
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();
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();
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();
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();
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));
}
void computeAdmittanceDelays() throw(Exception);
void generateComments(QTextStream& out, QDomElement &elt, QString coreFile) throw(Exception); // generates comments from <comments> element
- void generateLibraries(QTextStream& out, QDomElement &elt) throw(Exception); // generates libraries from <libraries> 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 <libraries> element
void generateArchitecture(QTextStream& out, QDomElement &elt ) throw(Exception); // generate the architecture using <architecture> 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__
else {\r
widthStr = "std_logic_vector(";\r
if (iface->getEndianess() == AbstractInterface::LittleEndian) {\r
- widthStr += iface->getWidth();\r
+ widthStr += iface->getWidthString();\r
widthStr += " downto 0)";\r
}\r
else {\r
widthStr += "0 to ";\r
- widthStr += iface->getWidth();\r
+ widthStr += iface->getWidthString();\r
widthStr += ")";\r
}\r
}\r
QDomElement input = doc.createElement("input");\r
input.setAttribute("name",iface->getName());\r
input.setAttribute("type",iface->getTypeString());\r
- input.setAttribute("width",iface->getWidth());\r
+ input.setAttribute("width",iface->getWidthString());\r
input.setAttribute("multiplicity","1");\r
input.setAttribute("purpose",iface->getPurposeString());\r
input.setAttribute("endian",iface->getEndianessString());\r
QDomElement output = doc.createElement("output");\r
output.setAttribute("name",iface->getName());\r
output.setAttribute("type",iface->getTypeString());\r
- output.setAttribute("width",iface->getWidth());\r
+ output.setAttribute("width",iface->getWidthString());\r
output.setAttribute("multiplicity","1");\r
output.setAttribute("purpose",iface->getPurposeString());\r
output.setAttribute("endian",iface->getEndianessString());\r
QDomElement bidir = doc.createElement("bidir");\r
bidir.setAttribute("name",iface->getName());\r
bidir.setAttribute("type",iface->getTypeString());\r
- bidir.setAttribute("width",iface->getWidth());\r
+ bidir.setAttribute("width",iface->getWidthString());\r
bidir.setAttribute("multiplicity","1");\r
bidir.setAttribute("purpose",iface->getPurposeString());\r
bidir.setAttribute("endian",iface->getEndianessString());\r
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
-<!-- Written by QtCreator 4.2.0, 2018-03-23T16:06:12. -->
+<!-- Written by QtCreator 4.2.0, 2018-03-27T18:47:18. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
- <value type="QByteArray">{eddbf04f-e5ee-4f36-bc65-6ab7f2b6d4ec}</value>
+ <value type="QByteArray">{3701e197-5b6c-48ea-9e98-a6cf6de18672}</value>
</data>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<valuemap type="QVariantMap">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
- <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{72d0832a-d73b-473a-b29c-d1c0737451fe}</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{ed04208c-8774-456b-99b9-4a02094ca7a4}</value>
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
+++ /dev/null
--------------------------------------------------------------------------------
---
--- 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;
-
+++ /dev/null
--------------------------------------------------------------------------------
---
--- 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;
-
+++ /dev/null
--------------------------------------------------------------------------------
---
--- 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;
-
<inputs>
<input endian="little" type="boolean" purpose="clock" multiplicity="1" width="1" name="clk"/>
<input endian="little" type="boolean" purpose="reset" multiplicity="1" width="1" name="reset"/>
- <input endian="little" type="natural" purpose="data" multiplicity="1" width="7" name="pix_in"/>
+ <input endian="little" type="natural" purpose="data" multiplicity="1" width="8" name="pix_in"/>
<control iface="pix_in"/>
</inputs>
<outputs>
- <output endian="little" type="natural" purpose="data" multiplicity="1" width="7" name="pix_out"/>
+ <output endian="little" type="natural" purpose="data" multiplicity="1" width="8" name="pix_out"/>
<control iface="pix_out"/>
</outputs>
</interfaces>
<inputs>
<input endian="little" type="boolean" purpose="clock" multiplicity="1" width="1" name="clk"/>
<input endian="little" type="boolean" purpose="reset" multiplicity="1" width="1" name="reset"/>
- <input endian="little" type="natural" purpose="data" multiplicity="1" width="7" name="rgb_in"/>
+ <input endian="little" type="natural" purpose="data" multiplicity="1" width="8" name="rgb_in"/>
<control iface="rgb_in"/>
</inputs>
<outputs>
- <output endian="little" type="natural" purpose="data" multiplicity="1" width="7" name="gs_out"/>
+ <output endian="little" type="natural" purpose="data" multiplicity="1" width="8" name="gs_out"/>
<control iface="gs_out"/>
</outputs>
</interfaces>
<inputs>
<input endian="little" type="boolean" purpose="clock" multiplicity="1" width="1" name="clk"/>
<input endian="little" type="boolean" purpose="reset" multiplicity="1" width="1" name="reset"/>
- <input endian="little" type="natural" purpose="data" multiplicity="1" width="7" name="rgb_in"/>
+ <input endian="little" type="natural" purpose="data" multiplicity="1" width="8" name="rgb_in"/>
<control iface="rgb_in"/>
</inputs>
<outputs>
- <output endian="little" type="natural" purpose="data" multiplicity="1" width="7" name="ycbcr_out"/>
+ <output endian="little" type="natural" purpose="data" multiplicity="1" width="8" name="ycbcr_out"/>
<control iface="ycbcr_out"/>
</outputs>
</interfaces>
+++ /dev/null
--------------------------------------------------------------------------------
---
--- 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;
-
+++ /dev/null
--------------------------------------------------------------------------------
---
--- 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;
-
+++ /dev/null
--------------------------------------------------------------------------------
---
--- 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;
-