From: stephane Domas Date: Thu, 29 Mar 2018 20:16:28 +0000 (+0200) Subject: nearly finished GroupBlock VHDL gen X-Git-Url: https://bilbo.iut-bm.univ-fcomte.fr/and/gitweb/blast.git/commitdiff_plain/8f0bedf735fe2b306c11c3f4a168245a05e37ccd?ds=inline nearly finished GroupBlock VHDL gen --- diff --git a/AbstractBlock.cpp b/AbstractBlock.cpp index 3bb808e..7bdec1b 100644 --- a/AbstractBlock.cpp +++ b/AbstractBlock.cpp @@ -249,7 +249,7 @@ void AbstractBlock::connectClkReset() throw(Exception) { GroupBlock* parentBlock = AB_TO_GRP(parent); - cout << "connecting clk/rst for child " << qPrintable(name) << " of " << qPrintable(parentBlock->getName()) << endl; + QList lstClk = getInterfaces(AbstractInterface::Input,AbstractInterface::Clock); QList lstRst = getInterfaces(AbstractInterface::Input,AbstractInterface::Reset); @@ -273,10 +273,12 @@ void AbstractBlock::connectClkReset() throw(Exception) { fromClk = AI_TO_CON(clkrstgen->getIfaceFromName("clk")); fromRst = AI_TO_CON(clkrstgen->getIfaceFromName("reset")); } + cout << "connecting clk/rst for " << qPrintable(name) << " to clkrstgen" << endl; } else { fromClk = AI_TO_CON(parentBlock->getIfaceFromName("clk")); fromRst = AI_TO_CON(parentBlock->getIfaceFromName("reset")); + cout << "connecting clk/rst for child " << qPrintable(name) << " of " << qPrintable(parentBlock->getName()) << endl; } if ((fromClk == NULL) || (fromRst == NULL)) { throw(Exception(IFACE_GROUP_NOCLKRST,parentBlock)); @@ -284,6 +286,8 @@ void AbstractBlock::connectClkReset() throw(Exception) { else { fromClk->connectTo(toClk); fromRst->connectTo(toRst); + cout << "connection done between " << qPrintable(toClk->getConnectedFrom()->getOwner()->getName()) << "/" << qPrintable(toClk->getConnectedFrom()->getName()); + cout << " and " << qPrintable(toClk->getOwner()->getName()) << "/" << qPrintable(toClk->getName()) << endl; } } diff --git a/AbstractInputModifier.h b/AbstractInputModifier.h index 6f3abe8..890daf0 100644 --- a/AbstractInputModifier.h +++ b/AbstractInputModifier.h @@ -16,7 +16,7 @@ class AbstractInputModifier { public: - enum ModifierVHDLContext {AnyContext = 0, Entity = 1, Component = 2, Architecture = 3 }; + enum ModifierVHDLContext {AnyContext = 0, Entity = 1, Component = 2, Architecture = 3, Signal = 4 }; enum ModifierVHDLFlags { NoComma = 1 }; AbstractInputModifier(ConnectedInterface* _associatedIface); diff --git a/AbstractInterface.cpp b/AbstractInterface.cpp index 6c51907..39e672d 100644 --- a/AbstractInterface.cpp +++ b/AbstractInterface.cpp @@ -298,7 +298,17 @@ QString AbstractInterface::toVHDL(int context, int flags) throw(Exception) { QString ret=""; bool ok; - cout << "iface " << qPrintable(name) << " must be evaluated to vhdl :" << qPrintable(width) << " with type = " << qPrintable(getTypeString()) << endl; + //cout << "iface " << qPrintable(name) << " must be evaluated to vhdl :" << qPrintable(width) << " with type = " << qPrintable(getTypeString()) << endl; + + if (context == Instance) { + if (direction == Output) { + ret = "from_"+owner->getName()+"_"+name; + } + else if (direction == InOut) { + ret = "fromto_"+owner->getName()+"_"+name; + } + return ret; + } // create the width part QString widthStr = ""; @@ -411,10 +421,15 @@ QString AbstractInterface::toVHDL(int context, int flags) throw(Exception) { ret += widthStr; } else if (context == Signal) { - ret = widthStr; - } - else if (context == Architecture) { - + if (direction == Output) { + ret = "from_"+owner->getName()+"_"+name+" : "+widthStr; + } + else if (direction == InOut) { + ret = "fromto_"+owner->getName()+"_"+name+" : "+widthStr; + } + else if (direction == Input) { + ret = owner->getName()+"_"+name+" : "+widthStr; + } } return ret; diff --git a/AbstractInterface.h b/AbstractInterface.h index 1f6dd6f..3a3cb25 100644 --- a/AbstractInterface.h +++ b/AbstractInterface.h @@ -28,7 +28,7 @@ public : 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, Signal = 4 }; // NB : 3 is when creating an instance of the block that owns this iface + enum IfaceVHDLContext {AnyContext = 0, Entity = 1, Component = 2, Instance = 3, Signal = 4 }; enum IfaceVHDLFlags { NoComma = 1 }; static int getIntDirection(QString str); diff --git a/BlockParameter.h b/BlockParameter.h index 15df2d8..746a574 100644 --- a/BlockParameter.h +++ b/BlockParameter.h @@ -30,7 +30,7 @@ public : */ enum ParamWBAccess { Read = 1, Write = 2}; enum ParamWBDuration { Permanent = 1, Trigger = 2 }; - enum ParamVHDLContext { Entity = 1, Component = 2, Architecture = 3 }; // NB : 3 is when creating an instance of the block that owns this iface + enum ParamVHDLContext { Entity = 1, Component = 2, Instance = 3 }; // NB : 3 is when creating an instance of the block that owns this iface enum ParamVHDLFlags { NoComma = 1 }; BlockParameter(); diff --git a/BlockParameterGeneric.cpp b/BlockParameterGeneric.cpp index b5b5186..d652c37 100644 --- a/BlockParameterGeneric.cpp +++ b/BlockParameterGeneric.cpp @@ -69,13 +69,16 @@ QString BlockParameterGeneric::toVHDL(int context, int flags) { ret = formatNoValue.arg(name).arg(getTypeString()); } } - else if (context == BlockParameter::Architecture) { + else if (context == BlockParameter::Instance) { QString format = "%1 => %2"; if ((flags & BlockParameter::NoComma) == 0) { format.append(";"); } AbstractBlock* parent = owner->getParent(); - BlockParameter* p = parent->getParameterFromName(name); + BlockParameter* p = NULL; + if (parent != NULL) { + p = parent->getParameterFromName(name); + } if (p != NULL) { /* the parent group has a generic parameter with the same name diff --git a/BoxItem.cpp b/BoxItem.cpp index 85a1c9f..9ff42a8 100644 --- a/BoxItem.cpp +++ b/BoxItem.cpp @@ -791,6 +791,17 @@ void BoxItem::loadFunctional(QDomElement funcElement) throw(Exception) { functionalBlock->addInterface(ctlIface); } } + // connect clk and rst to group clk/rst or to clkrstgen + if ((name != "clkrstgen") && (parentGroupBlock != NULL)) { + try { + functionalBlock->connectClkReset(); + } + catch(Exception e) { + AbstractBlock* source = (AbstractBlock *)(e.getSource()); + cerr << qPrintable(source->getName()) << ":" << qPrintable(e.getMessage()) << endl; + throw(e); + } + } // creating InterfaceItem initInterfaceItems(); diff --git a/DelayInputModifier.cpp b/DelayInputModifier.cpp index e035c38..a90695a 100644 --- a/DelayInputModifier.cpp +++ b/DelayInputModifier.cpp @@ -1,5 +1,6 @@ #include "DelayInputModifier.h" #include "ConnectedInterface.h" +#include "AbstractBlock.h" DelayInputModifier::DelayInputModifier(ConnectedInterface *_associatedInterface, int _delayLength) : AbstractInputModifier(_associatedInterface) { setDelayLength(_delayLength); @@ -20,6 +21,52 @@ QList* DelayInputModifier::getModifiedInput(QList* input) { QString DelayInputModifier::toVHDL(int context, int flags) throw(Exception) { + + ConnectedInterface* fromCtlIface = associatedIface->getConnectedFrom(); + ConnectedInterface* fromIface = AI_TO_CON(fromCtlIface->getAssociatedIface()); + + ConnectedInterface* toCtlIface = associatedIface; + ConnectedInterface* toIface = AI_TO_CON(toCtlIface->getAssociatedIface()); + QString toName = toIface->getOwner()->getName()+"_"+toIface->getName(); + QString toCtlName = toCtlIface->getOwner()->getName()+"_"+toCtlIface->getName(); + QString dm1 = ""; + QString dm2 = ""; + dm1.setNum(delayLength-1); + dm2.setNum(delayLength-2); + QString ret=""; + if (context == Architecture) { + ret = toName + "_mod_process : process(clk,reset)\n"; + ret += " begin\n"; + ret += " if reset = '1' then\n"; + ret += " "+toName+"_dly <= (others => (others => '0'));\n"; + ret += " "+toCtlName+"_dly <= (others => '0');\n"; + ret += " "+toName+"_mod <= (others => '0');\n"; + ret += " "+toCtlName+"_mod <= '0';\n"; + ret += " elsif rising_edge(clk) then\n"; + ret += " "+toName+"_mod <= "+toName+"_dly("+dm1+");\n"; + ret += " "+toCtlName+"_mod <= "+toCtlName+"_dly("+dm1+");\n"; + ret += " "+toName+"_dly(0) <= "+fromIface->toVHDL(AbstractInterface::Instance,0)+";\n"; + ret += " "+toCtlName+"_dly(0) <= "+fromCtlIface->toVHDL(AbstractInterface::Instance,0)+";\n"; + ret += " "+toName+"_dly(1 to "+dm1+") <= "+toName+"_dly(0 to "+dm2+");\n"; + ret += " "+toCtlName+"_dly(1 to "+dm1+") <= "+toCtlName+"_dly(0 to "+dm2+");\n"; + ret += " end if\n"; + ret += " end process "+toName + "_mod_process\n"; + } + else if (context == Signal) { + QString sig = toIface->toVHDL(AbstractInterface::Signal,0); + sig.replace(" : ","_mod : "); + ret = " signal "+sig+"\n"; + sig = toCtlIface->toVHDL(AbstractInterface::Signal,0); + sig.replace(" : ","_mod : "); + ret += " signal "+sig+"\n"; + QString wStr=""; + wStr.setNum(toIface->getWidth()); + ret += " signal "+toName+"_dly : vector_of_std_logic_vector"+wStr+"(0 to "+dm1+");\n"; + ret += " signal "+toCtlName+"_dly : vector_of_std_logic(0 to "+dm1+");\n"; + } + + return ret; + } QString DelayInputModifier::getTypeStr() { diff --git a/GroupBlock.cpp b/GroupBlock.cpp index 9a8bb0f..66268b9 100644 --- a/GroupBlock.cpp +++ b/GroupBlock.cpp @@ -21,8 +21,17 @@ GroupBlock::GroupBlock(GroupBlock *_parent) throw(Exception) : AbstractBlock() // creating clk/rst interfaces clk = new GroupInterface(this,"clk", AbstractInterface::Input, AbstractInterface::Clock); rst = new GroupInterface(this,"reset", AbstractInterface::Input, AbstractInterface::Reset); - addInterface(clk); - addInterface(rst); + addInterface(clk); + addInterface(rst); + + try { + connectClkReset(); + } + catch(Exception e) { + AbstractBlock* source = (AbstractBlock *)(e.getSource()); + cerr << qPrintable(source->getName()) << ":" << qPrintable(e.getMessage()) << endl; + throw(e); + } } else { topGroup = true; @@ -436,33 +445,133 @@ void GroupBlock::generateArchitecture(QTextStream& out, QDomElement &elt) throw( out << " SIGNALS" << endl; out << " ----------------------------" << endl << endl; - out << " -- signals from input ports of " << name << endl; - QList listInputs = getInputs(); - foreach(AbstractInterface* iface, listInputs) { + + foreach(AbstractBlock* block, blocks) { + try { + out << " -- signals from output ports of " << block->getName() << endl; + QList listOutputs = block->getOutputs(); + foreach(AbstractInterface* iface, listOutputs) { + if ((iface->getPurpose() == AbstractInterface::Data)||(iface->getPurpose() == AbstractInterface::Control)) { + out << " signal " << iface->toVHDL(AbstractInterface::Signal,0) << endl; + } + else if (block->getName() == "clkrstgen") { + if ((iface->getPurpose() == AbstractInterface::Clock)||(iface->getPurpose() == AbstractInterface::Reset)) { + out << " signal " << iface->toVHDL(AbstractInterface::Signal,0) << endl; + } + } + } + } + catch(Exception e) { + throw(e); + } + out << endl; + } + foreach(AbstractBlock* block, blocks) { + try { + out << " -- signals for modified input ports of " << block->getName() << endl; + QList listInputs = block->getInputs(); + foreach(AbstractInterface* iface, listInputs) { + if (iface->getPurpose() == AbstractInterface::Control) { + ConnectedInterface* connCtlIface = AI_TO_CON(iface); + AbstractInputModifier* modifier = connCtlIface->getInputModifier(); + if (modifier != NULL) { + out << modifier->toVHDL(AbstractInputModifier::Signal,0) << endl; + } + } + } + } + catch(Exception e) { + throw(e); + } + out << endl; + } + + out << "begin" << endl; + + // generate signals that goes to the output ports + + out << " -- connections to output ports of " << name << endl; + QList listOutputs = getOutputs(); + foreach(AbstractInterface* iface, listOutputs) { 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; - } + ConnectedInterface* fromIface = connIface->getConnectedFrom(); + out << " " << connIface->getName() << " <= " << fromIface->toVHDL(AbstractInterface::Instance,0) << ";" << endl; } } + out << endl; + + + + // generate instances foreach(AbstractBlock* block, blocks) { try { - out << " -- signals from output ports of " << block->getName() << endl; + out << " " << block->getName() << "_1 : " << block->getName() << endl; + + QList listGenerics = block->getGenericParameters(); + QList listInputs = block->getInputs(); QList 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; + QList listBidirs = block->getBidirs(); + + if (!listGenerics.isEmpty()) { + out << " generic map (" << endl; + for(i=0;itoVHDL(BlockParameter::Instance, BlockParameter::NoComma) << "," << endl; + } + out << " " << listGenerics.at(i)->toVHDL(BlockParameter::Instance,BlockParameter::NoComma) << endl; + out << " )" << endl; + } + + out << " port map (" << endl; + QString portMap = ""; + + for(i=0;igetConnectedFrom(); + + if (fromIface->isFunctionalInterface()) { + portMap += " " + connIface->getName() + " => "; + bool hasMod = false; + if (connIface->getPurpose() == AbstractInterface::Data) { + ConnectedInterface* connCtlIface = AI_TO_CON(connIface->getAssociatedIface()); + if ((connCtlIface != NULL) && (connCtlIface->getInputModifier() != NULL)) { + hasMod = true; + } + } + else if (connIface->getPurpose() == AbstractInterface::Control) { + if (connIface->getInputModifier() != NULL) { + hasMod = true; + } } + if (hasMod) { + portMap += connIface->getOwner()->getName()+"_"+connIface->getName()+"_mod,\n"; + } + else { + portMap += fromIface->toVHDL(AbstractInterface::Instance, AbstractInterface::NoComma) + ",\n"; + } + } + else if (fromIface->isGroupInterface()) { + portMap += " " + connIface->getName() + " => " + fromIface->getName() + ",\n"; + } + } + if (listOutputs.size()>0) { + for(i=0;igetName() + " => " + connIface->toVHDL(AbstractInterface::Instance, AbstractInterface::NoComma) + ",\n"; + } + } + if (listBidirs.size()>0) { + for(i=0;igetName() + " => " + connIface->toVHDL(AbstractInterface::Instance, AbstractInterface::NoComma) + ",\n"; } } + portMap.chop(2); + out << portMap << endl; + + + out << " );" << endl; } catch(Exception e) { throw(e); @@ -470,6 +579,26 @@ void GroupBlock::generateArchitecture(QTextStream& out, QDomElement &elt) throw( out << endl; } + // generate input modifiers + foreach(AbstractBlock* block, blocks) { + + foreach(AbstractInterface* iface, block->getControlInputs()) { + ConnectedInterface* connIface = AI_TO_CON(iface); + // check if it is connected + if (connIface->getConnectedFrom() == NULL) { + throw(Exception(IFACE_NOT_CONNECTED,this)); + } + AbstractInputModifier* modifier = connIface->getInputModifier(); + if (modifier != NULL) { + try { + out << modifier->toVHDL(AbstractInputModifier::Architecture,0) << endl; + } + catch(Exception e) { + throw(e); + } + } + } + } out << "end architecture rtl;" << endl; } diff --git a/blast.creator.user b/blast.creator.user index af36049..3d17b3d 100644 --- a/blast.creator.user +++ b/blast.creator.user @@ -1,10 +1,10 @@ - + EnvironmentId - {3701e197-5b6c-48ea-9e98-a6cf6de18672} + {c8006d66-d34f-42be-ad10-d0207752286d} ProjectExplorer.Project.ActiveTarget @@ -61,7 +61,7 @@ Desktop Desktop - {ed04208c-8774-456b-99b9-4a02094ca7a4} + {2c9bf876-3476-44eb-8065-1f0844704dda} 0 0 0