From f8a72288aa2c45ac71b30a68781450ba0fecf1b6 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Wed, 20 May 2015 14:02:18 +0200 Subject: [PATCH] Better handling of exceptions between C++ & Python. Misc. checks. * Bug: In Hurricane, in PyHurricane.h the macro HCATCH was not catching standard STL exceptions. This was the source of the cryptic message: "Fatal Python error: Py_EndInterpreter: thread still has a frame" The Python interpreter was interrupted uncleanly bypassing it's own exceptions mechanism. In PyViewer, the Viewer *do not* inherit from a base class (in the Python export). * New: In Hurricane, in DbU, compute maximum values (in double) for grid, lambda & physical (in meter) so now the DbU::toGrid(), DbU::toLambda() & DbU::toPhysical() methods can check for out of bound values, and throw an exception. * Change: In Hurricane, ExceptionWidget::catchAllWrapper() now returns a boolean, set to if an exception has been catched. Allow callers to interrupt themselves if a problem has occured. * Bug: In Kite & Etesian, in the Python wrapper, send a Python exception if catchAllwrapper() did return true, instead of continuing... * Change: In Kite & Etesian, adds a setViewer() method (exported in Python) to use the graphical ExceptionWidget when in graphic mode. * Bug: In Cumulus, in PadsCorona.py the check for the core vs. chip size was not returning False when invalid. * New: In CRL Core, in Vst driver, add a support IEEE VHDL. Inactive for now as I don't see clearly the policy for selecting it or not. Remove the code of the old Vst driver. In Blif parser, check for non-existent models (incomplete or corrupted Blif file). Found by G. Gouvine. * New: Added extras file for IDE-like support under Emacs. --- .dir-locals.el | 38 + .gitignore | 4 + .projectile | 6 + crlcore/src/ccore/AllianceFramework.cpp | 3 + crlcore/src/ccore/alliance/vst/VhdlEntity.cpp | 19 +- crlcore/src/ccore/alliance/vst/VhdlSignal.cpp | 28 +- crlcore/src/ccore/alliance/vst/VstDriver.cpp | 690 +----------------- crlcore/src/ccore/blif/BlifParser.cpp | 4 + crlcore/src/ccore/crlcore/VhdlEntity.h | 9 +- cumulus/src/plugins/ChipPlugin.py | 3 +- cumulus/src/plugins/chip/Configuration.py | 42 +- cumulus/src/plugins/chip/PadsCorona.py | 10 +- etesian/src/AddFeeds.cpp | 3 +- etesian/src/EtesianEngine.cpp | 9 +- etesian/src/GraphicEtesianEngine.cpp | 2 +- etesian/src/PyEtesianEngine.cpp | 49 +- etesian/src/etesian/EtesianEngine.h | 111 +-- hurricane/src/hurricane/DbU.cpp | 54 +- hurricane/src/hurricane/hurricane/DbU.h | 16 +- .../src/isobar/hurricane/isobar/PyHurricane.h | 25 +- hurricane/src/viewer/ExceptionWidget.cpp | 5 +- hurricane/src/viewer/PyViewer.cpp | 2 +- .../viewer/hurricane/viewer/ExceptionWidget.h | 2 +- .../viewer/hurricane/viewer/PyCellViewer.h | 2 +- kite/src/PyKiteEngine.cpp | 86 ++- 25 files changed, 402 insertions(+), 820 deletions(-) create mode 100644 .dir-locals.el create mode 100644 .projectile diff --git a/.dir-locals.el b/.dir-locals.el new file mode 100644 index 00000000..93a59750 --- /dev/null +++ b/.dir-locals.el @@ -0,0 +1,38 @@ +((nil . ((company-clang-arguments + . ("-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/crlcore/src/ccore/agds" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/crlcore/src/ccore/alliance/ap" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/crlcore/src/ccore/alliance/vst" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/crlcore/src/ccore/bookshelf" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/crlcore/src/ccore/cif" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/crlcore/src/ccore/crlcore" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/crlcore/src/ccore/lefdef" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/crlcore/src/ccore/liberty" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/crlcore/src/ccore/openaccess" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/crlcore/src/ccore/spice" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/crlcore/src/ccore/toolbox" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/crlcore/src/cyclop" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/crlcore/src/fonts" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/crlcore/src/LibraryManager/crlcore" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/crlcore/src/pyCRL/crlcore" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/equinox/src/equinox" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/equinox/src/intervalTree/src/equinox" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/etesian/src/etesian" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/hurricane/src/hurricane/hurricane" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/hurricane/src/isobar/hurricane/isobar" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/hurricane/src/viewer/hurricane/viewer" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/hurricane/src/viewer/obsoletes" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/katabatic/src/katabatic" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/kite/src/kite" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/knik/src/knik" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/solstice/src/solstice" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/unicorn/src/unicorn" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/vlsisapd/src/agds/src/vlsisapd/agds" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/vlsisapd/src/bookshelf/src/vlsisapd/bookshelf" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/vlsisapd/src/cif/src/vlsisapd/cif" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/vlsisapd/src/configuration/src/vlsisapd/configuration" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/vlsisapd/src/dtr/src/vlsisapd/dtr" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/vlsisapd/src/liberty/src/vlsisapd/liberty" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/vlsisapd/src/openChams/src/vlsisapd/openChams" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/vlsisapd/src/spice/src/vlsisapd/spice" + "-I/dsk/l1/jpc/coriolis-2.x/src/coriolis/vlsisapd/src/utilities/src/vlsisapd/utilities" + ))))) diff --git a/.gitignore b/.gitignore index 1b8a5f44..82129b60 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,10 @@ *.bak TAGS +GTAGS +GPATH +GRTAGS + man/ rtf/ diff --git a/.projectile b/.projectile new file mode 100644 index 00000000..cfbd3c87 --- /dev/null +++ b/.projectile @@ -0,0 +1,6 @@ +-*.fig +-*.png +-*.eps +-*.pdf +-*.aux +-*.bb diff --git a/crlcore/src/ccore/AllianceFramework.cpp b/crlcore/src/ccore/AllianceFramework.cpp index 36fd0d25..581c1b46 100644 --- a/crlcore/src/ccore/AllianceFramework.cpp +++ b/crlcore/src/ccore/AllianceFramework.cpp @@ -33,6 +33,9 @@ #include "crlcore/AllianceFramework.h" + + + namespace CRL { diff --git a/crlcore/src/ccore/alliance/vst/VhdlEntity.cpp b/crlcore/src/ccore/alliance/vst/VhdlEntity.cpp index 4305ab88..149c742b 100644 --- a/crlcore/src/ccore/alliance/vst/VhdlEntity.cpp +++ b/crlcore/src/ccore/alliance/vst/VhdlEntity.cpp @@ -273,7 +273,7 @@ namespace Vhdl { for ( auto isignal=internalSignals.begin(); isignal!=internalSignals.end() ; ++isignal ) { out << tab; - (*isignal)->toVhdlPort( out, width, Entity::AsInnerSignal ); + (*isignal)->toVhdlPort( out, width, Entity::AsInnerSignal|(_flags & Entity::IeeeMode) ); out << ";\n"; } out << "\n"; @@ -297,7 +297,7 @@ namespace Vhdl { size_t ioCount = 0; for ( auto isignal=ioSignals.begin(); isignal!=ioSignals.end() ; ++isignal ) { if (ioCount) out << "\n" << tab << " ; "; - (*isignal)->toVhdlPort( out, width, Entity::AsPortSignal ); + (*isignal)->toVhdlPort( out, width, Entity::AsPortSignal|(_flags & Entity::IeeeMode ) ); ++ioCount; } out << "\n" << tab << " );"; @@ -317,10 +317,21 @@ namespace Vhdl { out << "-- Coriolis Structural VHDL Driver\n"; out << "-- Generated on " << stamp << "\n"; out << "-- \n"; - out << "-- To be interoperable with Alliance, it uses it's special VHDL subset.\n"; - out << "-- (\"man vhdl\" under Alliance for more informations)\n"; + if (isIeeeMode()) { + out << "-- VHDL IEEE compliant.\n"; + } else { + out << "-- To be interoperable with Alliance, it uses it's special VHDL subset.\n"; + out << "-- (\"man vhdl\" under Alliance for more informations)\n"; + } out << "-- =======================================================================\n"; out << "\n"; + + if (isIeeeMode()) { + out << "library IEEE;\n"; + out << "use IEEE.std_logic_1164.all;\n"; + out << "use IEEE.numeric_std.all;\n\n\n"; + } + out << tab++ << "entity " << getCell()->getName() << " is\n"; toPort( out ); out << --tab << "\nend " << getCell()->getName() << ";\n\n"; diff --git a/crlcore/src/ccore/alliance/vst/VhdlSignal.cpp b/crlcore/src/ccore/alliance/vst/VhdlSignal.cpp index 2252dd12..77f4ca01 100644 --- a/crlcore/src/ccore/alliance/vst/VhdlSignal.cpp +++ b/crlcore/src/ccore/alliance/vst/VhdlSignal.cpp @@ -59,18 +59,26 @@ namespace Vhdl { } if (not range.empty()) { - switch ( (unsigned int)direction & (Net::Direction::ConnTristate - |Net::Direction::ConnWiredOr) ) { - case Net::Direction::ConnTristate: out << " mux_vector" << range << " bus"; break; - case Net::Direction::ConnWiredOr: out << " wor_vector" << range << " bus"; break; - default: out << " bit_vector" << range; + if (flags & Entity::IeeeMode) { + out << " std_logic_vector" << range; + } else { + switch ( (unsigned int)direction & (Net::Direction::ConnTristate + |Net::Direction::ConnWiredOr) ) { + case Net::Direction::ConnTristate: out << " mux_vector" << range << " bus"; break; + case Net::Direction::ConnWiredOr: out << " wor_vector" << range << " bus"; break; + default: out << " bit_vector" << range; + } } } else { - switch ( (unsigned int)direction & (Net::Direction::ConnTristate - |Net::Direction::ConnWiredOr) ) { - case Net::Direction::ConnTristate: out << " mux_bit bus"; break; - case Net::Direction::ConnWiredOr: out << " wor_bit bus"; break; - default: out << " bit"; + if (flags & Entity::IeeeMode) { + out << " std_logic"; + } else { + switch ( (unsigned int)direction & (Net::Direction::ConnTristate + |Net::Direction::ConnWiredOr) ) { + case Net::Direction::ConnTristate: out << " mux_bit bus"; break; + case Net::Direction::ConnWiredOr: out << " wor_bit bus"; break; + default: out << " bit"; + } } } } diff --git a/crlcore/src/ccore/alliance/vst/VstDriver.cpp b/crlcore/src/ccore/alliance/vst/VstDriver.cpp index ce610e3d..ceedb0d3 100644 --- a/crlcore/src/ccore/alliance/vst/VstDriver.cpp +++ b/crlcore/src/ccore/alliance/vst/VstDriver.cpp @@ -31,688 +31,22 @@ using namespace Hurricane; #include "Vst.h" -namespace { - - using namespace std; - using namespace CRL; - - - class GlobalNetLookup { - public: - inline void addLookup ( Net* ); - inline Net* lookup ( const string& ); - inline bool isGlobal ( Net* ); - inline void clear (); - private: - map _globalNets; - }; - - - inline void GlobalNetLookup::addLookup ( Net* globalNet ) - { - if ( globalNet == NULL ) return; - _globalNets.insert ( make_pair(getString(globalNet->getName()) - ,globalNet - ) ); - } - - - inline Net* GlobalNetLookup::lookup ( const string& name ) - { - map::iterator inet = _globalNets.find(name); - if ( inet == _globalNets.end() ) return NULL; - return (*inet).second; - } - - - inline bool GlobalNetLookup::isGlobal ( Net* globalNet ) - { - if ( globalNet == NULL ) return false; - return (lookup(getString(globalNet->getName())) != NULL); - } - - - inline void GlobalNetLookup::clear () - { _globalNets.clear (); } - - - GlobalNetLookup __globalNets; - - -void FilterPointsInStrings(string& s) { - // Problem in VST... : the . which seems to represent hierachy paths - // in ap is not supported... - // So for the moment we just replace . by _ ... Hope this works - // If you are reading this message then maybe it does not!! - string::size_type iterator = s.find('.'); - while (iterator != string::npos) - { - s[iterator] = '_'; - iterator = s.find('.', iterator); - } -} - -struct StringSort -{ - - // Sorts signals taking into account parenthesis ... - // i(0) is before i(10) - bool operator()(const string* string1, const string* string2) const - { - string::size_type string1OpenPar = string1->find('('); - string::size_type string2OpenPar = string2->find('('); - if ((string1OpenPar == string::npos) || (string2OpenPar == string::npos)) - return (*string1 < *string2); - if ((string1->find('(', string1OpenPar + 1) != string::npos) - || (string2->find('(', string2OpenPar + 1) != string::npos)) - throw Error("malformed string, multi '(' in <%s>", string2->c_str()); - string::size_type string1ClosePar = string1->rfind(')'); - string::size_type string2ClosePar = string2->rfind(')'); - if ((string1ClosePar == string::npos) || (string2ClosePar == string::npos)) - throw Error("malformed string, cannot find ')'"); - if ((string1ClosePar != string1->size()-1) || (string2ClosePar != string2->size()-1)) { - cerr << "string1 := \"" << *string1 << "\"" << endl; - cerr << "string2 := \"" << *string2 << "\"" << endl; - throw Error("malformed string"); - } - if ((string1->rfind(')', string1ClosePar - 1) != string::npos) - || (string2->rfind(')', string2ClosePar - 1) != string::npos)) - throw Error("malformed string, multi ')'"); - - if (string1->compare(0, string1OpenPar + 1, *string2, 0, string2OpenPar + 1)) - return (*string1 < *string2); - - string number1String = string(*string1, string1OpenPar + 1, string1->size()-string1OpenPar-2); - string number2String = string(*string2, string2OpenPar + 1, string2->size()-string2OpenPar-2); - - int number1 = atoi(number1String.c_str()); - int number2 = atoi(number2String.c_str()); - - return (number1 < number2); - } -}; - -unsigned FindIndex(const string& stringtosearch, string::size_type openpar) -{ - string numberString = string(stringtosearch, openpar+1, stringtosearch.size()-openpar-2); - return atoi(numberString.c_str()); -} - -string getNetDirection(const Net* net) -{ - switch ( net->getDirection() & (Net::Direction::INOUT | Net::Direction::UNDEFINED) ) { - case Net::Direction::UNDEFINED: return "linkage"; - case Net::Direction::IN: return "in"; - case Net::Direction::OUT: return "out"; - case Net::Direction::INOUT: return "inout"; - default: - throw Error( "Unrecognized direction for Net <%s> of Cell <%s> (code:%u)" - , getString(net->getCell()->getName()).c_str() - , getString(net->getName()).c_str() - , (unsigned int)net->getDirection() ); - } -} - -typedef vector StringPtVector; -typedef vector StringVector; -typedef map StringNetMap; -typedef map StringPlugMap; -typedef set NetSet; -typedef vector PlugVector; - -unsigned FindBiggestName(StringPtVector& stringptvector) -{ - unsigned biggest = 0; - for (StringPtVector::const_iterator spvit = stringptvector.begin(); - spvit != stringptvector.end(); - spvit++) - { - string::size_type stringOpenPar = (*spvit)->find('('); - if (stringOpenPar != string::npos) - { - if (biggest < stringOpenPar) - biggest = stringOpenPar; - } - else - if (biggest < (*spvit)->size()) - biggest = (*spvit)->size(); - } - return biggest; -} - -void DumpPortList(ofstream &ccell, Cell* cell) -{ - ccell << " port (" << endl; - StringPtVector netsString; - StringNetMap stringNetMap; - for_each_net(net, cell->getExternalNets()) - { - const Name& name = NetExtension::getPort(net); - string* stringName; - if (!name.isEmpty()) - stringName = new string(getString(name)); - else - stringName = new string(getString(net->getName())); - netsString.push_back(stringName); - StringNetMap::iterator snmit = stringNetMap.find(stringName); - if (snmit != stringNetMap.end()) - { - throw Error("two times the same name"); - } - stringNetMap[stringName] = net; - end_for; - } - sort(netsString.begin(), netsString.end(), StringSort()); - - unsigned biggestName = FindBiggestName(netsString); - - StringVector vectorizedNetsString; - StringPtVector::const_iterator spvit = netsString.begin(); - while (spvit!=netsString.end()) - { - const string* string1 = *spvit; - string::size_type string1OpenPar = string1->find('('); - StringNetMap::iterator snmit = stringNetMap.find(string1); - if (snmit == stringNetMap.end()) - { - throw Error("Cannot find net named " + *string1); - } - Net* net1 = snmit->second; - string bitType; - if (net1->getDirection() & Net::Direction::ConnTristate) bitType = " mux_bit bus"; - else if (net1->getDirection() & Net::Direction::ConnWiredOr ) bitType = " wor_bit bus"; - else bitType = " bit"; - - if (string1OpenPar == string::npos) - { - vectorizedNetsString.push_back( - " " - + *string1 - + string(biggestName - string1->size() + 1, ' ') - + ": " - + getNetDirection(net1) - + bitType); - ++spvit; - continue; - } - - unsigned index1 = 0; - unsigned index2 = 0; - bool vectorFound = false; - - while (++spvit != netsString.end()) - { - if (!vectorFound) - { - index1 = index2 = FindIndex(*string1, string1OpenPar); - } - const string* string2 = *spvit; - StringNetMap::iterator snmit = stringNetMap.find(string2); - if (snmit == stringNetMap.end()) - { - throw Error("Cannot find net named " + *string2); - } - Net* net2 = snmit->second; - string::size_type string2OpenPar = string2->find('('); - if (string2OpenPar == string::npos) - break; - if (string1->compare(0, string1OpenPar + 1, *string2, 0, string2OpenPar + 1)) - break; - if (net1->getDirection() != net2->getDirection()) - break; - unsigned newIndex = FindIndex(*string2, string2OpenPar); - if (!vectorFound) - { - index1 = FindIndex(*string1, string1OpenPar); - if (newIndex != index1+1) - break; - index2 = newIndex; - vectorFound= true; - } - else - { - if (newIndex != index2+1) - break; - index2 = newIndex; - } - } - ostringstream index1StringStream; - index1StringStream << index1; - ostringstream index2StringStream; - index2StringStream << index2; - string name = string(*string1, 0, string1OpenPar); - string vectorType; - string busType; - if (net1->getDirection() & Net::Direction::ConnTristate) { - vectorType = " mux_vector("; - busType = " bus"; - } else if (net1->getDirection() & Net::Direction::ConnWiredOr) { - vectorType = " wor_vector("; - busType = " bus"; - } else - vectorType = " bit_vector("; - - vectorizedNetsString.push_back( - " " - + name - + string(biggestName - name.size() + 1, ' ') - + ": " - + getNetDirection(net1) - + vectorType - + index2StringStream.str() - + " downto " - + index1StringStream.str() - + ")" - + busType); - } - - StringVector::const_iterator svit = vectorizedNetsString.begin(); - while ((svit != vectorizedNetsString.end()) && (svit+1 != vectorizedNetsString.end())) - { - ccell << *(svit++) << ";" << endl; - } - if (svit != vectorizedNetsString.end()) - ccell << *svit << endl; - ccell << " );" << endl; - for (StringPtVector::iterator spvit = netsString.begin(); - spvit != netsString.end(); - spvit++) - { - delete(*spvit); - } -} - -void DumpSignalList(ofstream &ccell, Cell* cell) -{ - StringPtVector netsString; - NetSet netSet; - forEach(Net*, inet, cell->getNets()) - { - if ( not (*inet)->isExternal() ) { - string* stringName = new string(inet->getName()._getString()); - FilterPointsInStrings(*stringName); - netsString.push_back(stringName); - NetSet::iterator nsit = netSet.find(*inet); - if (nsit != netSet.end()) - throw Error("two times the same name"); - netSet.insert(*inet); - } - if ( (*inet)->isGlobal() ) { - __globalNets.addLookup ( *inet ); - } - } - sort(netsString.begin(), netsString.end(), StringSort()); - - unsigned biggestName = FindBiggestName(netsString); - - StringPtVector::const_iterator spvit = netsString.begin(); - while (spvit!=netsString.end()) - { - const string* string1 = *spvit; - string::size_type string1OpenPar = string1->find('('); - - if (string1OpenPar == string::npos) - { - ccell << "signal " - << *string1 - << string(biggestName - string1->size() + 1, ' ') - << ": bit;" - << endl; - ++spvit; - continue; - } - - unsigned index1 = FindIndex(*string1, string1OpenPar); - unsigned index2 = index1; - - while (++spvit != netsString.end()) - { - const string* string2 = *spvit; - string::size_type string2OpenPar = string2->find('('); - if (string2OpenPar == string::npos) - break; - if (string1->compare(0, string1OpenPar + 1, *string2, 0, string2OpenPar + 1)) - break; - unsigned newIndex = FindIndex(*string2, string2OpenPar); - //if (newIndex != index2+1) - // break; - index2 = newIndex; - } - ostringstream index1StringStream; - index1StringStream << index1; - ostringstream index2StringStream; - index2StringStream << index2; - string name = string(*string1, 0, string1OpenPar); - ccell << "signal " - << name - << string(biggestName - name.size() + 1, ' ') - << ": bit_vector(" - << index2StringStream.str() - << " downto " - << index1StringStream.str() - << ");" - << endl; - } - - for (StringPtVector::iterator spvit = netsString.begin(); - spvit != netsString.end(); - spvit++) - { - delete(*spvit); - } -} - -void DumpConnectionList(ofstream &ccell, Instance*instance) -{ - ccell << " port map ( " << endl; - - StringPtVector netsString; - StringPlugMap stringPlugMap; - for_each_plug(plug, instance->getPlugs()) - { - Net* masterNet = plug->getMasterNet(); - const Name& name = NetExtension::getPort(masterNet); - string* netName; - if (!name.isEmpty()) - netName = new string(getString(name)); - else - netName = new string(getString(masterNet->getName())); - netsString.push_back(netName); - StringPlugMap::iterator spmit = stringPlugMap.find(netName); - if (spmit != stringPlugMap.end()) - { - throw Error("two times the same name"); - } - stringPlugMap[netName] = plug; - end_for; - } - - sort(netsString.begin(), netsString.end(), StringSort()); - - unsigned biggestName = FindBiggestName(netsString); - - StringVector connectionsString; - StringPtVector::const_iterator spvit = netsString.begin(); - while (spvit!=netsString.end()) - { - const string* string1 = *spvit; - string::size_type string1OpenPar = string1->find('('); - StringPlugMap::iterator spmit = stringPlugMap.find(string1); - if (spmit == stringPlugMap.end()) - { - throw Error("Cannot find net named " + *string1); - } - if (string1OpenPar == string::npos) - { - Plug* plug = spmit->second; - string connectedNetName; - if (plug->isConnected()) { - Net* net = plug->getNet(); - if (net->isExternal()) { - const Name& name = NetExtension::getPort(net); - if (!name.isEmpty()) - connectedNetName = getString(name); - else - connectedNetName = getString(net->getName()); - } - else - connectedNetName = getString(net->getName()); - } else { - Net* masterNet = plug->getMasterNet(); - if (masterNet->isGlobal()) // connection by name - { - Net* globalNet = __globalNets.lookup ( getString(masterNet->getName()) ); - if ( globalNet != NULL ) connectedNetName = getString(globalNet->getName()); -#if VERY_SLOW - for_each_net(globalnet, instance->getCell()->getGlobalNets()) - { - if (globalnet->getName() == masterNet->getName()) - { - connectedNetName = string(masterNet->getName()._getString()); - break; - } - end_for; - } -#endif - if ( connectedNetName.empty() ) { - throw Error("No global net " + masterNet->getName()._getString() + " in cell " + instance->getCell()->getName()._getString()); - } - } - else - { - throw Error("Plug " + masterNet->getName()._getString() + " of instance " + instance->getName()._getString() + " must be connected"); - } - } - FilterPointsInStrings(connectedNetName); - - connectionsString.push_back( - " " - + *string1 - + string(biggestName - string1->size() + 1, ' ') - + " => " - + connectedNetName - ); - ++spvit; - continue; - } - - Plug* plug1 = spmit->second; - unsigned index1 = 0; - unsigned index2 = 0; - PlugVector plugConnectedVector; - plugConnectedVector.push_back(plug1); - bool vectorFound = false; - - while (++spvit != netsString.end()) - { - const string* string2 = *spvit; - StringPlugMap::iterator spmit = stringPlugMap.find(string2); - if (spmit == stringPlugMap.end()) - { - throw Error("Cannot find plug named " + *string2); - } - string::size_type string2OpenPar = string2->find('('); - if (string2OpenPar == string::npos) - break; - if (string1->compare(0, string1OpenPar + 1, *string2, 0, string2OpenPar + 1)) - break; - unsigned newIndex = FindIndex(*string2, string2OpenPar); - if (!vectorFound) - { - index1 = FindIndex(*string1, string1OpenPar); - if (newIndex != index1+1) - break; - index2 = newIndex; - Plug* plug2 = spmit->second; - plugConnectedVector.push_back(plug2); - vectorFound= true; - } - else - { - if (newIndex != index2+1) - break; - index2 = newIndex; - Plug* plug2 = spmit->second; - plugConnectedVector.push_back(plug2); - } - } - - if (vectorFound) - { - if (index2 > index1) - reverse(plugConnectedVector.begin(), plugConnectedVector.end()); - string connections; - PlugVector::const_iterator pvit = plugConnectedVector.begin(); - while (pvit != plugConnectedVector.end()) - { - Plug* plug = *pvit; - string connectedNetName; - if (plug->isConnected()) { - Net* net = plug->getNet(); - if (net->isExternal()) { - const Name& name = NetExtension::getPort(net); - if (!name.isEmpty()) - connectedNetName = getString(name); - else - connectedNetName = getString(net->getName()); - } - else - connectedNetName = getString(net->getName()); - } - else - if (plug->getMasterNet()->isGlobal()) - { - cerr << "Make all your connections" << endl; - exit(1); - } - FilterPointsInStrings(connectedNetName); - if (pvit+1 == plugConnectedVector.end()) - connections += connectedNetName; - else - connections += connectedNetName + "&"; - ++pvit; - } - string name = string(*string1, 0, string1OpenPar); - connectionsString.push_back( - " " - + name - + string(biggestName - name.size() + 1, ' ') - + " => " - + connections - ); - } - else - { - string name; - if (string1OpenPar != string::npos) - { - name = string(*string1, 0, string1OpenPar); - } - else - { - name = *string1; - } - - string connectedNetName; - if (plug1->isConnected()) - { - cerr << plug1 << "plug is connected" << endl; - Net* net = plug1->getNet(); - const Name& portName = NetExtension::getPort(net); - if (!portName.isEmpty()) - connectedNetName = getString(portName); - else - connectedNetName = getString(net->getName()); - } - else - if (plug1->getMasterNet()->isGlobal()) { - cerr << "Make all your connections" << endl; - exit(1); - } - - FilterPointsInStrings(connectedNetName); - connectionsString.push_back( - " " - + name - + string(biggestName - name.size() + 1, ' ') - + " => " - + connectedNetName - ); - } - } - - StringVector::const_iterator csit = connectionsString.begin(); - while (csit != connectionsString.end()) - { - if (csit+1 == connectionsString.end()) - ccell << *csit << endl; - else - ccell << *csit << "," << endl; - ++csit; - } - ccell << " );" << endl; - - for (StringPtVector::iterator spvit = netsString.begin(); - spvit != netsString.end(); - spvit++) - { - delete(*spvit); - } -} - -} - - namespace CRL { -void vstDriver ( const string cellPath, Cell *cell, unsigned int &saveState ) -{ - NamingScheme::toVhdl( cell, NamingScheme::FromVerilog ); - Vhdl::Entity* vhdlEntity = Vhdl::EntityExtension::create( cell, Vhdl::Entity::EntityMode ); - string celltest = cellPath; -//celltest.insert( celltest.size()-4, "_test" ); - ::std::ofstream ccelltest ( celltest.c_str() ); - vhdlEntity->toEntity(ccelltest); - ccelltest << endl; - ccelltest.close(); + using namespace std; -#if 0 - __globalNets.clear (); - ::std::ofstream ccell ( cellPath.c_str() ); - ccell << "entity " << cell->getName() << " is" << endl; - DumpPortList(ccell, cell); - ccell << "end " << cell->getName() << ";" << endl; - ccell << endl; - ccell << "architecture structural of " << cell->getName() << " is" << endl; - typedef set ModelSet; - ModelSet modelSet; - typedef list InstanceList; - InstanceList instanceList; - for_each_instance(instance, cell->getInstances()) - { - Cell* model = instance->getMasterCell(); - CatalogProperty *stateProp = - static_cast(model->getProperty(CatalogProperty::getPropertyName())); - - if (stateProp && (stateProp->getState()->isFeed())) - continue; - - modelSet.insert(model); - instanceList.push_back(instance); - end_for; - } - - for (ModelSet::const_iterator msit = modelSet.begin(); - msit != modelSet.end(); - msit++) - { - Cell* model = *msit; - ccell << "component " << model->getName() << endl; - DumpPortList(ccell, model); - ccell << "end component;" << endl; - ccell << endl; - } + void vstDriver ( const string cellPath, Cell *cell, unsigned int &saveState ) + { + NamingScheme::toVhdl( cell, NamingScheme::FromVerilog ); + Vhdl::Entity* vhdlEntity = Vhdl::EntityExtension::create( cell, Vhdl::Entity::EntityMode|Vhdl::Entity::IeeeMode ); + string celltest = cellPath; + ofstream ccelltest ( celltest.c_str() ); - DumpSignalList(ccell, cell); + vhdlEntity->toEntity( ccelltest ); + ccelltest << endl; + ccelltest.close(); + } - ccell << endl << "begin" << endl << endl; - for (InstanceList::const_iterator ilit = instanceList.begin(); - ilit != instanceList.end(); - ilit++) - { - Instance* instance = *ilit; - string insName(instance->getName()._getString()); - FilterPointsInStrings(insName); - ccell << insName << " : " << instance->getMasterCell()->getName() << endl; - - DumpConnectionList(ccell, instance); - ccell << endl; - } - ccell << "end structural;" << endl; - ccell.close (); -#endif -} - -} +} // CRL namespace. diff --git a/crlcore/src/ccore/blif/BlifParser.cpp b/crlcore/src/ccore/blif/BlifParser.cpp index 0f4a28f7..44efbe5e 100644 --- a/crlcore/src/ccore/blif/BlifParser.cpp +++ b/crlcore/src/ccore/blif/BlifParser.cpp @@ -468,6 +468,10 @@ namespace { void Model::connectSubckts () { for ( Subckt* subckt : _subckts ) { + if(not subckt->getModel()) + throw Error( "No .model or cell named <%s> has been found.\n" + , subckt->getModelName().c_str() ); + Instance* instance = Instance::create( _cell , subckt->getInstanceName() , subckt->getModel()->getCell() diff --git a/crlcore/src/ccore/crlcore/VhdlEntity.h b/crlcore/src/ccore/crlcore/VhdlEntity.h index bb69a6ff..d5d8270f 100644 --- a/crlcore/src/ccore/crlcore/VhdlEntity.h +++ b/crlcore/src/ccore/crlcore/VhdlEntity.h @@ -58,9 +58,10 @@ namespace Vhdl { public: enum Flag { NoFlags = 0x0000 , EntityMode = 0x0001 - , ComponentMode = 0x0002 - , AsPortSignal = 0x0004 - , AsInnerSignal = 0x0008 + , IeeeMode = 0x0002 + , ComponentMode = 0x0004 + , AsPortSignal = 0x0008 + , AsInnerSignal = 0x0010 }; public: static bool parseNetName ( const Net*, std::string& stem, size_t& index ); @@ -70,6 +71,7 @@ namespace Vhdl { Entity ( EntityProperty*, Cell*, unsigned int flags ); ~Entity (); inline bool isEntityMode () const; + inline bool isIeeeMode () const; inline bool isComponentMode () const; const Cell* getCell () const; const Signal* getSignal ( std::string name ) const; @@ -92,6 +94,7 @@ namespace Vhdl { }; + inline bool Entity::isIeeeMode () const { return _flags & IeeeMode; } inline bool Entity::isEntityMode () const { return _flags & EntityMode; } inline bool Entity::isComponentMode () const { return _flags & ComponentMode; } diff --git a/cumulus/src/plugins/ChipPlugin.py b/cumulus/src/plugins/ChipPlugin.py index 93219970..7482547e 100644 --- a/cumulus/src/plugins/ChipPlugin.py +++ b/cumulus/src/plugins/ChipPlugin.py @@ -147,6 +147,7 @@ class PlaceCore ( chip.Configuration.ChipConfWrapper ): mauka.destroy() else: etesian = Etesian.EtesianEngine.create( coreCell ) + etesian.setViewer( self.viewer ) etesian.place() etesian.destroy() @@ -189,7 +190,7 @@ def ScriptMain ( **kw ): cell, editor = plugins.kwParseMain( **kw ) - conf = chip.Configuration.loadConfiguration( cell ) + conf = chip.Configuration.loadConfiguration( cell, editor ) if not conf.isValid(): return padsCorona = chip.PadsCorona.Corona( conf ) diff --git a/cumulus/src/plugins/chip/Configuration.py b/cumulus/src/plugins/chip/Configuration.py index b998435d..7fde3fad 100644 --- a/cumulus/src/plugins/chip/Configuration.py +++ b/cumulus/src/plugins/chip/Configuration.py @@ -449,12 +449,13 @@ class ChipConf ( object ): return - def __init__ ( self, chipConfigDict, cell ): + def __init__ ( self, chipConfigDict, cell, viewer=None ): if not isinstance(chipConfigDict,dict): raise ErrorMessage( 1, 'The "chip" variable is not a dictionnary.' ) self._validated = True self._cell = cell + self._viewer = viewer # Block Corona parameters. self._railsNb = getParameter('chip','chip.block.rails.count').asInt() self._hRailWidth = DbU.fromLambda( getParameter('chip','chip.block.rails.hWidth' ).asInt() ) @@ -506,6 +507,7 @@ class ChipConf ( object ): self.checkPads() self.computeChipSize() + self.checkChipSize() self.findPowerAndClockNets() return @@ -599,7 +601,7 @@ class ChipConf ( object ): print ErrorMessage( 1, 'There must be at least one pad of model "%s" to be used as reference.' \ % self._pckName ) self._validated = False - return False + return self._padHeight = self._clockPad.getMasterCell().getAbutmentBox().getHeight() self._padWidth = self._clockPad.getMasterCell().getAbutmentBox().getWidth() @@ -608,11 +610,29 @@ class ChipConf ( object ): horizontalPads = max( len(self._southPads), len(self._northPads) ) verticalPads = max( len(self._eastPads ), len(self._westPads ) ) - self._chipSize = Box( 0 - , 0 - , self._padWidth * horizontalPads + 2*self._padHeight - , self._padWidth * verticalPads + 2*self._padHeight - ) + self._chipSize = Box( 0 + , 0 + , self._padWidth * horizontalPads + 2*self._padHeight + , self._padWidth * verticalPads + 2*self._padHeight + ) + return + + + def checkChipSize ( self ): + #if self._coreSize.isEmpty(): return + # + #minWidth = self._coreSize.getWidth () + self._minCorona + 2*self._padHeight + #minHeight = self._coreSize.getHeight() + self._minCorona + 2*self._padHeight + # + #if self._chipSize.getWidth() < minWidth: + # print ErrorMessage( 1, 'Core is too wide to fit into the chip. Needs: %d, but has %d' \ + # % ( DbU.toLambda(minWidth), DbU.toLambda(self._chipSize.getWidth()) ) ) + # self._validated = False + # + #if self._chipSize.getHeight() < minHeight: + # print ErrorMessage( 1, 'Core is too wide to fit into the chip. Needs: %d, but has %d' \ + # % ( DbU.toLambda(minHeight), DbU.toLambda(self._chipSize.getHeight()) ) ) + # self._validated = False return def getSpecialNetRoot ( self, net ): @@ -645,7 +665,9 @@ class ChipConfWrapper ( GaugeConfWrapper ): def getSliceStep ( self ): return self._gaugeConf.getSliceStep() @property - def cell ( self ): return self._chipConf._cell + def cell ( self ): return self._chipConf._cell + @property + def viewer ( self ): return self._chipConf._viewer # Global Pad names. @property @@ -724,7 +746,7 @@ class ChipConfWrapper ( GaugeConfWrapper ): def useClockTree ( self ): return self._chipConf._useClockTree -def loadConfiguration ( cell ): +def loadConfiguration ( cell, viewer=None ): sys.path.append( os.getcwd() ) confFile = cell.getName()+'_chip' @@ -738,4 +760,4 @@ def loadConfiguration ( cell ): % confFile ) return ChipConfWrapper( GaugeConf() - , ChipConf ( confModule.__dict__['chip'], cell ) ) + , ChipConf ( confModule.__dict__['chip'], cell, viewer ) ) diff --git a/cumulus/src/plugins/chip/PadsCorona.py b/cumulus/src/plugins/chip/PadsCorona.py index cbf854ae..2f61b752 100644 --- a/cumulus/src/plugins/chip/PadsCorona.py +++ b/cumulus/src/plugins/chip/PadsCorona.py @@ -90,7 +90,7 @@ class Side ( object ): def check ( self ): - validated = True + self.validated = True if self._type == chip.North: self.validated = self._check( self._corona.coreSize.getWidth() + 2*self._corona.minCorona @@ -106,10 +106,10 @@ class Side ( object ): elif self._type == chip.South: checkName = 'south pads' elif self._type == chip.West: checkName = 'west pads' - validated = self._check( len(self._pads)*self._corona.padWidth - + 2*self._corona.padHeight - , checkName ) and validated - return validated + self.validated = self._check( len(self._pads) * self._corona.padWidth + + 2*self._corona.padHeight + , checkName ) and self.validated + return self.validated def _createPowerContacts ( self, pad, net ): diff --git a/etesian/src/AddFeeds.cpp b/etesian/src/AddFeeds.cpp index 56b1223b..d177e55d 100644 --- a/etesian/src/AddFeeds.cpp +++ b/etesian/src/AddFeeds.cpp @@ -24,6 +24,7 @@ #include "hurricane/Plug.h" #include "hurricane/Path.h" #include "hurricane/viewer/CellWidget.h" +#include "hurricane/viewer/CellViewer.h" #include "crlcore/AllianceFramework.h" #include "crlcore/ToolBox.h" #include "etesian/EtesianEngine.h" @@ -400,7 +401,7 @@ namespace Etesian { UpdateSession::close(); - if (_cellWidget) _cellWidget->refresh(); + if (_viewer) _viewer->getCellWidget()->refresh(); } diff --git a/etesian/src/EtesianEngine.cpp b/etesian/src/EtesianEngine.cpp index 78ce3fdc..b754d36d 100644 --- a/etesian/src/EtesianEngine.cpp +++ b/etesian/src/EtesianEngine.cpp @@ -39,6 +39,7 @@ #include "hurricane/RoutingPad.h" #include "hurricane/UpdateSession.h" #include "hurricane/viewer/CellWidget.h" +#include "hurricane/viewer/CellViewer.h" #include "katabatic/GCellGrid.h" #include "katabatic/KatabaticEngine.h" #include "kite/KiteEngine.h" @@ -257,7 +258,7 @@ namespace Etesian { , _placementUB () , _cellsToIds () , _idsToInsts () - , _cellWidget (NULL) + , _viewer (NULL) , _feedCells (this) { } @@ -391,7 +392,7 @@ namespace Etesian { , rows *getSliceHeight() ) ); UpdateSession::close(); - if (_cellWidget) _cellWidget->fitToContents(); + if (_viewer) _viewer->getCellWidget()->fitToContents(); } @@ -433,7 +434,7 @@ namespace Etesian { dots.finish( Dots::Reset ); - if (_cellWidget) _cellWidget->refresh(); + if (_viewer) _viewer->getCellWidget()->refresh(); _placed = false; } @@ -996,7 +997,7 @@ namespace Etesian { UpdateSession::close(); - if (_cellWidget) _cellWidget->refresh(); + if (_viewer) _viewer->getCellWidget()->refresh(); } diff --git a/etesian/src/GraphicEtesianEngine.cpp b/etesian/src/GraphicEtesianEngine.cpp index f2131af2..b52a7066 100644 --- a/etesian/src/GraphicEtesianEngine.cpp +++ b/etesian/src/GraphicEtesianEngine.cpp @@ -67,7 +67,7 @@ namespace Etesian { EtesianEngine* etesian = EtesianEngine::get( cell ); if (not etesian) { etesian = EtesianEngine::create( cell ); - etesian->setCellWidget( _viewer->getCellWidget() ); + etesian->setViewer( _viewer ); } else cerr << Warning( "%s already has a Etesian engine.", getString(cell).c_str() ) << endl; diff --git a/etesian/src/PyEtesianEngine.cpp b/etesian/src/PyEtesianEngine.cpp index 8ab8ec41..2dcc9b09 100644 --- a/etesian/src/PyEtesianEngine.cpp +++ b/etesian/src/PyEtesianEngine.cpp @@ -1,4 +1,3 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. @@ -16,7 +15,9 @@ #include "hurricane/isobar/PyCell.h" +#include "hurricane/viewer/PyCellViewer.h" #include "hurricane/Cell.h" +#include "hurricane/viewer/ExceptionWidget.h" #include "etesian/PyEtesianEngine.h" # undef ACCESS_OBJECT @@ -37,6 +38,7 @@ namespace Etesian { using Hurricane::in_trace; using Hurricane::Error; using Hurricane::Warning; + using Hurricane::ExceptionWidget; using Isobar::ProxyProperty; using Isobar::ProxyError; using Isobar::ConstructorError; @@ -46,6 +48,7 @@ namespace Etesian { using Isobar::ParseTwoArg; using Isobar::PyCell; using Isobar::PyCell_Link; + using Isobar::PyCellViewer; using CRL::PyToolEngine; @@ -101,14 +104,44 @@ extern "C" { return PyEtesianEngine_Link(etesian); } - // Standart Accessors (Attributes). - DirectVoidMethod(EtesianEngine,etesian,place) + static PyObject* PyEtesianEngine_setViewer ( PyEtesianEngine* self, PyObject* args ) + { + trace << "PyEtesianEngine_setViewer ()" << endl; + + HTRY + METHOD_HEAD( "EtesianEngine.setViewer()" ) + + PyCellViewer* pyViewer; + if (not ParseOneArg("EtesianEngine.setViewer()",args,":cellView",(PyObject**)&pyViewer)) { + return NULL; + } + etesian->setViewer( PYCELLVIEWER_O(pyViewer) ); + HCATCH + + Py_RETURN_NONE; + } + + + static PyObject* PyEtesianEngine_place ( PyEtesianEngine* self ) + { + trace << "PyEtesianEngine_place()" << endl; + HTRY + METHOD_HEAD("EtesianEngine.place()") + if (etesian->getViewer()) { + if (ExceptionWidget::catchAllWrapper( std::bind(&EtesianEngine::place,etesian) )) { + PyErr_SetString( HurricaneError, "EtesianEngine::place() has thrown an exception (C++)." ); + return NULL; + } + } else { + etesian->place(); + } + HCATCH + Py_RETURN_NONE; + } + + // Standart Accessors (Attributes). // DirectVoidMethod(EtesianEngine,etesian,runNegociate) - // DirectVoidMethod(EtesianEngine,etesian,printConfiguration) - // DirectVoidMethod(EtesianEngine,etesian,saveGlobalSolution) - // DirectVoidMethod(EtesianEngine,etesian,finalizeLayout) - // DirectVoidMethod(EtesianEngine,etesian,dumpMeasures) // DirectGetBoolAttribute(PyEtesianEngine_getToolSuccess,getToolSuccess,PyEtesianEngine,EtesianEngine) // Standart Destroy (Attribute). @@ -120,6 +153,8 @@ extern "C" { , "Returns the Etesian engine attached to the Cell, None if there isn't." } , { "create" , (PyCFunction)PyEtesianEngine_create , METH_VARARGS|METH_STATIC , "Create an Etesian engine on this cell." } + , { "setViewer" , (PyCFunction)PyEtesianEngine_setViewer , METH_VARARGS + , "Associate a Viewer to this EtesianEngine." } , { "place" , (PyCFunction)PyEtesianEngine_place , METH_NOARGS , "Run the placer (Etesian)." } , { "destroy" , (PyCFunction)PyEtesianEngine_destroy , METH_NOARGS diff --git a/etesian/src/etesian/EtesianEngine.h b/etesian/src/etesian/EtesianEngine.h index a277c570..2a09b1b4 100644 --- a/etesian/src/etesian/EtesianEngine.h +++ b/etesian/src/etesian/EtesianEngine.h @@ -28,6 +28,7 @@ namespace Hurricane { class Net; class Cell; class CellWidget; + class CellViewer; class Instance; } @@ -52,47 +53,48 @@ namespace Etesian { class EtesianEngine : public CRL::ToolEngine { public: - static const Name& staticGetName (); - static EtesianEngine* create ( Cell* ); - static EtesianEngine* get ( const Cell* ); - public: - virtual Configuration* getConfiguration (); - virtual const Configuration* getConfiguration () const; - virtual const Name& getName () const; - inline CellGauge* getCellGauge () const; - inline DbU::Unit getPitch () const; - inline DbU::Unit getSliceHeight () const; - inline Effort getPlaceEffort () const; - inline GraphicUpdate getUpdateConf () const; - inline Density getSpreadingConf () const; - inline bool getRoutingDriven () const; - inline double getSpaceMargin () const; - inline double getAspectRatio () const; - inline const FeedCells& getFeedCells () const; - inline void setCellWidget ( Hurricane::CellWidget* ); - - void startMeasures (); - void stopMeasures (); - void printMeasures ( std::string ) const; - - void setDefaultAb (); - void resetPlacement (); - void toColoquinte (); - - void preplace (); - void roughLegalize ( float minDisruption, unsigned options ); - void globalPlace ( float initPenalty, float minDisruption, float targetImprovement, float minInc, float maxInc, unsigned options=0 ); - void detailedPlace ( int iterations, int effort, unsigned options=0 ); - void feedRoutingBack (); - - void place (); - - inline void useFeed ( Cell* ); - size_t findYSpin (); - void addFeeds (); - virtual Record* _getRecord () const; - virtual std::string _getString () const; - virtual std::string _getTypeName () const; + static const Name& staticGetName (); + static EtesianEngine* create ( Cell* ); + static EtesianEngine* get ( const Cell* ); + public: + virtual Configuration* getConfiguration (); + virtual const Configuration* getConfiguration () const; + virtual const Name& getName () const; + inline CellGauge* getCellGauge () const; + inline DbU::Unit getPitch () const; + inline DbU::Unit getSliceHeight () const; + inline Effort getPlaceEffort () const; + inline GraphicUpdate getUpdateConf () const; + inline Density getSpreadingConf () const; + inline bool getRoutingDriven () const; + inline double getSpaceMargin () const; + inline double getAspectRatio () const; + inline const FeedCells& getFeedCells () const; + inline Hurricane::CellViewer* getViewer () const; + inline void setViewer ( Hurricane::CellViewer* ); + + void startMeasures (); + void stopMeasures (); + void printMeasures ( std::string ) const; + + void setDefaultAb (); + void resetPlacement (); + void toColoquinte (); + + void preplace (); + void roughLegalize ( float minDisruption, unsigned options ); + void globalPlace ( float initPenalty, float minDisruption, float targetImprovement, float minInc, float maxInc, unsigned options=0 ); + void detailedPlace ( int iterations, int effort, unsigned options=0 ); + void feedRoutingBack (); + + void place (); + + inline void useFeed ( Cell* ); + size_t findYSpin (); + void addFeeds (); + virtual Record* _getRecord () const; + virtual std::string _getString () const; + virtual std::string _getTypeName () const; private: // Attributes. @@ -110,7 +112,7 @@ namespace Etesian { coloquinte::density_restrictions _densityLimits; std::unordered_map _cellsToIds; std::vector _idsToInsts; - Hurricane::CellWidget* _cellWidget; + Hurricane::CellViewer* _viewer; FeedCells _feedCells; size_t _yspinSlice0; @@ -131,18 +133,19 @@ namespace Etesian { // Inline Functions. - inline void EtesianEngine::setCellWidget ( Hurricane::CellWidget* cw ) { _cellWidget = cw; } - inline CellGauge* EtesianEngine::getCellGauge () const { return getConfiguration()->getCellGauge(); } - inline DbU::Unit EtesianEngine::getPitch () const { return getCellGauge()->getPitch(); } - inline DbU::Unit EtesianEngine::getSliceHeight () const { return getCellGauge()->getSliceHeight(); } - inline Effort EtesianEngine::getPlaceEffort () const { return getConfiguration()->getPlaceEffort(); } - inline GraphicUpdate EtesianEngine::getUpdateConf () const { return getConfiguration()->getUpdateConf(); } - inline Density EtesianEngine::getSpreadingConf () const { return getConfiguration()->getSpreadingConf(); } - inline bool EtesianEngine::getRoutingDriven () const { return getConfiguration()->getRoutingDriven(); } - inline double EtesianEngine::getSpaceMargin () const { return getConfiguration()->getSpaceMargin(); } - inline double EtesianEngine::getAspectRatio () const { return getConfiguration()->getAspectRatio(); } - inline void EtesianEngine::useFeed ( Cell* cell ) { _feedCells.useFeed(cell); } - inline const FeedCells& EtesianEngine::getFeedCells () const { return _feedCells; } + inline void EtesianEngine::setViewer ( Hurricane::CellViewer* viewer ) { _viewer = viewer; } + inline Hurricane::CellViewer* EtesianEngine::getViewer () const { return _viewer; } + inline CellGauge* EtesianEngine::getCellGauge () const { return getConfiguration()->getCellGauge(); } + inline DbU::Unit EtesianEngine::getPitch () const { return getCellGauge()->getPitch(); } + inline DbU::Unit EtesianEngine::getSliceHeight () const { return getCellGauge()->getSliceHeight(); } + inline Effort EtesianEngine::getPlaceEffort () const { return getConfiguration()->getPlaceEffort(); } + inline GraphicUpdate EtesianEngine::getUpdateConf () const { return getConfiguration()->getUpdateConf(); } + inline Density EtesianEngine::getSpreadingConf () const { return getConfiguration()->getSpreadingConf(); } + inline bool EtesianEngine::getRoutingDriven () const { return getConfiguration()->getRoutingDriven(); } + inline double EtesianEngine::getSpaceMargin () const { return getConfiguration()->getSpaceMargin(); } + inline double EtesianEngine::getAspectRatio () const { return getConfiguration()->getAspectRatio(); } + inline void EtesianEngine::useFeed ( Cell* cell ) { _feedCells.useFeed(cell); } + inline const FeedCells& EtesianEngine::getFeedCells () const { return _feedCells; } // Variables. diff --git a/hurricane/src/hurricane/DbU.cpp b/hurricane/src/hurricane/DbU.cpp index 6648f26d..1f4253a5 100644 --- a/hurricane/src/hurricane/DbU.cpp +++ b/hurricane/src/hurricane/DbU.cpp @@ -18,8 +18,6 @@ // License along with Hurricane. If not, see // . // -// =================================================================== -// // +-----------------------------------------------------------------+ // | H U R R I C A N E | // | V L S I B a c k e n d D a t a - B a s e | @@ -49,10 +47,13 @@ namespace Hurricane { double DbU::_resolution = 0.1; double DbU::_gridsPerLambda = 10.0; double DbU::_physicalsPerGrid = 1.0; + double DbU::_gridMax = DbU::toGrid ( DbU::Max ); + double DbU::_lambdaMax = DbU::toLambda ( DbU::Max ); + double DbU::_physicalMax = DbU::toPhysical( DbU::Max, DbU::Unity ); unsigned int DbU::_stringMode = DbU::Symbolic; DbU::UnitPower DbU::_stringModeUnitPower = DbU::Nano; - DbU::Unit DbU::_symbolicSnapGridStep = DbU::lambda(1.0); - DbU::Unit DbU::_realSnapGridStep = DbU::grid (10.0); + DbU::Unit DbU::_symbolicSnapGridStep = DbU::fromLambda( 1.0); + DbU::Unit DbU::_realSnapGridStep = DbU::fromGrid (10.0); const DbU::Unit DbU::Min = std::numeric_limits::min(); const DbU::Unit DbU::Max = std::numeric_limits::max(); @@ -95,6 +96,42 @@ namespace Hurricane { // Class : "Hurricane::DbU". + void DbU::_updateBounds () + { + _gridMax = toGrid ( Max ); + _lambdaMax = toLambda ( Max ); + _physicalMax = toPhysical( Max, Unity ); + } + + + void DbU::checkGridBound ( double value ) + { + if (value < 0) value = -value; + if (value >= _gridMax) + throw Error( "Grid value %.1f converts to out of range DbU value (maximum is: %.1f)." + , value, _gridMax ); + } + + + void DbU::checkLambdaBound ( double value ) + { + if (value < 0) value = -value; + if (value >= _lambdaMax) + throw Error( "Lambda value %.1f converts to out of range DbU (maximum is: %.1f)." + , value, _lambdaMax ); + } + + + void DbU::checkPhysicalBound ( double value, UnitPower p ) + { + if (value < 0) value = -value; + value *= getUnitPower(p); + if (value >= _physicalMax) + throw Error( "Physical value %.1fnm converts to out of range DbU (maximum is: %.1f)." + , (value/1.0e-9), _physicalMax ); + } + + unsigned int DbU::getPrecision () { return _precision; } @@ -126,6 +163,8 @@ namespace Hurricane { setSymbolicSnapGridStep ( DbU::lambda( 1.0) ); setRealSnapGridStep ( DbU::grid (10.0) ); + + _updateBounds(); } @@ -144,7 +183,10 @@ namespace Hurricane { void DbU::setPhysicalsPerGrid ( double physicalsPerGrid, UnitPower p ) - { _physicalsPerGrid = physicalsPerGrid * getUnitPower(p); } + { + _physicalsPerGrid = physicalsPerGrid * getUnitPower(p); + _updateBounds(); + } double DbU::getPhysicalsPerGrid () @@ -170,6 +212,8 @@ namespace Hurricane { DataBase::getDB()->getTechnology()->_onDbuChange ( scale ); setSymbolicSnapGridStep ( DbU::lambda(1) ); + + _updateBounds(); } diff --git a/hurricane/src/hurricane/hurricane/DbU.h b/hurricane/src/hurricane/hurricane/DbU.h index fe047d04..11b03828 100644 --- a/hurricane/src/hurricane/hurricane/DbU.h +++ b/hurricane/src/hurricane/hurricane/DbU.h @@ -18,8 +18,6 @@ // License along with Hurricane. If not, see // . // -// =================================================================== -// // +-----------------------------------------------------------------+ // | H U R R I C A N E | // | V L S I B a c k e n d D a t a - B a s e | @@ -66,6 +64,9 @@ namespace Hurricane { }; public: + static void checkGridBound ( double value ); + static void checkLambdaBound ( double value ); + static void checkPhysicalBound ( double value, UnitPower p ); // User to DB Converters. static inline Unit fromDb ( long value ); static inline Unit fromGrid ( double value ); @@ -120,6 +121,8 @@ namespace Hurricane { static Slot* getValueSlot ( const string& name, const Unit* u ); static void setStringMode ( unsigned int mode, UnitPower p=Nano ); static void getStringMode ( unsigned int& mode, UnitPower& p ); + private: + static void _updateBounds (); public: // Static Attributes: constants. @@ -136,15 +139,18 @@ namespace Hurricane { static DbU::UnitPower _stringModeUnitPower; static DbU::Unit _realSnapGridStep; static DbU::Unit _symbolicSnapGridStep; + static double _gridMax; + static double _lambdaMax; + static double _physicalMax; }; // Inline Functions. // New converter naming scheme. inline DbU::Unit DbU::fromDb ( long value ) { return value; } - inline DbU::Unit DbU::fromGrid ( double value ) { return (long)rint( value/_resolution ); } - inline DbU::Unit DbU::fromLambda ( double value ) { return fromGrid(value*_gridsPerLambda); } - inline DbU::Unit DbU::fromPhysical ( double value, UnitPower p ) { return fromGrid((value*getUnitPower(p))/_physicalsPerGrid); } + inline DbU::Unit DbU::fromGrid ( double value ) { checkGridBound (value); return (long)rint( value/_resolution ); } + inline DbU::Unit DbU::fromLambda ( double value ) { checkLambdaBound (value); return fromGrid(value*_gridsPerLambda); } + inline DbU::Unit DbU::fromPhysical ( double value, UnitPower p ) { checkPhysicalBound(value,p); return fromGrid((value*getUnitPower(p))/_physicalsPerGrid); } inline long DbU::toDb ( DbU::Unit u ) { return u; } inline double DbU::toGrid ( DbU::Unit u ) { return _resolution*(double)u; } inline double DbU::toGrid ( double u ) { return _resolution*u; } diff --git a/hurricane/src/isobar/hurricane/isobar/PyHurricane.h b/hurricane/src/isobar/hurricane/isobar/PyHurricane.h index 7a67fa66..abac6419 100644 --- a/hurricane/src/isobar/hurricane/isobar/PyHurricane.h +++ b/hurricane/src/isobar/hurricane/isobar/PyHurricane.h @@ -22,6 +22,7 @@ // #define DEBUG 1 #include "Python.h" +#include #include #include #include @@ -1398,15 +1399,27 @@ extern "C" { # define HCATCH \ } \ - catch ( Error& e ) { \ - std::string message = "\n" + getString(e); \ - PyErr_SetString ( HurricaneError, message.c_str() ); \ - return ( NULL ); \ - } \ catch ( Warning& w ) { \ std::string message = "\n" + getString(w); \ PyErr_Warn ( HurricaneWarning, const_cast(message.c_str()) ); \ - } + } \ + catch ( Error& e ) { \ + std::string message = "\n" + getString(e); \ + PyErr_SetString ( HurricaneError, message.c_str() ); \ + return NULL; \ + } \ + catch ( std::exception& e ) { \ + std::string message = "\n" + std::string(e.what()); \ + PyErr_SetString ( HurricaneError, message.c_str() ); \ + return NULL; \ + } \ + catch ( ... ) { \ + std::string message = \ + "\nUnmanaged exception, neither a Hurricane::Error nor" \ + "std::exception."; \ + PyErr_SetString ( HurricaneError, message.c_str() ); \ + return NULL; \ + } \ } // End of extern "C". diff --git a/hurricane/src/viewer/ExceptionWidget.cpp b/hurricane/src/viewer/ExceptionWidget.cpp index 280c560a..f01a1164 100644 --- a/hurricane/src/viewer/ExceptionWidget.cpp +++ b/hurricane/src/viewer/ExceptionWidget.cpp @@ -64,10 +64,12 @@ namespace Hurricane { } - void ExceptionWidget::catchAllWrapper ( std::function< void() > method ) + bool ExceptionWidget::catchAllWrapper ( std::function< void() > method ) { + bool failure = true; try { method(); + failure = false; } catch ( Error& e ) { ExceptionWidget::run( e ); @@ -85,6 +87,7 @@ namespace Hurricane { ExceptionWidget::run( message ); } + return failure; } diff --git a/hurricane/src/viewer/PyViewer.cpp b/hurricane/src/viewer/PyViewer.cpp index 3f5ddb93..c3b62e7d 100644 --- a/hurricane/src/viewer/PyViewer.cpp +++ b/hurricane/src/viewer/PyViewer.cpp @@ -93,7 +93,7 @@ extern "C" { __cs.addType ( "hsvr" , &PyTypeHSVr , "" , false ); __cs.addType ( "displaySty", &PyTypeDisplayStyle, "", false ); __cs.addType ( "graphics" , &PyTypeGraphics , "" , false ); - __cs.addType ( "cellView" , &PyTypeCellViewer , "" , false, "view" ); + __cs.addType ( "cellView" , &PyTypeCellViewer , "" , false ); PyObject* module = Py_InitModule ( "Viewer", PyViewer_Methods ); if ( module == NULL ) { diff --git a/hurricane/src/viewer/hurricane/viewer/ExceptionWidget.h b/hurricane/src/viewer/hurricane/viewer/ExceptionWidget.h index 254f36da..f18aac6d 100644 --- a/hurricane/src/viewer/hurricane/viewer/ExceptionWidget.h +++ b/hurricane/src/viewer/hurricane/viewer/ExceptionWidget.h @@ -37,7 +37,7 @@ namespace Hurricane { static void run ( Exception& ); static void run ( std::exception& ); static void run ( const QString&, const QString& where="" ); - static void catchAllWrapper ( std::function< void() > method ); + static bool catchAllWrapper ( std::function< void() > method ); public: ExceptionWidget ( QWidget* parent=NULL); void setMessage ( const QString& ); diff --git a/hurricane/src/viewer/hurricane/viewer/PyCellViewer.h b/hurricane/src/viewer/hurricane/viewer/PyCellViewer.h index 4304ad0e..e70fdd5c 100644 --- a/hurricane/src/viewer/hurricane/viewer/PyCellViewer.h +++ b/hurricane/src/viewer/hurricane/viewer/PyCellViewer.h @@ -49,7 +49,7 @@ extern "C" { #define IsPyCellViewer(v) ( (v)->ob_type == &PyTypeCellViewer ) #define PYCELLVIEWER(v) ( (PyCellViewer*)(v) ) -#define PYCELLVIEWER_O(v) ( ISOBAR_CELL_VIEWER(v)->_object ) +#define PYCELLVIEWER_O(v) ( PYCELLVIEWER(v)->_object ) } // End of extern "C". diff --git a/kite/src/PyKiteEngine.cpp b/kite/src/PyKiteEngine.cpp index caa3b873..443f8377 100644 --- a/kite/src/PyKiteEngine.cpp +++ b/kite/src/PyKiteEngine.cpp @@ -15,7 +15,7 @@ #include "hurricane/isobar/PyCell.h" -#include "hurricane/viewer/CellViewer.h" +#include "hurricane/viewer/PyCellViewer.h" #include "hurricane/viewer/ExceptionWidget.h" #include "hurricane/Cell.h" #include "kite/PyKiteEngine.h" @@ -48,6 +48,7 @@ namespace Kite { using Isobar::ParseTwoArg; using Isobar::PyCell; using Isobar::PyCell_Link; + using Isobar::PyCellViewer; using CRL::PyToolEngine; @@ -61,12 +62,15 @@ extern "C" { { \ trace << "Py" #SELF_TYPE "_" #FUNC_NAME "()" << endl; \ HTRY \ - METHOD_HEAD(#SELF_TYPE "." #FUNC_NAME "()") \ - if (SELF_OBJECT->getViewer()) { \ - ExceptionWidget::catchAllWrapper( std::bind(&KiteEngine::FUNC_NAME,SELF_OBJECT) ); \ - } else { \ - SELF_OBJECT->FUNC_NAME(); \ - } \ + METHOD_HEAD(#SELF_TYPE "." #FUNC_NAME "()") \ + if (SELF_OBJECT->getViewer()) { \ + if (ExceptionWidget::catchAllWrapper( std::bind(&KiteEngine::FUNC_NAME,SELF_OBJECT) )) { \ + PyErr_SetString( HurricaneError, #FUNC_NAME "() has thrown an exception (C++)." ); \ + return NULL; \ + } \ + } else { \ + SELF_OBJECT->FUNC_NAME(); \ + } \ HCATCH \ Py_RETURN_NONE; \ } @@ -120,23 +124,44 @@ extern "C" { } + static PyObject* PyKiteEngine_setViewer ( PyKiteEngine* self, PyObject* args ) + { + trace << "PyKiteEngine_setViewer ()" << endl; + + HTRY + METHOD_HEAD( "KiteEngine.setViewer()" ) + + PyCellViewer* pyViewer; + if (not ParseOneArg("KiteEngine.setViewer()",args,":cellView",(PyObject**)&pyViewer)) { + return NULL; + } + kite->setViewer( PYCELLVIEWER_O(pyViewer) ); + HCATCH + + Py_RETURN_NONE; + } + + PyObject* PyKiteEngine_runGlobalRouter ( PyKiteEngine* self, PyObject* args ) { trace << "PyKiteEngine_runGlobalRouter()" << endl; HTRY - METHOD_HEAD("KiteEngine.runGlobalRouter()") - unsigned int flags = 0; - if (PyArg_ParseTuple(args,"I:KiteEngine.runGlobalRouter", &flags)) { - if (kite->getViewer()) { - ExceptionWidget::catchAllWrapper( std::bind(&KiteEngine::runGlobalRouter,kite,flags) ); + METHOD_HEAD("KiteEngine.runGlobalRouter()") + unsigned int flags = 0; + if (PyArg_ParseTuple(args,"I:KiteEngine.runGlobalRouter", &flags)) { + if (kite->getViewer()) { + if (ExceptionWidget::catchAllWrapper( std::bind(&KiteEngine::runGlobalRouter,kite,flags) )) { + PyErr_SetString( HurricaneError, "KiteEngine::runGlobalrouter() has thrown an exception (C++)." ); + return NULL; + } + } else { + kite->runGlobalRouter(flags); + } } else { - kite->runGlobalRouter(flags); + PyErr_SetString(ConstructorError, "KiteEngine.runGlobalRouter(): Invalid number/bad type of parameter."); + return NULL; } - } else { - PyErr_SetString(ConstructorError, "KiteEngine.runGlobalRouter(): Invalid number/bad type of parameter."); - return NULL; - } HCATCH Py_RETURN_NONE; @@ -177,7 +202,10 @@ extern "C" { } if (kite->getViewer()) { - ExceptionWidget::catchAllWrapper( std::bind(&KiteEngine::loadGlobalRouting,kite,flags/*,*routingNets*/) ); + if (ExceptionWidget::catchAllWrapper( std::bind(&KiteEngine::loadGlobalRouting,kite,flags/*,*routingNets*/) )) { + PyErr_SetString( HurricaneError, "KiteEngine::loadGlobalrouting() has thrown an exception (C++)." ); + return NULL; + } } else { kite->loadGlobalRouting(flags/*,*routingNets*/); } @@ -201,8 +229,14 @@ extern "C" { if (PyArg_ParseTuple(args,"I:KiteEngine.layerAssign", &flags)) { if (kite->getViewer()) { - ExceptionWidget::catchAllWrapper( std::bind(&KiteEngine::balanceGlobalDensity,kite) ); - ExceptionWidget::catchAllWrapper( std::bind(&KiteEngine::layerAssign ,kite,flags) ); + bool failure = ExceptionWidget::catchAllWrapper( std::bind(&KiteEngine::balanceGlobalDensity,kite) ); + if (not failure) + failure = ExceptionWidget::catchAllWrapper( std::bind(&KiteEngine::layerAssign,kite,flags) ); + + if (failure) { + PyErr_SetString( HurricaneError, "EtesianEngine::place() has thrown an exception (C++)." ); + return NULL; + } } else { kite->balanceGlobalDensity(); kite->layerAssign (flags); @@ -223,7 +257,10 @@ extern "C" { HTRY METHOD_HEAD("KiteEngine.runNegociatePreRouted()") if (kite->getViewer()) { - ExceptionWidget::catchAllWrapper( std::bind(&KiteEngine::runNegociate,kite,Kite::KtPreRoutedStage) ); + if (ExceptionWidget::catchAllWrapper( std::bind(&KiteEngine::runNegociate,kite,Kite::KtPreRoutedStage) )) { + PyErr_SetString( HurricaneError, "EtesianEngine::runNegiciatePreRouted() has thrown an exception (C++)." ); + return NULL; + } } else { kite->runNegociate( Kite::KtPreRoutedStage ); } @@ -238,7 +275,10 @@ extern "C" { HTRY METHOD_HEAD("KiteEngine.runNegociate()") if (kite->getViewer()) { - ExceptionWidget::catchAllWrapper( std::bind(&KiteEngine::runNegociate,kite,0) ); + if (ExceptionWidget::catchAllWrapper( std::bind(&KiteEngine::runNegociate,kite,0) )) { + PyErr_SetString( HurricaneError, "EtesianEngine::runNegociate() has thrown an exception (C++)." ); + return NULL; + } } else { kite->runNegociate(); } @@ -263,6 +303,8 @@ extern "C" { , "Returns the Kite engine attached to the Cell, None if there isnt't." } , { "create" , (PyCFunction)PyKiteEngine_create , METH_VARARGS|METH_STATIC , "Create a Kite engine on this cell." } + , { "setViewer" , (PyCFunction)PyKiteEngine_setViewer , METH_VARARGS + , "Associate a Viewer to this KiteEngine." } , { "printConfiguration" , (PyCFunction)PyKiteEngine_printConfiguration , METH_NOARGS , "Display on the console the configuration of Kite." } , { "saveGlobalSolution" , (PyCFunction)PyKiteEngine_saveGlobalSolution , METH_NOARGS