X-Git-Url: https://bilbo.iut-bm.univ-fcomte.fr/and/gitweb/blast.git/blobdiff_plain/abbc64cf04a35ab3549d5c516f44c7c5921baa63..8fb3c55ee009a11db5e1c08a4cfb286979412745:/Graph.cpp?ds=sidebyside diff --git a/Graph.cpp b/Graph.cpp index 1c87123..4b22691 100644 --- a/Graph.cpp +++ b/Graph.cpp @@ -2,13 +2,16 @@ #include "GroupBlock.h" #include "ReferenceBlock.h" #include "FunctionalBlock.h" +#include "SpecialBlock.h" -Graph::Graph() { - topGroup = new GroupBlock(NULL); +Graph::Graph(bool createTopGroupIface) { + topGroup = new GroupBlock(NULL, createTopGroupIface); topGroup->setName("top group"); + groups.append(topGroup); } Graph::~Graph() { + delete topGroup; } @@ -16,16 +19,196 @@ QList Graph::getOutsideInterfaces() { return topGroup->getInterfaces(); } -GroupBlock* Graph::createChildBlock(GroupBlock* parent) { - GroupBlock* b = new GroupBlock(parent); +GroupBlock* Graph::createChildGroupBlock(GroupBlock* parent, bool createGroupIface) { + GroupBlock* b = new GroupBlock(parent, createGroupIface); + groups.append(b); return b; } -FunctionalBlock* Graph::addFunctionalBlock(GroupBlock* group, ReferenceBlock* ref) { +void Graph::removeGroupBlock(GroupBlock *group) { + group->removeAllBlocks(); + GroupBlock* parent = AB_TO_GRP(group->getParent()); + parent->removeBlock(group); + groups.removeAll(group); +} + +GroupBlock* Graph::getGroupBlockByName(QString name) { + foreach(GroupBlock* group, groups) { + if (group->getName() == name) return group; + } + return NULL; +} - FunctionalBlock* newBlock = new FunctionalBlock(group,ref); - newBlock->populate(); +FunctionalBlock* Graph::createFunctionalBlock(GroupBlock* group, ReferenceBlock* ref, bool createIfaces) { + + FunctionalBlock* newBlock = NULL; + if (ref->getSpecialType() != -1) { + newBlock = new SpecialBlock(ref->getSpecialType(), group,ref, createIfaces); + } + else { + newBlock = new FunctionalBlock(group,ref, createIfaces); + } group->addBlock(newBlock); return newBlock; } + +FunctionalBlock* Graph::duplicateFunctionalBlock(FunctionalBlock *block) { + + ReferenceBlock* ref = block->getReference(); + GroupBlock* group = AB_TO_GRP(block->getParent()); + + // adding to the graph + FunctionalBlock* newBlock = createFunctionalBlock(group,ref, true); + return newBlock; +} + + +bool Graph::removeFunctionalBlock(FunctionalBlock* block) { + GroupBlock* group = AB_TO_GRP(block->getParent()); + group->removeBlock(block); + return true; +} + +FunctionalBlock* Graph::getFunctionalBlockByName(QString name, GroupBlock* parent) { + FunctionalBlock* block = NULL; + if (parent != NULL) { + block = AB_TO_FUN(parent->getFunctionalBlockByName(name)); + } + else { + foreach(GroupBlock* group, groups) { + block = AB_TO_FUN(group->getFunctionalBlockByName(name)); + if (block != NULL) return block; + } + } + return block; +} + +FunctionalBlock* Graph::createStimuliBlock(ReferenceBlock* ref, bool createIfaces) { + /* A stimuli block is always a special block with idSpecial = 1 */ + + FunctionalBlock* newBlock = new SpecialBlock(AbstractBlock::Source, NULL,ref, createIfaces); + stimulis.append(newBlock); + return newBlock; +} + +FunctionalBlock* Graph::duplicateStimuliBlock(FunctionalBlock *block) { + + ReferenceBlock* ref = block->getReference(); + + // adding to the graph + FunctionalBlock* newBlock = createStimuliBlock(ref, true); + return newBlock; +} + +FunctionalBlock* Graph::getStimuliBlockByName(QString name) { + foreach(FunctionalBlock* block, stimulis) { + if (block->getName() == name) return block; + } + return NULL; +} + +bool Graph::removeStimuliBlock(FunctionalBlock *block) { + stimulis.removeAll(block); + return true; +} + +void Graph::createPatterns() throw(Exception) { + + foreach(AbstractBlock* block, stimulis) { + FunctionalBlock* funBlock = AB_TO_FUN(block); + try { + funBlock->createPatterns(); + } + catch(Exception e) { + throw(e); + } + } + + foreach(AbstractBlock* block, groups) { + GroupBlock* group = AB_TO_GRP(block); + foreach(AbstractBlock* inBlock, group->getBlocks()) { + if (inBlock->isFunctionalBlock()) { + FunctionalBlock* funBlock = AB_TO_FUN(inBlock); + try { + funBlock->createPatterns(); + } + catch(Exception e) { + throw(e); + } + } + } + } +} + +void Graph::resetPatternComputed() { + foreach(AbstractBlock* block, stimulis) { + block->setOutputPatternComputed(false); + block->resetTraversalLevel(); + } + foreach(AbstractBlock* block, groups) { + GroupBlock* group = AB_TO_GRP(block); + group->setOutputPatternComputed(false); + block->resetTraversalLevel(); + foreach(AbstractBlock* inBlock, group->getBlocks()) { + inBlock->setOutputPatternComputed(false); + block->resetTraversalLevel(); + } + } +} + +void Graph::computeOutputPatterns(int nbExec) throw(Exception) { + + try { + createPatterns(); + } + catch(Exception e) { + throw(e); + } + + resetPatternComputed(); + // search for all block that are source. + QList sources; + sources.append(stimulis); + foreach(AbstractBlock* block, groups) { + GroupBlock* group = AB_TO_GRP(block); + foreach(AbstractBlock* inBlock, group->getBlocks()) { + FunctionalBlock* funBlock = AB_TO_FUN(inBlock); + if (inBlock->isSourceBlock()) { + sources.append(funBlock); + } + } + } + // search for maximum PP length + int maxPP = 0; + foreach(FunctionalBlock* block, sources) { + if (block->getProductionPatternLength() > maxPP) maxPP = block->getProductionPatternLength(); + } + // compute output for generators + int maxExecLen = maxPP*nbExec; + foreach(FunctionalBlock* block, sources) { + int d = block->getProductionPatternLength(); + block->computeOutputPattern((maxExecLen+d-1)/d); + } + // compute output for top group + try { + topGroup->computeOutputPattern(); + } + catch(Exception e) { + throw(e); + } +} + +void Graph::generateVHDL(const QString &path) throw(Exception) { + try { + topGroup->generateVHDL(path); + } + catch(Exception e) { + throw(e); + } +} + +QList Graph::getExternalResources() { + QList list = topGroup->getExternalResources(); + return list; +}