catch(Exception e) {\r
throw(e);\r
}\r
- out << " end component " << endl << endl;\r
+ out << " end component; " << endl << endl;\r
}\r
\r
\r
\r
// others\r
void connectClkReset() throw(Exception); \r
-\r
+ virtual QList<QString> getExternalResources() = 0; // returns the list of all external files needed for VHDL generation\r
virtual void generateVHDL(const QString& path) throw(Exception) = 0; // main entry to generate the VHDL code\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
return true; \r
}\r
\r
-QString BlockImplementation::eval(QString line, QTextStream& out) {\r
- QString res, s, begLine, endLine, expr;\r
- evaluator->setExpression(line);\r
- QRegExp *rxString = new QRegExp("(.*)@{(.*)}(.*)");\r
- QRegExp *rxValue = new QRegExp("(.*)@val{(.*)}(.*)");\r
- QRegExp *rxExpr = new QRegExp(".*@eval{(.*)}.*");\r
-\r
- int nbAt = line.count('@');\r
- while(nbAt != 0) {\r
- for(int i = 0; i < line.size(); i++) {\r
- if(rxString->indexIn(line)) {\r
- begLine = rxString->cap(1);\r
- s = rxString->cap(2);\r
- endLine = rxString->cap(3);\r
- res = begLine + evalString(s) + endLine + '\n';\r
- nbAt --;\r
- }\r
- }\r
- for(int i = 0; i < line.size(); i++) {\r
- if(rxValue->indexIn(line)) {\r
- begLine = rxValue->cap(1);\r
- s = rxValue->cap(2);\r
- endLine = rxValue->cap(3);\r
- res = begLine + evalValue(s) + endLine + '\n';\r
- nbAt --;\r
- }\r
- }\r
- for(int i = 0; i < line.size(); i++) {\r
- if(rxExpr->indexIn(line)) {\r
- expr = rxExpr->cap(1);\r
- if(expr.count('@') == 0) {\r
- evaluator->setExpression(expr);\r
- s = QString::number(evaluator->evaluate());\r
- }\r
- res = begLine + s + endLine + '\n';\r
- nbAt --;\r
- }\r
- }\r
- }\r
- return res;\r
-}\r
-\r
-QString BlockImplementation::evalComplex(QString line, int id) {\r
- QString res, s, begLine, endLine, expr;\r
- QRegExp *rxString = new QRegExp("(.*)@{(.*)}(.*)");\r
- QRegExp *rxValue = new QRegExp("(.*)@val{(.*)}(.*)");\r
- QRegExp *rxExpr = new QRegExp(".*@eval{(.*)}.*");\r
- QRegExp *rxFor = new QRegExp("@foreach{.*}(@{.*})(.*)@endforeach");\r
- QRegExp *rxCase = new QRegExp("@caseeach{.*,(.*),(.*)}(@{.*})(.*)@endcaseeach");\r
- QRegExp *rxCaseDown = new QRegExp("@#-:(.*)");\r
- QRegExp *rxCaseUp = new QRegExp("@#:(.*)");\r
- evaluator->setExpression(line);\r
-\r
- int nbAt = line.count('@') - 2;\r
- while(nbAt != 0) {\r
- for(int i = 0; i < line.size(); i++) {\r
- if(rxString->indexIn(line)) {\r
- begLine = rxString->cap(1);\r
- s = rxString->cap(2);\r
- endLine = rxString->cap(3);\r
- if(evalStringComplex(s)->size() == 0)\r
- line = begLine + evalString(s) + endLine;\r
- nbAt --;\r
- }\r
- }\r
- for(int i = 0; i < line.size(); i++) {\r
- if(rxValue->indexIn(line)) {\r
- begLine = rxValue->cap(1);\r
- s = rxValue->cap(2);\r
- endLine = rxValue->cap(3);\r
- line = begLine + evalValue(s) + endLine;\r
- nbAt --;\r
- }\r
- }\r
- for(int i = 0; i < line.size(); i++) {\r
- if(rxExpr->indexIn(line)) {\r
- expr = rxExpr->cap(1);\r
- if(expr.count('@') == 0) {\r
- evaluator->setExpression(expr);\r
- s = QString::number(evaluator->evaluate());\r
- }\r
- res = begLine + s + endLine + '\n';\r
- nbAt --;\r
- }\r
- }\r
- }\r
-\r
- if(id == 1) {\r
- if(rxFor->indexIn(line)) {\r
- QString intName, instruc;\r
- intName = rxFor->cap(1);\r
- instruc = rxFor->cap(2);\r
- QList<AbstractInterface*> *intList = evalStringComplex(intName);\r
- if(intList->size() != 0) {\r
- for(int i = 0; i < intList->size(); i++) {\r
- res = intList->at(i)->getName() + instruc + '\n';\r
- }\r
- }\r
- }\r
- }\r
-\r
- else if(id == 2) {\r
- if(rxCase->indexIn(line)) {\r
- QString intName, sigName, cases, instruc;\r
- int number;\r
- sigName = rxCase->cap(1);\r
- cases = rxCase->cap(2);\r
- intName = rxCase->cap(3);\r
- instruc = rxCase->cap(4);\r
- QList<AbstractInterface*> *intList = evalStringComplex(intName);\r
- int listSize = intList->count();\r
- res = "case " + sigName + " is\n";\r
- if(rxCaseUp->indexIn(cases)) {\r
- number = rxCaseUp->cap(1).toInt();\r
- for(int j = number; j < listSize; j++) {\r
- if(listSize > 0) {\r
- for(int i = 0; i < listSize; i++) {\r
- res += "\twhen " + QString::number(number) + " " + intList->at(i)->getName() + instruc + "\n";\r
- }\r
- }\r
- else\r
- res += "\twhen " + number + ' ' + intName + instruc + "\n";\r
- number++;\r
- }\r
- }\r
- if(rxCaseDown->indexIn(cases)) {\r
- number = rxCaseDown->cap(1).toInt();\r
- for(int j = number; j < listSize; j++) {\r
- if(listSize > 0) {\r
- for(int i = 0; i < listSize; i++) {\r
- res += "\twhen " + QString::number(number) + " " + intList->at(i)->getName() + instruc + "\n";\r
- }\r
- }\r
- else\r
- res += "\twhen " + number + ' ' + intName + instruc + "\n";\r
- number--;\r
- }\r
- res += "end case ;\n";\r
- }\r
- }\r
- }\r
- return res;\r
-}\r
-\r
-QString BlockImplementation::evalString(QString s) {\r
-\r
- QString name = getIfaceUserName(block->AbstractBlock::getIfaceFromName(s));\r
- return name;\r
-}\r
-\r
-QList<AbstractInterface*>* BlockImplementation::evalStringComplex(QString s) {\r
-\r
- int j = 0;\r
- QList<AbstractInterface*> *listInterfaces = new QList<AbstractInterface*>();\r
- AbstractInterface *inter = block->AbstractBlock::getIfaceFromName(s);\r
- QList<AbstractInterface*> listIntBlock = block->getInterfaces();\r
- for(int i = 0; i < listIntBlock.size(); i++) {\r
- if(inter->getName().compare(listIntBlock.at(i)->getName()) < -1) {\r
- listInterfaces->insert(j, inter);\r
- j ++;\r
- }\r
- }\r
- return listInterfaces;\r
-}\r
-\r
-QString BlockImplementation::evalValue(QString s) {\r
-\r
- QString val = "";\r
- if(paramMap.contains(s))\r
- val = paramMap.value(s);\r
- return val;\r
-}\r
-\r
-QString BlockImplementation::getIfaceUserName(AbstractInterface* refIface) {\r
-\r
- if (! refIface->isReferenceInterface()) return "";\r
-\r
- AbstractInterface* funcIface = NULL;\r
-\r
- if (refIface->getDirection() == AbstractInterface::Input) {\r
- foreach(AbstractInterface* iface, block->getInputs()) {\r
- FunctionalInterface* fi = (FunctionalInterface*)iface;\r
- if (fi->getReference() == refIface) {\r
- funcIface = iface;\r
- break;\r
- }\r
- }\r
- }\r
- else if (refIface->getDirection() == AbstractInterface::Output) {\r
- foreach(AbstractInterface* iface, block->getOutputs()) {\r
- FunctionalInterface* fi = (FunctionalInterface*)iface;\r
- if (fi->getReference() == refIface) {\r
- funcIface = iface;\r
- break;\r
- }\r
- }\r
- }\r
- else if (refIface->getDirection() == AbstractInterface::InOut) {\r
- foreach(AbstractInterface* iface, block->getBidirs()) {\r
- FunctionalInterface* fi = (FunctionalInterface*)iface;\r
- if (fi->getReference() == refIface) {\r
- funcIface = iface;\r
- break;\r
- }\r
- }\r
- }\r
- if (funcIface == NULL) return "";\r
-\r
- return funcIface->getName();\r
-}\r
-\r
QDataStream& operator<<(QDataStream &out, const BlockImplementation &impl) {\r
\r
out.setVersion(QDataStream::Qt_5_0);\r
toWrite << impl.xmlFile;\r
toWrite << impl.referenceXml;\r
toWrite << impl.referenceMd5;\r
+ toWrite << impl.resources;\r
// saving patterns\r
toWrite << impl.noPatterns;\r
toWrite << impl.delta;\r
in >> impl.xmlFile;\r
in >> impl.referenceXml;\r
in >> impl.referenceMd5;\r
+ in >> impl.resources;\r
// loading patterns\r
in >> impl.noPatterns;\r
in >> impl.delta;\r
\r
return in;\r
}\r
-\r
-QString BlockImplementation::calculateWidth(QString s){\r
- QRegExp *rxWidth = new QRegExp("$*([a-zA-Z0-9_-]*)");\r
- QStringList matchList = s.split(" ");\r
- int pos = 0;\r
- QString res, line;\r
- QList<BlockParameter*> listParams = reference->getParameters();\r
-\r
- while ((pos = rxWidth->indexIn(s, pos)) != -1) {\r
- matchList << rxWidth->cap(1);\r
- pos += rxWidth->matchedLength();\r
- }\r
-\r
- for (int i = 0; i < matchList.size(); i++) {\r
- QString match = matchList.at(i);\r
- if(rxWidth->indexIn(match)) {\r
- for(int j = 0; j < listParams.size(); j++) {\r
- if(match.compare(listParams.at(j)->getName())) {\r
- BlockParameter *param = listParams.at(i);\r
- if(param->getContext() == "generic") {\r
- match = match.remove('$');\r
- }\r
- else {\r
- match = param->getValue().toString();\r
- }\r
- }\r
- }\r
- }\r
- }\r
- line = matchList.join(' ');\r
- evaluator->setExpression(line);\r
- res = evaluator->evaluate();\r
- return res;\r
-}\r
-\r
inline QHash<QString,QString> getConsumptionPattern() { return consumptionPattern; }\r
inline QHash<QString,QString> getProductionPattern() { return productionPattern; }\r
inline QString getProductionCounter() { return productionCounter; }\r
+ inline QList<QString> getResources() { return resources; }\r
\r
// setters\r
inline void setDelta(QString _delta) { delta = _delta; }\r
\r
inline bool hasNoPatterns() { return noPatterns; }\r
\r
- QString eval(QString line, QTextStream& out);\r
- QString evalComplex(QString line, int num);\r
- QString evalString(QString s);\r
- QList<AbstractInterface*>* evalStringComplex(QString s);\r
- QString evalValue(QString s);\r
- QString calculateWidth(QString s);\r
-\r
inline void setReference(ReferenceBlock* _reference) { reference = _reference; }\r
\r
void loadPatterns(QDomElement &root) throw(Exception);\r
bool checkPatterns(); \r
\r
- inline void addSource(QString file) { sources.append(file); }\r
+ inline void addResource(QString file) { resources.append(file); }\r
private: \r
QString xmlFile;\r
QString referenceXml;\r
QString referenceMd5;\r
\r
- QList<QString> sources;\r
+ QList<QString> resources;\r
\r
QMap<QString, int> paramMap;\r
ArithmeticEvaluator* evaluator;\r
QString delta;\r
QHash<QString,QString> consumptionPattern; // key = reference interface name, value = pattern expression\r
QHash<QString,QString> productionPattern; // key = reference interface name, value = pattern expression\r
- QString productionCounter;\r
-\r
- QString getIfaceUserName(AbstractInterface* refIface); // get the name of an interface given by the user, from the reference interface\r
+ QString productionCounter; \r
\r
friend QDataStream &operator<<(QDataStream &out, const BlockImplementation &impl);\r
friend QDataStream &operator>>(QDataStream &in, BlockImplementation &impl);\r
formatNoValue.append(";");\r
}\r
\r
- if (!userValue.isNull()) {\r
- ret = formatValue.arg(name).arg(getTypeString()).arg(userValue.toString());\r
- }\r
- else if (!defaultValue.isNull()) {\r
- ret = formatValue.arg(name).arg(getTypeString()).arg(defaultValue.toString());\r
+ QString typeStr = "";\r
+ QString valueStr = "";\r
+ if ((type == Boolean)||(type == Bit)) {\r
+ typeStr = "std_logic";\r
+ if (!userValue.isNull()) {\r
+ valueStr = "'"+userValue.toString()+"'";\r
+ ret = formatValue.arg(name).arg(typeStr).arg(valueStr);\r
+ }\r
+ else if (!defaultValue.isNull()) {\r
+ valueStr = "'"+defaultValue.toString()+"'";\r
+ ret = formatValue.arg(name).arg(typeStr).arg(valueStr);\r
+ }\r
+ else {\r
+ ret = formatNoValue.arg(name).arg(typeStr);\r
+ }\r
}\r
else {\r
- ret = formatNoValue.arg(name).arg(getTypeString());\r
+ typeStr = getTypeString();\r
+ if (!userValue.isNull()) {\r
+ ret = formatValue.arg(name).arg(typeStr).arg(userValue.toString());\r
+ }\r
+ else if (!defaultValue.isNull()) {\r
+ ret = formatValue.arg(name).arg(typeStr).arg(defaultValue.toString());\r
+ }\r
+ else {\r
+ ret = formatNoValue.arg(name).arg(typeStr);\r
+ }\r
}\r
}\r
else if (context == BlockParameter::Instance) {\r
}\r
else {\r
if (!userValue.isNull()) {\r
- ret = format.arg(name).arg(userValue.toString());\r
+ if ((type == Boolean)||(type == Bit)) {\r
+ ret = format.arg(name).arg("'"+userValue.toString()+"'");\r
+ }\r
+ else {\r
+ ret = format.arg(name).arg(userValue.toString());\r
+ }\r
}\r
else if (!defaultValue.isNull()) {\r
- ret = format.arg(name).arg(defaultValue.toString());\r
+ if ((type == Boolean)||(type == Bit)) {\r
+ ret = format.arg(name).arg("'"+defaultValue.toString()+"'");\r
+ }\r
+ else {\r
+ ret = format.arg(name).arg(defaultValue.toString());\r
+ }\r
}\r
else {\r
// abnormal case\r
dm1.setNum(delayLength-1);\r
dm2.setNum(delayLength-2);\r
QString ret="";\r
+ QString clkName = "clk";\r
+ QString resetName = "reset";\r
+ if (toIface->getOwner()->getParent()->isTopGroupBlock()) {\r
+ clkName = "from_clkrstgen_clk";\r
+ resetName ="from_clkrstgen_reset";\r
+ }\r
+\r
if (context == Architecture) {\r
- ret = toName + "_mod_process : process(clk,reset)\n";\r
+ ret = toName + "_mod_process : process("+clkName+","+resetName+")\n";\r
ret += " begin\n";\r
- ret += " if reset = '1' then\n";\r
+ ret += " if "+resetName+" = '1' then\n";\r
ret += " "+toName+"_dly <= (others => (others => '0'));\n";\r
ret += " "+toCtlName+"_dly <= (others => '0');\n";\r
ret += " "+toName+"_mod <= (others => '0');\n";\r
ret += " "+toCtlName+"_mod <= '0';\n";\r
- ret += " elsif rising_edge(clk) then\n";\r
+ ret += " elsif rising_edge("+clkName+") then\n";\r
ret += " "+toName+"_mod <= "+toName+"_dly("+dm1+");\n";\r
ret += " "+toCtlName+"_mod <= "+toCtlName+"_dly("+dm1+");\n";\r
ret += " "+toName+"_dly(0) <= "+fromIface->toVHDL(AbstractInterface::Instance,0)+";\n";\r
ret += " "+toCtlName+"_dly(0) <= "+fromCtlIface->toVHDL(AbstractInterface::Instance,0)+";\n";\r
ret += " "+toName+"_dly(1 to "+dm1+") <= "+toName+"_dly(0 to "+dm2+");\n";\r
ret += " "+toCtlName+"_dly(1 to "+dm1+") <= "+toCtlName+"_dly(0 to "+dm2+");\n";\r
- ret += " end if\n";\r
- ret += " end process "+toName + "_mod_process\n";\r
+ ret += " end if;\n";\r
+ ret += " end process "+toName + "_mod_process;\n";\r
}\r
else if (context == Signal) {\r
QString sig = toIface->toVHDL(AbstractInterface::Signal,0);\r
#include "Parameters.h"
#include "MainWindow.h"
+#include "ExternalResource.h"
+
#include "Graph.h"
#include "ReferenceBlock.h"
#include "GroupBlock.h"
QFileInfo info(filename);
params->projectPath = info.absolutePath();
+ params->projectName = info.baseName();
cout << "project path = " << qPrintable(params->projectPath) << endl;
groupList.append(topGroup);
return topGroup;
*/
}
+void Dispatcher::generateVHDL() throw(Exception) {
+ static QString fctName = "Dispatcher::generateVHDL()";
+#ifdef DEBUG_FCTNAME
+ cout << "call to " << qPrintable(fctName) << endl;
+#endif
+
+ QDir baseDir(params->projectPath);
+ QDir srcDir(params->projectPath+"/src");
+
+ if (!baseDir.exists()) {
+ cerr << "Project path " << qPrintable(params->projectPath) << " no longer exists. First, recreate it and put the project file within. Then retry to generate." << endl;
+ return;
+ }
+
+ if (srcDir.exists()) {
+ srcDir.removeRecursively();
+ }
+ baseDir.mkdir("src");
+
+ if (! baseDir.exists("testbench")) {
+ baseDir.mkdir("testbench");
+ }
+ if (! baseDir.exists("Makefile")) {
+ QFile make("/home/sdomas/Projet/Blast/code/blast/Makefile-isim");
+ QString dest = params->projectPath;
+ dest += "/Makefile";
+ make.copy(dest);
+ }
+
+ // copying external resources
+ QString dest = params->projectPath;
+ dest += "/src/";
+ try {
+ params->getGraph()->generateVHDL(dest);
+
+ QList<QString> extResources = params->getGraph()->getExternalResources();
+ foreach(QString name, extResources) {
+ cout << qPrintable(name) << endl;
+ QList<ExternalResource*> lstRes = params->searchResourceByName(name);
+ foreach(ExternalResource* res, lstRes) {
+ QFile resFile(res->getFile());
+ QFileInfo info(res->getFile());
+ QString destFile = dest+info.fileName();
+ cout << "copying " << qPrintable(res->getFile()) << " into " << qPrintable(destFile) << endl;
+ resFile.copy(destFile);
+ }
+ }
+ }
+ catch(Exception e) {
+ throw(e);
+ }
+
+ // creating parameters file
+ QString paramName = params->projectPath+"/params-isim.txt";
+ QFile paramFile(paramName);
+ if (!paramFile.open(QIODevice::WriteOnly)) {
+ throw(Exception(PROJECTPATH_NOACCESS));
+ }
+ QTextStream out(¶mFile);
+ out << "PROJECT_NAME := " << params->projectName << endl << endl;
+ out << "SRC_DIR := src" << endl;
+ out << "TB_DIR := testbench" << endl << endl;
+ out << "VHDL_SRC := ";
+ QStringList filter;
+ filter << "*.vhd" ;
+ srcDir.setNameFilters(filter);
+ QStringList listVHDL = srcDir.entryList();
+ for(int j=0;j<listVHDL.size();j++) {
+ if (j > 0) {
+ out << "\t";
+ }
+ out << "$(SRC_DIR)/" << qPrintable(listVHDL.at(j));
+ if (j != listVHDL.size()-1) {
+ out << " \\";
+ }
+ out << endl;
+ }
+ out << endl;
+ out << "VL_SRC := ${XILINX}/verilog/src/glbl.v" << endl << endl;
+ out << "TB_SRC := $(TB_DIR)/$(PROJECT_NAME)_tb.vhd" << endl << endl;
+ out << "SIMU_EXE := $(PROJECT_NAME)_tb" << endl << endl;
+
+ paramFile.close();
+
+
+}
+
void Dispatcher::generateBlockVHDL(BoxItem *item){
static QString fctName = "Dispatcher::generateBlockVHDL()";
#ifdef DEBUG_FCTNAME
class InterfaceItem;
class GroupBlock;
class FunctionalBlock;
+#include "Exception.h"
+class Exception;
bool isCurrentProject;
public slots:
+
+ // graph ops
QMap<int, QString> getAllGroupNames();
+ void generateVHDL() throw(Exception);
+
+ // scene ops
GroupScene* getSceneById(int id);
GroupScene* getSceneByName(QString name);
BoxItem* getBoxItemById(int id);
case CONFIGFILE_NOACCESS : ret = tr("Blast configuration file cannot be read"); break;
case PROJECTFILE_CORRUPTED : ret = tr("Project file is corrupted"); break;
case PROJECTFILE_NOACCESS : ret = tr("Project file cannot be read"); break;
+ case PROJECTPATH_NOACCESS : ret = tr("Project (sub)directory or file cannot be created or accessed"); break;
case BLOCKPATH_NOACCESS : ret = tr("Directory containing references cannot be accessed (no rights/existence)"); break;
case IMPLPATH_NOACCESS : ret = tr("Directory containing implementations cannot be accessed (no rights/existence)"); break;
case BLOCKFILE_CORRUPTED : ret = tr("Block file is corrupted"); break;
#define PROJECTFILE_NOACCESS 201
#define PROJECTFILE_CORRUPTED 202
+#define PROJECTPATH_NOACCESS 203
#define BLOCKFILE_NOACCESS 301
#define BLOCKFILE_CORRUPTED 302
--- /dev/null
+#include "ExternalResource.h"\r
+\r
+\r
+ExternalResource::ExternalResource(const QString& _name, const QString& _file, int _type) {\r
+\r
+ name = _name;\r
+ file = _file;\r
+ type = _type;\r
+}\r
using namespace std;\r
using namespace Qt;\r
\r
-class ExternalSource {\r
+class ExternalResource {\r
\r
public :\r
\r
enum SourceType { Code = 1, Package, Netlist, InitFile};\r
\r
- ExternalSource(const QString& _name, const QString& _file, int _type = Code);\r
+ ExternalResource(const QString& _name, const QString& _file, int _type = Code);\r
\r
// getters\r
inline QString getName() { return name; }\r
+++ /dev/null
-#include "ExternalSource.h"\r
-\r
-\r
-ExternalSource::ExternalSource(const QString& _name, const QString& _file, int _type) {\r
-\r
- name = _name;\r
- file = _file;\r
- type = _type;\r
-}\r
return triggers.size();\r
}\r
\r
+QList<QString> FunctionalBlock::getExternalResources() {\r
+\r
+ BlockImplementation* impl = reference->getImplementations().at(0); // for now only take first impl available\r
+ QList<QString> list = impl->getResources();\r
+ foreach(QString s, list) {\r
+ cout << qPrintable(s) << " ";\r
+ }\r
+ cout << endl;\r
+\r
+ return list;\r
+}\r
+\r
+\r
void FunctionalBlock::generateVHDL(const QString& path) throw(Exception){\r
\r
- BlockImplementation* impl = reference->getImplementations().at(0); // for now only take first impl available\r
+ BlockImplementation* impl = reference->getImplementations().at(0); // for now only take first impl available \r
+\r
QFile implFile(impl->getXmlFile());\r
\r
// reading in into QDomDocument\r
QDomElement eltPack = nodePack.toElement();\r
QString namePack = eltPack.attribute("name","none");\r
QString usePack = eltPack.attribute("use","none");\r
- out << "use " << nameLib << "." << namePack << "." << usePack << endl;\r
+ out << "use " << nameLib << "." << namePack << "." << usePack << ";" << endl;\r
}\r
out << endl;\r
}\r
\r
out << indent << " port (" << endl;\r
\r
+ QString ports = "";\r
+ QTextStream outPorts(&ports);\r
+\r
// Generation of the clk & rst signals\r
- out << indent << " -- clk/rst" << endl;\r
+ outPorts << indent << " -- clk/rst" << endl;\r
foreach(AbstractInterface* iface, listInputs) {\r
if(iface->getPurpose() == AbstractInterface::Clock || iface->getPurpose() == AbstractInterface::Reset) {\r
- out << indent << " " << iface->getName() << " : in std_logic;" << endl;\r
+ outPorts << 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
+ outPorts << indent << " " << iface->getName() << " : out std_logic;" << endl;\r
}\r
}\r
\r
if (hasController) {\r
// Generation of the wishbone signals\r
- out << indent << " -- registers r/w via wishbone" << endl;\r
+ outPorts << indent << " -- registers r/w via wishbone" << endl;\r
QList<BlockParameter*> listWB = reference->getWishboneParameters();\r
for(i=0;i<listWB.size()-1;i++) {\r
- out << indent << " " << listWB.at(i)->toVHDL(BlockParameter::Entity, 0) << endl;\r
+ outPorts << indent << " " << listWB.at(i)->toVHDL(BlockParameter::Entity, 0) << endl;\r
}\r
- out << indent << " " << listWB.at(i)->toVHDL(BlockParameter::Entity,BlockParameter::NoComma) << endl;\r
+ outPorts << indent << " " << listWB.at(i)->toVHDL(BlockParameter::Entity,BlockParameter::NoComma) << endl;\r
}\r
\r
-\r
- int count = 0;\r
- foreach(AbstractInterface* iface, getInterfaces()) {\r
- if((iface->getPurpose() == AbstractInterface::Data)||(iface->getPurpose() == AbstractInterface::Control)) count++;\r
- }\r
// Generation of the data/control signals\r
\r
- int flag = 0;\r
- bool first = true;\r
-\r
- foreach(AbstractInterface* iface, listInputs) {\r
- if(iface->getPurpose() == AbstractInterface::Data) {\r
- if (first) {\r
- out << indent << " -- input data ports" << endl;\r
- first = false;\r
- }\r
- count--;\r
- if (count == 0) flag = AbstractInterface::NoComma;\r
- out << indent << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl;\r
+ QList<AbstractInterface*> listIface = getInterfaces(AbstractInterface::Input, AbstractInterface::Data);\r
+ if (listIface.size()>0) {\r
+ outPorts << indent << " -- input data ports" << endl;\r
+ foreach(AbstractInterface* iface, listIface) {\r
+ outPorts << indent << " " << iface->toVHDL(AbstractInterface::Entity, 0) << endl;\r
}\r
}\r
- first = true;\r
- foreach(AbstractInterface* iface, listInputs) {\r
- if(iface->getPurpose() == AbstractInterface::Control) {\r
- if (first) {\r
- out << indent << " -- input control ports" << endl;\r
- first = false;\r
- }\r
- count--;\r
- if (count == 0) flag = AbstractInterface::NoComma;\r
- out << indent << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl;\r
+ listIface = getInterfaces(AbstractInterface::Input, AbstractInterface::Control);\r
+ if (listIface.size()>0) {\r
+ outPorts << indent << " -- input control ports" << endl;\r
+ foreach(AbstractInterface* iface, listIface) {\r
+ outPorts << indent << " " << iface->toVHDL(AbstractInterface::Entity, 0) << endl;\r
}\r
}\r
- first = true;\r
- foreach(AbstractInterface* iface, listOutputs) {\r
- if(iface->getPurpose() == AbstractInterface::Data) {\r
- if (first) {\r
- out << indent << " -- output data ports" << endl;\r
- first = false;\r
- }\r
- count--;\r
- if (count == 0) flag = AbstractInterface::NoComma;\r
- out << indent << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl;\r
+ listIface = getInterfaces(AbstractInterface::Output, AbstractInterface::Data);\r
+ if (listIface.size()>0) {\r
+ outPorts << indent << " -- output data ports" << endl;\r
+ foreach(AbstractInterface* iface, listIface) {\r
+ outPorts << indent << " " << iface->toVHDL(AbstractInterface::Entity, 0) << endl;\r
}\r
}\r
- first = true;\r
- foreach(AbstractInterface* iface, listOutputs) {\r
- if(iface->getPurpose() == AbstractInterface::Control) {\r
- if (first) {\r
- out << indent << " -- output control ports" << endl;\r
- first = false;\r
- }\r
- count--;\r
- if (count == 0) flag = AbstractInterface::NoComma;\r
- out << indent << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl;\r
+ listIface = getInterfaces(AbstractInterface::Output, AbstractInterface::Control);\r
+ if (listIface.size()>0) {\r
+ outPorts << indent << " -- output control ports" << endl;\r
+ foreach(AbstractInterface* iface, listIface) {\r
+ outPorts << indent << " " << iface->toVHDL(AbstractInterface::Entity, 0) << endl;\r
}\r
}\r
- first = true;\r
- foreach(AbstractInterface* iface, listBidirs) {\r
- if(iface->getPurpose() == AbstractInterface::Data) {\r
- if (first) {\r
- out << indent << " -- bidirs data ports" << endl;\r
- first = false;\r
- }\r
- count--;\r
- if (count == 0) flag = AbstractInterface::NoComma;\r
- out << indent << " " << iface->toVHDL(AbstractInterface::Entity, flag) << endl;\r
+ listIface = getInterfaces(AbstractInterface::InOut, AbstractInterface::Data);\r
+ if (listIface.size()>0) {\r
+ outPorts << indent << " -- bidirs data ports" << endl;\r
+ foreach(AbstractInterface* iface, listIface) {\r
+ outPorts << indent << " " << iface->toVHDL(AbstractInterface::Entity, 0) << endl;\r
}\r
}\r
+\r
+ ports.chop(2);\r
+ ports += "\n";\r
+ out << ports;\r
out << indent << " );" << endl << endl;\r
\r
}\r
\r
void FunctionalBlock::generateArchitecture(QTextStream& out, QDomElement &elt ) throw(Exception) {\r
+ QRegularExpression rxPort("@\\{([a-zA-Z0-9_]+)\\}");\r
QString expr;\r
QString code = elt.text();\r
- cout << qPrintable(code) << endl;\r
+ //cout << qPrintable(code) << endl;\r
out << "architecture rtl of " << name << " is" << endl;\r
\r
QStringList listLine = code.split("\n");\r
}\r
*/\r
if(line.contains("@{")) {\r
- out << line << endl;\r
+ QMap<QString,QString> modifs;\r
+ //cout << qPrintable(line) << endl;\r
+ QRegularExpressionMatchIterator matchPort = rxPort.globalMatch(line);\r
+ while(matchPort.hasNext()) {\r
+ QRegularExpressionMatch m = matchPort.next();\r
+ QString refName = m.captured(1);\r
+ AbstractInterface* refIface = reference->getIfaceFromName(refName);\r
+ QString funName = getIfaceUserName(refIface);\r
+ if (!funName.isEmpty()) {\r
+ modifs.insert(m.captured(0),funName);\r
+ //cout << "replace " << qPrintable(refIface->getName()) << " by " << qPrintable(funIface->getName()) << endl;\r
+ }\r
+ }\r
+ QMapIterator<QString,QString> iterM(modifs);\r
+ while(iterM.hasNext()) {\r
+ iterM.next();\r
+ QString oldName = iterM.key();\r
+ QString newName = iterM.value();\r
+ line.replace(oldName,newName);\r
+ }\r
}\r
+ out << line << endl;\r
}\r
+\r
+ out << "end rtl;" << endl;\r
}\r
\r
void FunctionalBlock::generateController(QTextStream &out) throw(Exception) {\r
\r
}\r
\r
+QString FunctionalBlock::getIfaceUserName(AbstractInterface* refIface) {\r
+\r
+ if (! refIface->isReferenceInterface()) return "";\r
+\r
+ AbstractInterface* funcIface = NULL;\r
+\r
+ if (refIface->getDirection() == AbstractInterface::Input) {\r
+ foreach(AbstractInterface* iface, getInputs()) {\r
+ FunctionalInterface* fi = AI_TO_FUN(iface);\r
+ if (fi->getReference() == refIface) {\r
+ funcIface = iface;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ else if (refIface->getDirection() == AbstractInterface::Output) {\r
+ foreach(AbstractInterface* iface, getOutputs()) {\r
+ FunctionalInterface* fi = AI_TO_FUN(iface);\r
+ if (fi->getReference() == refIface) {\r
+ funcIface = iface;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ else if (refIface->getDirection() == AbstractInterface::InOut) {\r
+ foreach(AbstractInterface* iface, getBidirs()) {\r
+ FunctionalInterface* fi = AI_TO_FUN(iface);\r
+ if (fi->getReference() == refIface) {\r
+ funcIface = iface;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ if (funcIface == NULL) return "";\r
+\r
+ return funcIface->getName();\r
+}\r
+\r
// others\r
\r
void populate(); // create parameters and interface from reference block\r
+\r
+ QList<QString> getExternalResources();\r
void generateVHDL(const QString& path) throw(Exception); // main entry to generate the VHDL code \r
+ QString getIfaceUserName(AbstractInterface* refIface); // get iface name from reference interface\r
\r
void parametersValidation(QList<AbstractBlock *> *checkedBlocks, QList<AbstractBlock*>* blocksToConfigure);\r
\r
throw(e);
}
}
+
+QList<QString> Graph::getExternalResources() {
+ QList<QString> list = topGroup->getExternalResources();
+ return list;
+}
// others
QList<AbstractInterface *> getOutsideInterfaces();
+ QList<QString> getExternalResources(); // returns the list of all external files needed for VHDL generation
+
/*!
* \brief createPatterns
* createPatterns() crosses the graph and for each functional block, it computes
#include "string.h"
#include <sstream>
#include "Parameters.h"
+#include "DelayInputModifier.h"
int GroupBlock::counter = 1;
}
}
+QList<QString> GroupBlock::getExternalResources() {
+
+ QList<QString> list;
+ foreach(AbstractBlock* block, blocks) {
+ list.append(block->getExternalResources());
+ }
+ return list;
+}
+
void GroupBlock::generateVHDL(const QString& path) throw(Exception) {
QString coreFile = "";
- coreFile = path;
+ coreFile = path;
coreFile.append(Parameters::normalizeName(name));
coreFile.append(".vhd");
generateLibraries(outCore,dummyElt);
generateEntity(outCore);
generateArchitecture(outCore,dummyElt);
+
+ foreach(AbstractBlock* block, blocks) {
+ block->generateVHDL(path);
+ }
}
catch(Exception err) {
throw(err);
out << "architecture rtl of " << name << " is " << endl << endl;
+ // generate type for delays, if needed.
+ QList<int> modWidth;
+ foreach(AbstractBlock* block, blocks) {
+ QList<AbstractInterface*> listCtlInputs = block->getControlInputs();
+ foreach(AbstractInterface* iface, listCtlInputs) {
+ ConnectedInterface* connCtlIface = AI_TO_CON(iface);
+ AbstractInputModifier* modifier = connCtlIface->getInputModifier();
+ if (modifier != NULL) {
+ ConnectedInterface* connIface = AI_TO_CON(connCtlIface->getAssociatedIface());
+ int w = connIface->getWidth();
+ if (w == -1) throw(Exception(INVALID_VALUE));
+ if (!modWidth.contains(w)) {
+ modWidth.append(w);
+ }
+ }
+ }
+ }
+ if (modWidth.size() > 0) {
+
+ out << " -- types for modified inputs" << endl;
+ out << " type vector_of_std_logic is array (natural range <>) of std_logic;" << endl;
+ foreach(int w, modWidth) {
+ QString mw = "";
+ mw.setNum(w);
+ QString mwm1 = "";
+ mwm1.setNum(w-1);
+ out << " type vector_of_std_logic_vector"<< mw << " is array (natural range <>) of std_logic_vector(" << mwm1 << " downto 0);" << endl;
+ }
+ out << endl;
+ }
+
+
// generate the components
foreach(AbstractBlock* block, blocks) {
try {
out << endl;
// generate signals
out << " ----------------------------" << endl;
- out << " SIGNALS" << endl;
+ out << " -- SIGNALS" << endl;
out << " ----------------------------" << endl << endl;
-
+// "normal" signals
foreach(AbstractBlock* block, blocks) {
try {
out << " -- signals from output ports of " << block->getName() << endl;
}
out << endl;
}
+
+ // signal for modifiers
foreach(AbstractBlock* block, blocks) {
- try {
- out << " -- signals for modified input ports of " << block->getName() << endl;
- QList<AbstractInterface*> listInputs = block->getInputs();
- foreach(AbstractInterface* iface, listInputs) {
- if (iface->getPurpose() == AbstractInterface::Control) {
+ bool hasModif = false;
+ QList<AbstractInterface*> listCtlInputs = block->getControlInputs();
+
+ foreach(AbstractInterface* iface, listCtlInputs) {
+ ConnectedInterface* connCtlIface = AI_TO_CON(iface);
+ AbstractInputModifier* modifier = connCtlIface->getInputModifier();
+ if (modifier != NULL) {
+ hasModif = true;
+ break;
+ }
+ }
+ if (hasModif) {
+ try {
+ out << " -- signals for modified input ports of " << block->getName() << endl;
+ foreach(AbstractInterface* iface, listCtlInputs) {
ConnectedInterface* connCtlIface = AI_TO_CON(iface);
AbstractInputModifier* modifier = connCtlIface->getInputModifier();
if (modifier != NULL) {
}
}
}
+ catch(Exception e) {
+ throw(e);
+ }
+ out << endl;
}
- catch(Exception e) {
- throw(e);
- }
- out << endl;
}
out << "begin" << endl;
void computeOutputPattern(int nbExec = -1) throw(Exception);
void computeAdmittanceDelays() throw(Exception);
+ QList<QString> getExternalResources();
void generateVHDL(const QString& path) throw(Exception); // main entry to generate the VHDL code
private:
void MainWindow::slotGenerateVHDL() {
- QDir baseDir(params->projectPath);
- if (!baseDir.exists()) {
- cerr << "Project path " << qPrintable(params->projectPath) << " no longer exists. First, recreate it and put the project file within. Then retry to generate." << endl;
- return;
- }
- if (! baseDir.exists("src")) {
- baseDir.mkdir("src");
- }
- if (! baseDir.exists("testbench")) {
- baseDir.mkdir("testbench");
- }
- if (! baseDir.exists("Makefile")) {
- QFile make("/home/sdomas/Projet/Blast/code/blast/Makefile-isim");
- QString dest = params->projectPath;
- dest += "/Makefile";
- make.copy(dest);
- }
-
- QString dest = params->projectPath;
- dest += "/src/";
try {
- params->getGraph()->generateVHDL(dest);
+ dispatcher->generateVHDL();
}
catch(Exception e) {
cerr << qPrintable(e.getMessage()) << endl;
all : project compile
-project : $(PROJECT).prj
+project : $(PROJECT_NAME).prj
-compile : $(PROJECT).prj $(VHDL_SRC)
+compile : $(PROJECT_NAME).prj $(VHDL_SRC)
tb_name=$$( echo $(TB_SRC) | sed 's,.*/,,' | sed 's,[.].*,,'); \
- fuse $(ISIM_LIB).$$tb_name $(ISIM_LIB).glbl -prj $(PROJECT).prj -L unisim -L secureip -timeprecision_vhdl ps -o $(SIMU_EXE)
+ fuse $(ISIM_LIB).$$tb_name $(ISIM_LIB).glbl -prj $(PROJECT_NAME).prj -L unisim -L secureip -timeprecision_vhdl ps -o $(SIMU_EXE)
view :
$(SIMU_EXE) -gui -wdb $(SIMU_EXE).wdb
-$(PROJECT).prj :
+$(PROJECT_NAME).prj :
if [ -f $@ ]; then rm $@; fi
echo "### VHDL sources"
for fich in $(VHDL_SRC); do echo vhdl $(ISIM_LIB) $$fich >> $@; done
clean :
rm -f *~
- rm -f $(PROJECT).prj
+ rm -f $(PROJECT_NAME).prj
cd $(SRC_DIR); rm -f *~
cd $(TB_DIR); rm -f *~
if (compList != "none") {\r
QStringList compos = compList.split(",");\r
foreach(QString s, compos) {\r
- impl->addSource(s);\r
+ impl->addResource(s);\r
}\r
}\r
\r
QString netName = list.at(j);\r
netName.truncate(list.at(j).size() -4);\r
cout << "found netlist " << qPrintable(netName) << endl;\r
- availableSources.append(new ExternalSource(netName,fileName,ExternalSource::Netlist));\r
+ availableResources.append(new ExternalResource(netName,fileName,ExternalResource::Netlist));\r
}\r
else {\r
cout << "parsing " << qPrintable(fileName) << " ... ";\r
if (matchPack.hasMatch()) {\r
QString packName = matchPack.captured(1);\r
cout << "found package " << qPrintable(packName) << endl;\r
- availableSources.append(new ExternalSource(packName,fileName,ExternalSource::Package));\r
+ availableResources.append(new ExternalResource(packName,fileName,ExternalResource::Package));\r
}\r
}\r
else if (line.contains("entity", Qt::CaseInsensitive)) {\r
if (matchEnt.hasMatch()) {\r
QString entityName = matchEnt.captured(1);\r
cout << "found entity " << qPrintable(entityName) << endl;\r
- availableSources.append(new ExternalSource(entityName,fileName,ExternalSource::Code));\r
+ availableResources.append(new ExternalResource(entityName,fileName,ExternalResource::Code));\r
}\r
}\r
line = in.readLine();\r
}\r
}\r
\r
-ExternalSource* Parameters::searchSourceByName(const QString& name) {\r
- foreach(ExternalSource* s, availableSources) {\r
- if (s->getName() == name) return s;\r
+QList<ExternalResource *> Parameters::searchResourceByName(const QString& name) {\r
+ QList<ExternalResource*> listRes;\r
+ foreach(ExternalResource* s, availableResources) {\r
+ if (s->getName() == name) {\r
+ listRes.append(s);\r
+ }\r
}\r
- return NULL;\r
+ return listRes;\r
}\r
\r
void Parameters::addAvailableBlock(ReferenceBlock *block) {\r
class GroupWidget;\r
\r
#include "BlockImplementation.h"\r
-#include "ExternalSource.h"\r
+#include "ExternalResource.h"\r
\r
#include "Exception.h"\r
class Exception;\r
\r
// others\r
static QString normalizeName(const QString& name);\r
- ExternalSource* searchSourceByName(const QString& name);\r
+ QList<ExternalResource*> searchResourceByName(const QString& name);\r
\r
/***************************************************\r
attributes that are general to the application\r
QList<QString> sourcePathes;\r
QList<ReferenceBlock*> availableBlocks;\r
QList<BlockImplementation*> availableImplementations;\r
- QList<ExternalSource*> availableSources;\r
+ QList<ExternalResource*> availableResources;\r
\r
ReferenceBlock* delayRef;\r
BlockImplementation* delayImpl; \r
throw(Exception(INVALID_REFBLOCK_USE));
}
+QList<QString> ReferenceBlock::getExternalResources() {
+ QList<QString> list;
+ return list;
+}
+
void load(QDomElement &elt) throw(Exception);
void setHashMd5();
+ QList<QString> getExternalResources();
void generateVHDL(const QString& path) throw(Exception); // main entry to generate the VHDL code
void parametersValidation(QList<AbstractBlock*>* checkedBlocks, QList<AbstractBlock*>* blocksToConfigure);
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
-<!-- Written by QtCreator 4.2.0, 2018-03-29T22:16:07. -->
+<!-- Written by QtCreator 4.2.0, 2018-03-30T16:40:46. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
- <value type="QByteArray">{c8006d66-d34f-42be-ad10-d0207752286d}</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">{2c9bf876-3476-44eb-8065-1f0844704dda}</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>
-ExternalSource.h
-ExternalSource.cpp
+ExternalResource.cpp
+ExternalResource.h
CustomDialog.h
CustomDialog.cpp
NewProjectDialog.h
$(BUILDPATH)/AbstractInputModifier.o \
$(BUILDPATH)/DelayInputModifier.o \
$(BUILDPATH)/BlockImplementation.o \
- $(BUILDPATH)/ExternalSource.o \
+ $(BUILDPATH)/ExternalResource.o \
$(BUILDPATH)/Graph.o \
$(BUILDPATH)/AbstractBoxItem.o \
$(BUILDPATH)/BoxItem.o \