X-Git-Url: https://bilbo.iut-bm.univ-fcomte.fr/and/gitweb/blast.git/blobdiff_plain/561d4f45e60504cc9e041370dd908b002fe776a5..HEAD:/ReferenceBlock.cpp?ds=sidebyside diff --git a/ReferenceBlock.cpp b/ReferenceBlock.cpp index a0a8220..56a34db 100644 --- a/ReferenceBlock.cpp +++ b/ReferenceBlock.cpp @@ -6,23 +6,19 @@ #include "BlockParameterGeneric.h" #include "BlockParameterPort.h" #include "BlockParameterWishbone.h" +#include "Parameters.h" -ReferenceBlock::ReferenceBlock(const QString _xmlFile) : AbstractBlock() { - xmlFile = _xmlFile; +ReferenceBlock::ReferenceBlock(const QString _xmlFile) : AbstractBlock(NULL) { + xmlFile = _xmlFile; } void ReferenceBlock::addCategory(int id) { categories.append(id); } -void ReferenceBlock::setBriefDescription(const QString& str) { +void ReferenceBlock::setDescription(const QString& str) { if(str != NULL) - descriptionBrief = str; -} - -void ReferenceBlock::setDetailedDescription(const QString& str) { - if(str != NULL) - descriptionDetail = str; + description = str; } void ReferenceBlock::addImplementation(BlockImplementation *impl) { @@ -44,6 +40,16 @@ void ReferenceBlock::setHashMd5() { void ReferenceBlock::load(QDomElement &elt) throw(Exception) { + cout << "Block : get version" << endl; + QString verStr = elt.attribute("version","none"); + QString specialStr = elt.attribute("special","none"); + if (verStr != "none") { + setVersion(verStr); + } + else { + setVersion("0.0"); + } + setSpecialType(getSpecialTypeFromString(specialStr)); cout << "Block : get informations" << endl; QDomElement eltInfo = elt.firstChildElement("informations"); @@ -74,7 +80,7 @@ void ReferenceBlock::load(QDomElement &elt) throw(Exception) { // create interfaces that correspond to a wishbone parameter, if any. try { - createInterfaceForParameters(); + createInterfaceForWishbone(); } catch(int err) { throw(err); @@ -94,7 +100,7 @@ void ReferenceBlock::loadInformations(QDomElement &elt) throw(Exception) { } else { QDomText txtName = nodeNameTxt.toText(); - name = txtName.data().trimmed(); + name = Parameters::normalizeName(txtName.data().trimmed()); cout<< "block name : " << qPrintable(name) << endl; } @@ -104,38 +110,31 @@ void ReferenceBlock::loadInformations(QDomElement &elt) throw(Exception) { QString idsStr = eltCat.attribute("ids","none"); if (idsStr == "none") throw (Exception(BLOCKFILE_CORRUPTED)); - QStringList listCat = idsStr.split(","); - foreach(QString str, listCat) - { - int idCat = str.toInt(&ok); - categories.append(idCat); + if (idsStr.isEmpty()) { + categories.append(99); + } + else { + QStringList listCat = idsStr.split(","); + foreach(QString str, listCat) + { + int idCat = str.toInt(&ok); + categories.append(idCat); + } } // getting description cout << "Block info : get description" << endl; QDomElement eltDesc = eltCat.nextSiblingElement("description"); - // getting brief - QDomElement eltBrief = eltDesc.firstChildElement("brief"); - QDomNode nodeBriefTxt = eltBrief.firstChild(); - if (nodeBriefTxt.isNull()) { - descriptionBrief = "no brief description"; - } - else { - QDomText txtBrief = nodeBriefTxt.toText(); - descriptionBrief = txtBrief.data().trimmed(); - cout << "block brief desc : " << qPrintable(descriptionBrief) << endl; - } - // getting detailed - QDomElement eltDetail = eltBrief.nextSiblingElement("detailed"); - QDomNode nodeDetailTxt = eltDetail.firstChild(); - if (nodeDetailTxt.isNull()) { - descriptionDetail = "no detailed description"; + // getting text + QDomNode nodeTxt = eltDesc.firstChild(); + if (nodeTxt.isNull()) { + description = "no description"; } else { - QDomText txtDetail = nodeDetailTxt.toText(); - descriptionDetail = txtDetail.data().trimmed(); - cout << "block detail desc : " << qPrintable(descriptionDetail) << endl; - } + QDomText txtBrief = nodeTxt.toText(); + description = txtBrief.data().trimmed(); + cout << "block desc : " << qPrintable(description) << endl; + } } void ReferenceBlock::loadParameters(QDomElement &elt) throw(Exception) { @@ -157,7 +156,7 @@ void ReferenceBlock::loadParameters(QDomElement &elt) throw(Exception) { valueStr = ""; } if (contextStr == "user") { - param = new BlockParameterUser(this,nameStr,valueStr); + param = new BlockParameterUser(this,nameStr,typeStr,valueStr); } else if (contextStr == "generic") { param = new BlockParameterGeneric(this,nameStr,typeStr,valueStr); @@ -169,11 +168,16 @@ void ReferenceBlock::loadParameters(QDomElement &elt) throw(Exception) { int duration = 0; QString wbValue = ""; QStringList listWb = wbStr.split(","); + cout << "wb param has:"; + foreach(QString s, listWb) { + cout << qPrintable(s) << " | "; + } + cout << endl; if (listWb.at(0) == "r") { access = BlockParameter::Read; } - else if (wbStr == "w") { + else if (listWb.at(0) == "w") { access = BlockParameter::Write; bool ok; wbValue = listWb.at(1).toInt(&ok); @@ -210,49 +214,160 @@ void ReferenceBlock::loadInterfaces(QDomElement &elt) throw(Exception) { QString nameStr; QString typeStr; QString widthStr; + QString endianStr; QString purposeStr; + QString clockStr; int purpose; QString multStr; int mult; - AbstractInterface* inter; + ReferenceInterface* iface; if ((elt.isNull()) || (elt.tagName() != "interfaces")) throw (Exception(BLOCKFILE_CORRUPTED)); QDomElement eltInputs = elt.firstChildElement("inputs"); + // getting each input QDomNodeList listNodeInputs = eltInputs.elementsByTagName("input"); + + // find all input clocks + QList clocks; + for(int i=0;icheckSetClockIface(nameStr)) { + throw (Exception(BLOCKFILE_CORRUPTED)); + } + inputs.append(iface); + clocks.append(iface); + } + } + cout << "number of clocks: " << clocks.size() << endl; + + // find inputs for(int i=0;igetName().toStdString() << endl; - cout << "purpose for " << nameStr.toStdString() << " : " << purposeStr.toStdString() << endl; purpose = ReferenceInterface::translatePurpose(purposeStr); - cout << "translated purpose : " << purpose << endl; - multStr = eltInput.attribute("multiplicity","none"); - mult = ReferenceInterface::translateMultiplicity(multStr); + if (purpose != AbstractInterface::Clock) { + cout << "translated purpose : " << purpose << endl; + nameStr = eltInput.attribute("name","none"); + typeStr = eltInput.attribute("type","none"); + widthStr = eltInput.attribute("width","none"); + endianStr = eltInput.attribute("endian","none"); + clockStr = eltInput.attribute("clock","none"); + int endianess; + if ((endianStr == "none") || (endianStr == "little")) { + endianess = AbstractInterface::LittleEndian; + } + else if (endianStr == "big") { + endianess = AbstractInterface::BigEndian; + } + else { + throw (Exception(BLOCKFILE_CORRUPTED)); + } - inter = new ReferenceInterface(this,nameStr,typeStr,widthStr,AbstractInterface::Input, purpose, mult); - inputs.append(inter); - } + multStr = eltInput.attribute("multiplicity","none"); + mult = ReferenceInterface::translateMultiplicity(multStr); + iface = new ReferenceInterface(this,nameStr, AbstractInterface::Input, purpose, typeStr, widthStr, endianess, mult); + if (clockStr == "none") { + if (clocks.size() > 1) { + // if several clocks, the associated one MUST be given + throw (Exception(BLOCKFILE_CORRUPTED)); + } + // no clock given, take the single one + clockStr = clocks.at(0)->getName(); + } + if (! iface->checkSetClockIface(clockStr)) { + throw (Exception(BLOCKFILE_CORRUPTED)); + } + inputs.append(iface); + } + } + // getting each control + QDomNodeList listNodeInCtl = eltInputs.elementsByTagName("control"); + for(int i=0;igetName()+"_enb"; + iface = new ReferenceInterface(this,nameEnbStr,AbstractInterface::Input, AbstractInterface::Control,"boolean","1", AbstractInterface::LittleEndian, 1); + if (!iface->setAssociatedIface(dataIface)) { + throw (Exception(BLOCKFILE_CORRUPTED)); + } + clockStr = dataIface->getClockIfaceString(); + if (! iface->checkSetClockIface(clockStr)) { + throw (Exception(BLOCKFILE_CORRUPTED)); + } + cout << "created a control input named " << qPrintable(iface->getName()) << endl; + inputs.append(iface); + } QDomElement eltOutputs = eltInputs.nextSiblingElement("outputs"); QDomNodeList listNodeOutputs = eltOutputs.elementsByTagName("output"); for(int i=0;i 1) { + // if several clocks, the associated one MUST be given + throw (Exception(BLOCKFILE_CORRUPTED)); + } + // no clock given, take the single one + clockStr = clocks.at(0)->getName(); + } + if (! iface->checkSetClockIface(clockStr)) { + throw (Exception(BLOCKFILE_CORRUPTED)); + } + + outputs.append(iface); + } + // getting each control + QDomNodeList listNodeOutCtl = eltOutputs.elementsByTagName("control"); + for(int i=0;igetName()+"_enb"; + iface = new ReferenceInterface(this,nameStr,AbstractInterface::Output, AbstractInterface::Control,"boolean","1",AbstractInterface::LittleEndian, 1); + if (!iface->setAssociatedIface(dataIface)) { + throw (Exception(BLOCKFILE_CORRUPTED)); + } + clockStr = dataIface->getClockIfaceString(); + if (! iface->checkSetClockIface(clockStr)) { + throw (Exception(BLOCKFILE_CORRUPTED)); + } + cout << "created a control output named " << qPrintable(iface->getName()) << endl; + outputs.append(iface); } QDomElement eltBidirs = eltInputs.nextSiblingElement("bidirs"); @@ -263,32 +378,60 @@ void ReferenceBlock::loadInterfaces(QDomElement &elt) throw(Exception) { nameStr = eltBidir.attribute("name","none"); typeStr = eltBidir.attribute("type","none"); widthStr = eltBidir.attribute("width","none"); - purposeStr = eltBidir.attribute("type","none"); + endianStr = eltBidir.attribute("endian","none"); + clockStr = eltBidir.attribute("clock","none"); + int endianess; + if ((endianStr == "none") || (endianStr == "little")) { + endianess = AbstractInterface::LittleEndian; + } + else if (endianStr == "big") { + endianess = AbstractInterface::BigEndian; + } + else { + throw (Exception(BLOCKFILE_CORRUPTED)); + } + purposeStr = eltBidir.attribute("purpose","none"); purpose = ReferenceInterface::translatePurpose(purposeStr); multStr = eltBidir.attribute("multiplicity","none"); mult = ReferenceInterface::translateMultiplicity(multStr); - inter = new ReferenceInterface(this,nameStr,typeStr,widthStr,AbstractInterface::InOut, purpose, mult); - bidirs.append(inter); + iface = new ReferenceInterface(this,nameStr,AbstractInterface::InOut, purpose,typeStr,widthStr, endianess, mult); + if (clockStr == "none") { + if (clocks.size() > 1) { + // if several clocks, the associated one MUST be given + throw (Exception(BLOCKFILE_CORRUPTED)); + } + // no clock given, take the single one + clockStr = clocks.at(0)->getName(); + } + if (! iface->checkSetClockIface(clockStr)) { + throw (Exception(BLOCKFILE_CORRUPTED)); + } + + bidirs.append(iface); } } -void ReferenceBlock::createInterfaceForParameters() throw(Exception){ +void ReferenceBlock::createInterfaceForWishbone() throw(Exception){ ReferenceInterface* iface = NULL; foreach(BlockParameter* param, params) { if (param->isWishboneParameter()) { - BlockParameterWishbone* p = (BlockParameterWishbone*)param; - int orientation = -1; + + BlockParameterWishbone* p = (BlockParameterWishbone*)param; + cout << "creating interface for parameter wb " << qPrintable(p->getName()) << endl; + if (p->getWBAccess() == BlockParameter::Read) { - iface = new ReferenceInterface(this,p->getName(),p->getType(),p->getWidth(), AbstractInterface::Output, AbstractInterface::Wishbone,1); + iface = new ReferenceInterface(this,p->getName(), AbstractInterface::Output, AbstractInterface::Wishbone, p->getTypeString(),p->getWidth(), AbstractInterface::LittleEndian, 1); outputs.append(iface); } else if (p->getWBAccess() == BlockParameter::Write) { - iface = new ReferenceInterface(this,p->getName(),p->getType(),p->getWidth(), AbstractInterface::Input, AbstractInterface::Wishbone,1); + iface = new ReferenceInterface(this,p->getName(), AbstractInterface::Input, AbstractInterface::Wishbone,p->getTypeString(),p->getWidth(),AbstractInterface::LittleEndian,1); inputs.append(iface); } - ReferenceInterface* iface = new ReferenceInterface(this,p->getName(),p->getType(),p->getWidth(), orientation, AbstractInterface::Wishbone,1); + else { + throw (Exception(BLOCKFILE_CORRUPTED)); + } } } } @@ -311,8 +454,9 @@ QDataStream& operator<<(QDataStream &out, const ReferenceBlock &b) { toWrite << b.name; toWrite << b.xmlFile; - toWrite << b.descriptionBrief; - toWrite << b.descriptionDetail; + toWrite << b.specialType; + toWrite << b.version; + toWrite << b.description; toWrite << b.categories; toWrite << b.hashMd5; toWrite << b.params.size(); @@ -337,31 +481,88 @@ QDataStream& operator<<(QDataStream &out, const ReferenceBlock &b) { } toWrite << b.inputs.size(); + // firstly write clock ifaces for(int i=0; igetName(); - toWrite << iface->getWidth(); - toWrite << iface->getPurpose(); - toWrite << iface->getDirection(); - toWrite << iface->getMultiplicity(); + if (iface->getPurpose() == AbstractInterface::Clock) { + toWrite << iface->getName(); + toWrite << iface->getType(); + toWrite << iface->getWidthString(); + toWrite << iface->getPurpose(); + toWrite << iface->getDirection(); + toWrite << iface->getMultiplicity(); + toWrite << iface->getClockIfaceType(); + toWrite << iface->getClockIfaceString(); + } + } + // secondly write control ifaces + for(int i=0; igetPurpose() == AbstractInterface::Control) { + toWrite << iface->getName(); + toWrite << iface->getType(); + toWrite << iface->getWidthString(); + toWrite << iface->getPurpose(); + toWrite << iface->getDirection(); + toWrite << iface->getMultiplicity(); + toWrite << iface->getClockIfaceType(); + toWrite << iface->getClockIfaceString(); + } + } + // thirdly, write other ifaces + for(int i=0; igetPurpose() != AbstractInterface::Control) && (iface->getPurpose() != AbstractInterface::Clock)) { + toWrite << iface->getName(); + toWrite << iface->getType(); + toWrite << iface->getWidthString(); + toWrite << iface->getPurpose(); + toWrite << iface->getDirection(); + toWrite << iface->getMultiplicity(); + toWrite << iface->getClockIfaceType(); + toWrite << iface->getClockIfaceString(); + } } toWrite << b.outputs.size(); + // firstly write control ifaces for(int i=0; igetName(); - toWrite << iface->getWidth(); - toWrite << iface->getPurpose(); - toWrite << iface->getDirection(); - toWrite << iface->getMultiplicity(); + if (iface->getPurpose() == AbstractInterface::Control) { + toWrite << iface->getName(); + toWrite << iface->getType(); + toWrite << iface->getWidthString(); + toWrite << iface->getPurpose(); + toWrite << iface->getDirection(); + toWrite << iface->getMultiplicity(); + toWrite << iface->getClockIfaceType(); + toWrite << iface->getClockIfaceString(); + } + } + // secondly, write other ifaces + for(int i=0; igetPurpose() != AbstractInterface::Control) { + toWrite << iface->getName(); + toWrite << iface->getType(); + toWrite << iface->getWidthString(); + toWrite << iface->getPurpose(); + toWrite << iface->getDirection(); + toWrite << iface->getMultiplicity(); + toWrite << iface->getClockIfaceType(); + toWrite << iface->getClockIfaceString(); + } } toWrite << b.bidirs.size(); for(int i=0; igetName(); - toWrite << iface->getWidth(); + toWrite << iface->getType(); + toWrite << iface->getWidthString(); toWrite << iface->getPurpose(); toWrite << iface->getDirection(); toWrite << iface->getMultiplicity(); + toWrite << iface->getClockIfaceType(); + toWrite << iface->getClockIfaceString(); } out << blockData; @@ -383,8 +584,9 @@ QDataStream& operator>>(QDataStream &in, ReferenceBlock &b) { in >> b.name; in >> b.xmlFile; - in >> b.descriptionBrief; - in >> b.descriptionDetail; + in >> b.specialType; + in >> b.version; + in >> b.description; in >> b.categories; in >> b.hashMd5; b.params.clear(); @@ -402,7 +604,7 @@ QDataStream& operator>>(QDataStream &in, ReferenceBlock &b) { in >> valueStr; if (contextStr == "user") { - p = new BlockParameterUser(&b,nameStr,valueStr); + p = new BlockParameterUser(&b,nameStr,typeStr,valueStr); } else if (contextStr == "generic") { p = new BlockParameterGeneric(&b,nameStr,typeStr,valueStr); @@ -432,15 +634,33 @@ QDataStream& operator>>(QDataStream &in, ReferenceBlock &b) { iface = new ReferenceInterface(&b); in >> txt; iface->setName(txt); + int type; + in >> type; + iface->setType(type); in >> txt; iface->setWidth(txt); in >> val; - iface->setPurpose(val); + iface->setPurpose(val); in >> val; iface->setDirection(val); in >> val; iface->setMultiplicity(val); + int clkType; + QString clk; + in >> clkType; + in >> clk; + iface->setClockIfaceName(clk); + iface->setClockIfaceType(clkType); b.inputs.append(iface); + if (iface->getPurpose() == AbstractInterface::Data) { + QString ctlRefName = iface->getName()+"_enb"; + ReferenceInterface* ctlRefIface = AI_TO_REF(b.getIfaceFromName(ctlRefName)); + if (ctlRefIface != NULL) { + if (! ctlRefIface->setAssociatedIface(iface)) { + cerr << "Abnormal case while reading a reference block in library: cannot set associated control interface for data interface" << endl; + } + } + } } b.outputs.clear(); @@ -449,15 +669,33 @@ QDataStream& operator>>(QDataStream &in, ReferenceBlock &b) { iface = new ReferenceInterface(&b); in >> txt; iface->setName(txt); + int type; + in >> type; + iface->setType(type); in >> txt; iface->setWidth(txt); in >> val; - iface->setPurpose(val); + iface->setPurpose(val); in >> val; iface->setDirection(val); in >> val; iface->setMultiplicity(val); + int clkType; + QString clk; + in >> clkType; + in >> clk; + iface->setClockIfaceName(clk); + iface->setClockIfaceType(clkType); b.outputs.append(iface); + if (iface->getPurpose() == AbstractInterface::Data) { + QString ctlRefName = iface->getName()+"_enb"; + ReferenceInterface* ctlRefIface = AI_TO_REF(b.getIfaceFromName(ctlRefName)); + if (ctlRefIface != NULL) { + if (! ctlRefIface->setAssociatedIface(iface)) { + cerr << "Abnormal case while reading a reference block in library" << endl; + } + } + } } b.bidirs.clear(); @@ -466,6 +704,9 @@ QDataStream& operator>>(QDataStream &in, ReferenceBlock &b) { iface = new ReferenceInterface(&b); in >> txt; iface->setName(txt); + int type; + in >> type; + iface->setType(type); in >> txt; iface->setWidth(txt); in >> val; @@ -474,8 +715,60 @@ QDataStream& operator>>(QDataStream &in, ReferenceBlock &b) { iface->setDirection(val); in >> val; iface->setMultiplicity(val); + int clkType; + QString clk; + in >> clkType; + in >> clk; + iface->setClockIfaceName(clk); + iface->setClockIfaceType(clkType); b.bidirs.append(iface); } return in; } + +void ReferenceBlock::checkInputPatternCompatibility() throw(Exception){ + throw(Exception(INVALID_REFBLOCK_USE)); +} + +void ReferenceBlock::computeOutputPattern(int nbExec) throw(Exception) { + // does strictly nothing + throw(Exception(INVALID_REFBLOCK_USE)); +} + +void ReferenceBlock::computeAdmittanceDelays() throw(Exception) { + // does strictly nothing + throw(Exception(INVALID_REFBLOCK_USE)); +} + + +void ReferenceBlock::generateVHDL(const QString& path) throw(Exception){ + throw(Exception(INVALID_REFBLOCK_USE)); +} + +void ReferenceBlock::generateComments(QTextStream& out, QDomElement &elt, QString coreFile) throw(Exception) { + throw(Exception(INVALID_REFBLOCK_USE)); +} + +void ReferenceBlock::generateLibraries(QTextStream& out, QDomElement &elt) throw(Exception) { + throw(Exception(INVALID_REFBLOCK_USE)); +} + +void ReferenceBlock::generateArchitecture(QTextStream& out, QDomElement &elt ) throw(Exception) { + throw(Exception(INVALID_REFBLOCK_USE)); +} + +void ReferenceBlock::generateController(QTextStream& out) throw(Exception) { + throw(Exception(INVALID_REFBLOCK_USE)); +} + +void ReferenceBlock::generateEntityOrComponentBody(QTextStream &out, int indentLevel, bool hasController) throw(Exception) { + throw(Exception(INVALID_REFBLOCK_USE)); +} + +QList ReferenceBlock::getExternalResources() { + QList list; + return list; +} + +