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 <true> 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.
This commit is contained in:
Jean-Paul Chaput 2015-05-20 14:02:18 +02:00
parent 909f86b4fc
commit f8a72288aa
25 changed files with 402 additions and 820 deletions

38
.dir-locals.el Normal file
View File

@ -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"
)))))

4
.gitignore vendored
View File

@ -5,6 +5,10 @@
*.bak
TAGS
GTAGS
GPATH
GRTAGS
man/
rtf/

6
.projectile Normal file
View File

@ -0,0 +1,6 @@
-*.fig
-*.png
-*.eps
-*.pdf
-*.aux
-*.bb

View File

@ -33,6 +33,9 @@
#include "crlcore/AllianceFramework.h"
namespace CRL {

View File

@ -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";

View File

@ -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";
}
}
}
}

View File

@ -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<string,Net*> _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<string,Net*>::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<string*> StringPtVector;
typedef vector<string> StringVector;
typedef map<const string*, Net*> StringNetMap;
typedef map<const string*, Plug*> StringPlugMap;
typedef set<Net*> NetSet;
typedef vector<Plug*> 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<Cell*> ModelSet;
ModelSet modelSet;
typedef list<Instance*> InstanceList;
InstanceList instanceList;
for_each_instance(instance, cell->getInstances())
{
Cell* model = instance->getMasterCell();
CatalogProperty *stateProp =
static_cast<CatalogProperty*>(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.

View File

@ -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()

View File

@ -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; }

View File

@ -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 )

View File

@ -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 ) )

View File

@ -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 ):

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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;

View File

@ -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

View File

@ -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<string,unsigned int> _cellsToIds;
std::vector<Instance*> _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.

View File

@ -18,8 +18,6 @@
// License along with Hurricane. If not, see
// <http://www.gnu.org/licenses/>.
//
// ===================================================================
//
// +-----------------------------------------------------------------+
// | 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<long>::min();
const DbU::Unit DbU::Max = std::numeric_limits<long>::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();
}

View File

@ -18,8 +18,6 @@
// License along with Hurricane. If not, see
// <http://www.gnu.org/licenses/>.
//
// ===================================================================
//
// +-----------------------------------------------------------------+
// | 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; }

View File

@ -22,6 +22,7 @@
// #define DEBUG 1
#include "Python.h"
#include <exception>
#include <iostream>
#include <sstream>
#include <string>
@ -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<char*>(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".

View File

@ -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;
}

View File

@ -93,7 +93,7 @@ extern "C" {
__cs.addType ( "hsvr" , &PyTypeHSVr , "<HSVr>" , false );
__cs.addType ( "displaySty", &PyTypeDisplayStyle, "<DisplayStyle>", false );
__cs.addType ( "graphics" , &PyTypeGraphics , "<Graphics>" , false );
__cs.addType ( "cellView" , &PyTypeCellViewer , "<CellViewer>" , false, "view" );
__cs.addType ( "cellView" , &PyTypeCellViewer , "<CellViewer>" , false );
PyObject* module = Py_InitModule ( "Viewer", PyViewer_Methods );
if ( module == NULL ) {

View File

@ -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& );

View File

@ -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".

View File

@ -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