X-Git-Url: https://bilbo.iut-bm.univ-fcomte.fr/and/gitweb/blast.git/blobdiff_plain/cfe8322b50c9ef08ffbc3e52b0849bca4cd1d0bf..3fb762e7042d9b4a1cf78556ad9ed7f117cc53ba:/Parameters.cpp?ds=inline diff --git a/Parameters.cpp b/Parameters.cpp index c12fead..d7621d2 100644 --- a/Parameters.cpp +++ b/Parameters.cpp @@ -9,6 +9,7 @@ #include "GroupScene.h" #include "GroupItem.h" #include "BoxItem.h" +#include "StimuliItem.h" #include "InterfaceItem.h" #include "ConnectionItem.h" @@ -23,6 +24,10 @@ #include "Exception.h" #include "BlocksToConfigureWidget.h" +#include "BlockParameterGeneric.h" + +#include "DelayInputModifier.h" + Parameters::Parameters() { categoryTree = NULL; arrowWidth = 5; @@ -41,10 +46,14 @@ Parameters::Parameters() { unsaveModif = false; isRstClkShown = false; - - projectPath = QDir::currentPath(); validityExtension = "_enb"; + + projectPath = ""; + projectName = ""; + projectFile = ""; + + graph = new Graph(); } Parameters::~Parameters() { @@ -62,8 +71,8 @@ void Parameters::clear() { refPathes.clear(); } -Graph* Parameters::createGraph() { - graph = new Graph(); +Graph* Parameters::initGraph(bool createTopGroupIfaces) { + graph->createTopGroup(createTopGroupIfaces); return graph; } @@ -76,10 +85,126 @@ ReferenceBlock* Parameters::getReferenceBlock(int idCategory, int idBlock) { BlockCategory* blockCat = categoryTree->searchCategory(idCategory); if (blockCat == NULL) return NULL; - ReferenceBlock* ref = blockCat->getBlock(idBlock); + ReferenceBlock* ref = blockCat->getBlockById(idBlock); + return ref; +} + +ReferenceBlock* Parameters::getHiddenReferenceBlock(QString blockName) { + + BlockCategory* blockCat = categoryTree->searchCategory(100); + if (blockCat == NULL) return NULL; + ReferenceBlock* ref = blockCat->getBlockByName(blockName); return ref; } +double Parameters::getFeedingClockFrequency(AbstractInterface *iface) { + + int idClock = 0; + + if (iface->isReferenceInterface()) return 0.0; + + if (iface->getClockIfaceType() == AbstractInterface::ParameterName) { + BlockParameter* param = iface->getOwner()->getParameterFromName(iface->getClockIfaceString()); + if (!param->isUserParameter()) return 0.0; + bool ok; + double freq = param->getDoubleValue(&ok); + if (!ok) { + cerr << "Abnormal case: cannot retrieve clock id from parameter " << qPrintable(param->getName()) << endl; + } + return freq; + } + else if ( (iface->getClockIfaceType() == AbstractInterface::ClockName) || ((iface->getDirection() == AbstractInterface::Input) && (iface->getPurpose() == AbstractInterface::Clock))) { + + // if iface is not clock, retrieve the clock related to it + if (iface->getClockIfaceType() == AbstractInterface::ClockName) { + iface = iface->getClockIface(); + } + // if iface is a group interface, then iface name is ext_clk_X, thus extract the X + if (iface->isGroupInterface()) { + QString name = iface->getName(); + name.remove(0,8); + bool ok; + idClock = name.toInt(&ok); + if (!ok) { + cerr << "Abnormal case: cannot retrieve clock id from iface name " << qPrintable(iface->getName()) << endl; + return 0.0; + } + } + // if iface is a functional interface, it is connected to clkrstgen_X (in top group) or to ext_clk_X (in subgroup) + else if (iface->isFunctionalInterface()) { + FunctionalInterface* funIface = AI_TO_FUN(iface); + ConnectedInterface* connFrom = funIface->getConnectedFrom(); + if (connFrom == NULL) { + cerr << "Abnormal case: input clock " << qPrintable(iface->getName()) << " is not connected" << endl; + return 0.0; + } + if (iface->getOwner()->isTopGroupBlock()) { + QString name = connFrom->getOwner()->getName(); + name.remove(0,10); + bool ok; + idClock = name.toInt(&ok); + if (!ok) { + cerr << "Abnormal case: cannot retrieve clock id for " << qPrintable(iface->getName()) << endl; + return 0.0; + } + } + else { + QString name = connFrom->getName(); + name.remove(0,8); + bool ok; + idClock = name.toInt(&ok); + if (!ok) { + cerr << "Abnormal case: cannot retrieve clock id for " << qPrintable(iface->getName()) << endl; + return 0.0; + } + } + } + } + return graph->getClock(idClock); +} + +void Parameters::createDelayBlock() { + delayRef = new ReferenceBlock("no.xml"); + delayRef->addCategory(100); + delayRef->setName("delay"); + + BlockCategory* cat = categoryTree->searchCategory(100); + cat->blocks.append(delayRef); + + AbstractInterface* interIn = new ReferenceInterface(delayRef,"data_in",AbstractInterface::Input, AbstractInterface::Data, "expression","$in_width"); + delayRef->addInterface(interIn); + AbstractInterface* interInCtl = new ReferenceInterface(delayRef,"data_in_enb",AbstractInterface::Input, AbstractInterface::Control, "boolean","1"); + delayRef->addInterface(interInCtl); + interInCtl->setAssociatedIface(interIn); + AbstractInterface* interOut = new ReferenceInterface(delayRef,"data_out",AbstractInterface::Output, AbstractInterface::Data, "expression","$in_width"); + delayRef->addInterface(interOut); + AbstractInterface* interOutCtl = new ReferenceInterface(delayRef,"data_out_enb",AbstractInterface::Output, AbstractInterface::Control, "boolean","1"); + delayRef->addInterface(interOutCtl); + interOutCtl->setAssociatedIface(interOut); + BlockParameter* param1 = new BlockParameterGeneric(delayRef,"in_width","natural","8"); + BlockParameter* param2 = new BlockParameterGeneric(delayRef,"dly_length","natural","1"); + delayRef->addParameter(param1); + delayRef->addParameter(param2); + delayImpl = new BlockImplementation("no.xml"); + delayImpl->setDelta("1"); + QHash consPattern; + consPattern.insert("data_in_enb","1"); + delayImpl->setConsumptionPattern(consPattern); + QHash prodPattern; + prodPattern.insert("data_out_enb","O{$dly_length}1"); + delayImpl->setProductionPattern(prodPattern); + delayImpl->setProductionCounter("1"); + delayRef->addImplementation(delayImpl); + delayImpl->setReference(delayRef); + if (! delayImpl->checkPatterns()) { + cout << "Delay block creation: failure" << endl; + } + else { + cout << "Delay block creation: success" << endl; + } + +} + void Parameters::validateXmlFile(const QString& xmlFileName, const QString& xsdFileName, XmlFileType fileType) throw(Exception) { @@ -190,6 +315,16 @@ GroupWidget *Parameters::loadProject(QDomElement root) throw(Exception) { GroupBlock *groupBlock = NULL; GroupWidget* topGroup = NULL; + + QString path = root.attribute("project_path","none"); + if (path != "none") { + QDir dir(path); + if (dir.exists()) { + projectPath = path; + + } + cout << "project path set to " << qPrintable(projectPath) << endl; + } /********************************************************** 1 : getting scene and creating associated group widgets ***********************************************************/ @@ -205,7 +340,7 @@ GroupWidget *Parameters::loadProject(QDomElement root) throw(Exception) { if(!ok) throw(Exception(PROJECTFILE_CORRUPTED)); if (idUpperScene == -1) { - topGroup = dispatcher->createTopScene(); + topGroup = dispatcher->createTopScene(Dispatcher::Load); topScene->setId(idScene); groupItem = topScene->getGroupItem(); cout << "top group added to scene n°" << idScene << endl; @@ -213,7 +348,12 @@ GroupWidget *Parameters::loadProject(QDomElement root) throw(Exception) { else { cout << "trying to create scene n°" << idScene << " with upper scene n°" <addNewEmptyGroup(upperScene,false); + /* IMPORTANT: calling addNewEmptyGroup() leads to create a new GroupWidget + * AND a BoxItem in upperScene that represents the GroupItem in the + * newly created child scene. Thus, it has not to be created when + * reading bi_group tags in the following but just searched + */ + groupWidget = dispatcher->addNewEmptyGroup(Dispatcher::Load, upperScene,false); groupWidget->getScene()->setId(idScene); groupItem = groupWidget->getScene()->getGroupItem(); } @@ -232,9 +372,10 @@ GroupWidget *Parameters::loadProject(QDomElement root) throw(Exception) { if (idUpperScene != -1) { groupWidget->setWindowTitle(groupBlock->getName()); groupWidget->show(); + cout << qPrintable(groupItem->getRefBlock()->getName()) << " has upper box item in " << qPrintable(groupItem->getParentItem()->getScene()->getGroupItem()->getRefBlock()->getName()) << endl; } } - dispatcher->setSceneCounter(maxIdScene+1); + dispatcher->setSceneCounter(Dispatcher::Load, maxIdScene+1); cout << "groupItems loaded and windows created succefully!" << endl; /********************************************************** @@ -249,7 +390,29 @@ GroupWidget *Parameters::loadProject(QDomElement root) throw(Exception) { GroupScene *currentScene = searchSceneById(idScene,topScene); if(currentScene == NULL) throw(Exception(PROJECTFILE_CORRUPTED)); - + /********************************************************** + 2.1 : getting sources if it is top scene + ***********************************************************/ + if (currentScene->isTopScene()) { + QDomNodeList sourceNodes = currentSceneNode.elementsByTagName("source_item"); + cout << "top scene has " << sourceNodes.length() << " sources" << endl; + for(int j=0; jload(currentSBNode); + } + catch(Exception err) { + throw(err); + } + cout << "source item has been read, add it to the scene" << endl; + // add the block to the GroupScene + currentScene->addStimuliItem(sourceItem); + } + } + /********************************************************** + 2.2 : getting functional blocks + ***********************************************************/ QDomNodeList functionalBlockNodes = currentSceneNode.elementsByTagName("bi_functional"); for(int j=0; j lst = currentScene->getBoxItems(); foreach(BoxItem* item, lst) { @@ -367,13 +530,47 @@ GroupWidget *Parameters::loadProject(QDomElement root) throw(Exception) { InterfaceItem *iface2 = searchInterfaceItemById(to,topScene); if(iface1 != NULL && iface2 != NULL){ - dispatcher->createConnection(iface1,iface2); + dispatcher->createConnection(Dispatcher::Load, iface1,iface2); } else { cout << "interfaces not found, connect canceled!" << endl; } } cout << "connections loaded and created succefully!" << endl; + QDomNodeList modifierNodes = root.elementsByTagName("modifier"); + + for(int i=0; irefInter == NULL) || (iface->refInter->getAssociatedIface() == NULL)) { + cout << "modified interface not found, modifiers setup canceled!" << endl; + } + else { + ConnectedInterface* connIface = AI_TO_CON(iface->refInter->getAssociatedIface()); + + AbstractInputModifier* mod = NULL; + if (typeStr == "delay") { + int delay = paramsStr.toInt(&ok); + if(!ok) throw(Exception(PROJECTFILE_CORRUPTED)); + mod = new DelayInputModifier(connIface, delay); + connIface->setInputModifier(mod); + } + } + } + + cout << "modifiers loaded and created succefully!" << endl; + return topGroup; } @@ -450,10 +647,27 @@ void Parameters::loadBlastConfiguration(QString confFile) throw(Exception) { implPathes.append(path); cout << "impl path : " << qPrintable(path) << endl << endl; } + + QDomElement eltSource = eltImpl.nextSiblingElement("sources"); + nbPathesStr = eltSource.attribute("nb","none"); + nbPathes = nbPathesStr.toInt(&ok); + QDomNodeList listSourceDir = eltSource.elementsByTagName("source_lib"); + if ((!ok) || (nbPathes != listSourceDir.size())) throw(Exception(CONFIGFILE_CORRUPTED)); + + for(int i=0;i // for each child element, initialize the associated attributes of Parameters - QDomElement eltDefaults = eltImpl.nextSiblingElement("defaults"); + QDomElement eltDefaults = eltSource.nextSiblingElement("defaults"); QDomElement eltBlocks = eltDefaults.firstChildElement("blocks"); QString attributeStr = eltBlocks.attribute("width", "none"); @@ -515,7 +729,7 @@ void Parameters::loadReferencesFromXml() throw(Exception) { QString line = in.readLine(); line = in.readLine(); - if (!line.contains("")) { + if (!line.contains("addResource(s); + } + } + + try { + impl->loadPatterns(implRoot); + } + catch(int err) { + throw(err); + } availableImplementations.append(impl); ReferenceBlock* ref = NULL; @@ -694,9 +930,12 @@ void Parameters::loadImplementationsFromXml() throw(Exception) { } if (ref == NULL) { cout << "Cannot find a reference block for impl :" << qPrintable(fileName) << endl; - } - ref->addImplementation(impl); - impl->setReference(ref); + } + else { + ref->addImplementation(impl); + impl->setReference(ref); + if (! impl->checkPatterns()) throw(Exception(IMPLFILE_CORRUPTED)); + } cout << "OK" << endl; } } @@ -741,8 +980,11 @@ void Parameters::loadImplementationsFromLib() throw(Exception) { if (ref == NULL) { cout << "Cannot find a reference block for impl :" << qPrintable(impl->getXmlFile()) << endl; } - ref->addImplementation(impl); - impl->setReference(ref); + else { + ref->addImplementation(impl); + impl->setReference(ref); + if (! impl->checkPatterns()) throw(Exception(IMPLFILE_CORRUPTED)); + } } libFile.close(); } @@ -772,6 +1014,74 @@ void Parameters::saveImplementationsToLib() throw(Exception) { libFile.close(); } + + +void Parameters::loadSources() throw(Exception) { + + for(int i=0;i Parameters::searchResourceByName(const QString& name) { + QList listRes; + foreach(ExternalResource* s, availableResources) { + if (s->getName() == name) { + listRes.append(s); + } + } + return listRes; +} + void Parameters::addAvailableBlock(ReferenceBlock *block) { availableBlocks.append(block); foreach (int id,block->getCategories()) { @@ -933,6 +1243,35 @@ void Parameters::save(QString confFile) { } writer.writeEndElement(); // + + QList lstIfaceItem; + // search for modifiers + foreach(ConnectionItem* item, allConnections) { + InterfaceItem* fromIfaceItem = item->getFromInterfaceItem(); + AbstractInputModifier* mod = fromIfaceItem->refInter->getInputModifier(); + if (mod != NULL) { + if (!lstIfaceItem.contains(fromIfaceItem)) lstIfaceItem.append(fromIfaceItem); + } + InterfaceItem* toIfaceItem = item->getToInterfaceItem(); + mod = toIfaceItem->refInter->getInputModifier(); + if (mod != NULL) { + if (!lstIfaceItem.contains(toIfaceItem)) lstIfaceItem.append(toIfaceItem); + } + } + // write input modifiers + writer.writeStartElement("modifiers"); + foreach(InterfaceItem* item, lstIfaceItem) { + AbstractInputModifier* mod = item->refInter->getInputModifier(); + if (mod != NULL) { + writer.writeStartElement("modifier"); + writer.writeAttribute("id", QString::number(item->getId())); + writer.writeAttribute("type",mod->getTypeStr()); + writer.writeAttribute("params", mod->getParametersStr()); + writer.writeEndElement(); + } + } + + writer.writeEndElement(); // writer.writeEndElement(); //getBoxItems()){ + if(item->getRefBlock() == block) { + return item; + } + } + + BoxItem* item = NULL; + foreach(GroupScene *s, scene->getChildrenScene()) { + item = searchFunctionalBlockRecur(block,s); + if (item != NULL) return item; + } + return NULL; +} + InterfaceItem* Parameters::searchInterfaceItemById(int id, GroupScene* scene) { foreach(InterfaceItem *item, scene->getGroupItem()->getInterfaces()){ @@ -1010,6 +1375,15 @@ InterfaceItem* Parameters::searchInterfaceItemById(int id, GroupScene* scene) { return item; } } + if (scene->isTopScene()) { + foreach(StimuliItem *block, scene->getSourceItems()){ + foreach(InterfaceItem *item, block->getInterfaces()){ + if(item->getId() == id){ + return item; + } + } + } + } foreach(BoxItem *block, scene->getBoxItems()){ foreach(InterfaceItem *item, block->getInterfaces()){ if(item->getId() == id){ @@ -1024,3 +1398,10 @@ InterfaceItem* Parameters::searchInterfaceItemById(int id, GroupScene* scene) { } return NULL; } + +QString Parameters::normalizeName(const QString &name) { + QString s = name; + s.replace(QRegularExpression("[^a-zA-Z0-9_]"),"_"); + s.replace(QRegularExpression("[_]+"),"_"); + return s; +}