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 *.bak
TAGS TAGS
GTAGS
GPATH
GRTAGS
man/ man/
rtf/ 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" #include "crlcore/AllianceFramework.h"
namespace CRL { namespace CRL {

View File

@ -273,7 +273,7 @@ namespace Vhdl {
for ( auto isignal=internalSignals.begin(); isignal!=internalSignals.end() ; ++isignal ) { for ( auto isignal=internalSignals.begin(); isignal!=internalSignals.end() ; ++isignal ) {
out << tab; out << tab;
(*isignal)->toVhdlPort( out, width, Entity::AsInnerSignal ); (*isignal)->toVhdlPort( out, width, Entity::AsInnerSignal|(_flags & Entity::IeeeMode) );
out << ";\n"; out << ";\n";
} }
out << "\n"; out << "\n";
@ -297,7 +297,7 @@ namespace Vhdl {
size_t ioCount = 0; size_t ioCount = 0;
for ( auto isignal=ioSignals.begin(); isignal!=ioSignals.end() ; ++isignal ) { for ( auto isignal=ioSignals.begin(); isignal!=ioSignals.end() ; ++isignal ) {
if (ioCount) out << "\n" << tab << " ; "; if (ioCount) out << "\n" << tab << " ; ";
(*isignal)->toVhdlPort( out, width, Entity::AsPortSignal ); (*isignal)->toVhdlPort( out, width, Entity::AsPortSignal|(_flags & Entity::IeeeMode ) );
++ioCount; ++ioCount;
} }
out << "\n" << tab << " );"; out << "\n" << tab << " );";
@ -317,10 +317,21 @@ namespace Vhdl {
out << "-- Coriolis Structural VHDL Driver\n"; out << "-- Coriolis Structural VHDL Driver\n";
out << "-- Generated on " << stamp << "\n"; out << "-- Generated on " << stamp << "\n";
out << "-- \n"; out << "-- \n";
out << "-- To be interoperable with Alliance, it uses it's special VHDL subset.\n"; if (isIeeeMode()) {
out << "-- (\"man vhdl\" under Alliance for more informations)\n"; 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";
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"; out << tab++ << "entity " << getCell()->getName() << " is\n";
toPort( out ); toPort( out );
out << --tab << "\nend " << getCell()->getName() << ";\n\n"; out << --tab << "\nend " << getCell()->getName() << ";\n\n";

View File

@ -59,18 +59,26 @@ namespace Vhdl {
} }
if (not range.empty()) { if (not range.empty()) {
switch ( (unsigned int)direction & (Net::Direction::ConnTristate if (flags & Entity::IeeeMode) {
|Net::Direction::ConnWiredOr) ) { out << " std_logic_vector" << range;
case Net::Direction::ConnTristate: out << " mux_vector" << range << " bus"; break; } else {
case Net::Direction::ConnWiredOr: out << " wor_vector" << range << " bus"; break; switch ( (unsigned int)direction & (Net::Direction::ConnTristate
default: out << " bit_vector" << range; |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 { } else {
switch ( (unsigned int)direction & (Net::Direction::ConnTristate if (flags & Entity::IeeeMode) {
|Net::Direction::ConnWiredOr) ) { out << " std_logic";
case Net::Direction::ConnTristate: out << " mux_bit bus"; break; } else {
case Net::Direction::ConnWiredOr: out << " wor_bit bus"; break; switch ( (unsigned int)direction & (Net::Direction::ConnTristate
default: out << " bit"; |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" #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 { namespace CRL {
void vstDriver ( const string cellPath, Cell *cell, unsigned int &saveState ) using namespace std;
{
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();
#if 0
__globalNets.clear ();
::std::ofstream ccell ( cellPath.c_str() ); void vstDriver ( const string cellPath, Cell *cell, unsigned int &saveState )
ccell << "entity " << cell->getName() << " is" << endl; {
DumpPortList(ccell, cell); NamingScheme::toVhdl( cell, NamingScheme::FromVerilog );
ccell << "end " << cell->getName() << ";" << endl; Vhdl::Entity* vhdlEntity = Vhdl::EntityExtension::create( cell, Vhdl::Entity::EntityMode|Vhdl::Entity::IeeeMode );
ccell << endl; string celltest = cellPath;
ccell << "architecture structural of " << cell->getName() << " is" << endl; ofstream ccelltest ( celltest.c_str() );
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())) vhdlEntity->toEntity( ccelltest );
continue; ccelltest << endl;
ccelltest.close();
}
modelSet.insert(model);
instanceList.push_back(instance);
end_for;
}
for (ModelSet::const_iterator msit = modelSet.begin(); } // CRL namespace.
msit != modelSet.end();
msit++)
{
Cell* model = *msit;
ccell << "component " << model->getName() << endl;
DumpPortList(ccell, model);
ccell << "end component;" << endl;
ccell << endl;
}
DumpSignalList(ccell, cell);
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
}
}

View File

@ -468,6 +468,10 @@ namespace {
void Model::connectSubckts () void Model::connectSubckts ()
{ {
for ( Subckt* subckt : _subckts ) { 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 Instance* instance = Instance::create( _cell
, subckt->getInstanceName() , subckt->getInstanceName()
, subckt->getModel()->getCell() , subckt->getModel()->getCell()

View File

@ -58,9 +58,10 @@ namespace Vhdl {
public: public:
enum Flag { NoFlags = 0x0000 enum Flag { NoFlags = 0x0000
, EntityMode = 0x0001 , EntityMode = 0x0001
, ComponentMode = 0x0002 , IeeeMode = 0x0002
, AsPortSignal = 0x0004 , ComponentMode = 0x0004
, AsInnerSignal = 0x0008 , AsPortSignal = 0x0008
, AsInnerSignal = 0x0010
}; };
public: public:
static bool parseNetName ( const Net*, std::string& stem, size_t& index ); static bool parseNetName ( const Net*, std::string& stem, size_t& index );
@ -70,6 +71,7 @@ namespace Vhdl {
Entity ( EntityProperty*, Cell*, unsigned int flags ); Entity ( EntityProperty*, Cell*, unsigned int flags );
~Entity (); ~Entity ();
inline bool isEntityMode () const; inline bool isEntityMode () const;
inline bool isIeeeMode () const;
inline bool isComponentMode () const; inline bool isComponentMode () const;
const Cell* getCell () const; const Cell* getCell () const;
const Signal* getSignal ( std::string name ) 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::isEntityMode () const { return _flags & EntityMode; }
inline bool Entity::isComponentMode () const { return _flags & ComponentMode; } inline bool Entity::isComponentMode () const { return _flags & ComponentMode; }

View File

@ -147,6 +147,7 @@ class PlaceCore ( chip.Configuration.ChipConfWrapper ):
mauka.destroy() mauka.destroy()
else: else:
etesian = Etesian.EtesianEngine.create( coreCell ) etesian = Etesian.EtesianEngine.create( coreCell )
etesian.setViewer( self.viewer )
etesian.place() etesian.place()
etesian.destroy() etesian.destroy()
@ -189,7 +190,7 @@ def ScriptMain ( **kw ):
cell, editor = plugins.kwParseMain( **kw ) cell, editor = plugins.kwParseMain( **kw )
conf = chip.Configuration.loadConfiguration( cell ) conf = chip.Configuration.loadConfiguration( cell, editor )
if not conf.isValid(): return if not conf.isValid(): return
padsCorona = chip.PadsCorona.Corona( conf ) padsCorona = chip.PadsCorona.Corona( conf )

View File

@ -449,12 +449,13 @@ class ChipConf ( object ):
return return
def __init__ ( self, chipConfigDict, cell ): def __init__ ( self, chipConfigDict, cell, viewer=None ):
if not isinstance(chipConfigDict,dict): if not isinstance(chipConfigDict,dict):
raise ErrorMessage( 1, 'The "chip" variable is not a dictionnary.' ) raise ErrorMessage( 1, 'The "chip" variable is not a dictionnary.' )
self._validated = True self._validated = True
self._cell = cell self._cell = cell
self._viewer = viewer
# Block Corona parameters. # Block Corona parameters.
self._railsNb = getParameter('chip','chip.block.rails.count').asInt() self._railsNb = getParameter('chip','chip.block.rails.count').asInt()
self._hRailWidth = DbU.fromLambda( getParameter('chip','chip.block.rails.hWidth' ).asInt() ) self._hRailWidth = DbU.fromLambda( getParameter('chip','chip.block.rails.hWidth' ).asInt() )
@ -506,6 +507,7 @@ class ChipConf ( object ):
self.checkPads() self.checkPads()
self.computeChipSize() self.computeChipSize()
self.checkChipSize()
self.findPowerAndClockNets() self.findPowerAndClockNets()
return 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.' \ print ErrorMessage( 1, 'There must be at least one pad of model "%s" to be used as reference.' \
% self._pckName ) % self._pckName )
self._validated = False self._validated = False
return False return
self._padHeight = self._clockPad.getMasterCell().getAbutmentBox().getHeight() self._padHeight = self._clockPad.getMasterCell().getAbutmentBox().getHeight()
self._padWidth = self._clockPad.getMasterCell().getAbutmentBox().getWidth() self._padWidth = self._clockPad.getMasterCell().getAbutmentBox().getWidth()
@ -608,11 +610,29 @@ class ChipConf ( object ):
horizontalPads = max( len(self._southPads), len(self._northPads) ) horizontalPads = max( len(self._southPads), len(self._northPads) )
verticalPads = max( len(self._eastPads ), len(self._westPads ) ) verticalPads = max( len(self._eastPads ), len(self._westPads ) )
self._chipSize = Box( 0 self._chipSize = Box( 0
, 0 , 0
, self._padWidth * horizontalPads + 2*self._padHeight , self._padWidth * horizontalPads + 2*self._padHeight
, self._padWidth * verticalPads + 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 return
def getSpecialNetRoot ( self, net ): def getSpecialNetRoot ( self, net ):
@ -645,7 +665,9 @@ class ChipConfWrapper ( GaugeConfWrapper ):
def getSliceStep ( self ): return self._gaugeConf.getSliceStep() def getSliceStep ( self ): return self._gaugeConf.getSliceStep()
@property @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. # Global Pad names.
@property @property
@ -724,7 +746,7 @@ class ChipConfWrapper ( GaugeConfWrapper ):
def useClockTree ( self ): return self._chipConf._useClockTree def useClockTree ( self ): return self._chipConf._useClockTree
def loadConfiguration ( cell ): def loadConfiguration ( cell, viewer=None ):
sys.path.append( os.getcwd() ) sys.path.append( os.getcwd() )
confFile = cell.getName()+'_chip' confFile = cell.getName()+'_chip'
@ -738,4 +760,4 @@ def loadConfiguration ( cell ):
% confFile ) % confFile )
return ChipConfWrapper( GaugeConf() 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 ): def check ( self ):
validated = True self.validated = True
if self._type == chip.North: if self._type == chip.North:
self.validated = self._check( self._corona.coreSize.getWidth() self.validated = self._check( self._corona.coreSize.getWidth()
+ 2*self._corona.minCorona + 2*self._corona.minCorona
@ -106,10 +106,10 @@ class Side ( object ):
elif self._type == chip.South: checkName = 'south pads' elif self._type == chip.South: checkName = 'south pads'
elif self._type == chip.West: checkName = 'west pads' elif self._type == chip.West: checkName = 'west pads'
validated = self._check( len(self._pads)*self._corona.padWidth self.validated = self._check( len(self._pads) * self._corona.padWidth
+ 2*self._corona.padHeight + 2*self._corona.padHeight
, checkName ) and validated , checkName ) and self.validated
return validated return self.validated
def _createPowerContacts ( self, pad, net ): def _createPowerContacts ( self, pad, net ):

View File

@ -24,6 +24,7 @@
#include "hurricane/Plug.h" #include "hurricane/Plug.h"
#include "hurricane/Path.h" #include "hurricane/Path.h"
#include "hurricane/viewer/CellWidget.h" #include "hurricane/viewer/CellWidget.h"
#include "hurricane/viewer/CellViewer.h"
#include "crlcore/AllianceFramework.h" #include "crlcore/AllianceFramework.h"
#include "crlcore/ToolBox.h" #include "crlcore/ToolBox.h"
#include "etesian/EtesianEngine.h" #include "etesian/EtesianEngine.h"
@ -400,7 +401,7 @@ namespace Etesian {
UpdateSession::close(); UpdateSession::close();
if (_cellWidget) _cellWidget->refresh(); if (_viewer) _viewer->getCellWidget()->refresh();
} }

View File

@ -39,6 +39,7 @@
#include "hurricane/RoutingPad.h" #include "hurricane/RoutingPad.h"
#include "hurricane/UpdateSession.h" #include "hurricane/UpdateSession.h"
#include "hurricane/viewer/CellWidget.h" #include "hurricane/viewer/CellWidget.h"
#include "hurricane/viewer/CellViewer.h"
#include "katabatic/GCellGrid.h" #include "katabatic/GCellGrid.h"
#include "katabatic/KatabaticEngine.h" #include "katabatic/KatabaticEngine.h"
#include "kite/KiteEngine.h" #include "kite/KiteEngine.h"
@ -257,7 +258,7 @@ namespace Etesian {
, _placementUB () , _placementUB ()
, _cellsToIds () , _cellsToIds ()
, _idsToInsts () , _idsToInsts ()
, _cellWidget (NULL) , _viewer (NULL)
, _feedCells (this) , _feedCells (this)
{ {
} }
@ -391,7 +392,7 @@ namespace Etesian {
, rows *getSliceHeight() , rows *getSliceHeight()
) ); ) );
UpdateSession::close(); UpdateSession::close();
if (_cellWidget) _cellWidget->fitToContents(); if (_viewer) _viewer->getCellWidget()->fitToContents();
} }
@ -433,7 +434,7 @@ namespace Etesian {
dots.finish( Dots::Reset ); dots.finish( Dots::Reset );
if (_cellWidget) _cellWidget->refresh(); if (_viewer) _viewer->getCellWidget()->refresh();
_placed = false; _placed = false;
} }
@ -996,7 +997,7 @@ namespace Etesian {
UpdateSession::close(); UpdateSession::close();
if (_cellWidget) _cellWidget->refresh(); if (_viewer) _viewer->getCellWidget()->refresh();
} }

View File

@ -67,7 +67,7 @@ namespace Etesian {
EtesianEngine* etesian = EtesianEngine::get( cell ); EtesianEngine* etesian = EtesianEngine::get( cell );
if (not etesian) { if (not etesian) {
etesian = EtesianEngine::create( cell ); etesian = EtesianEngine::create( cell );
etesian->setCellWidget( _viewer->getCellWidget() ); etesian->setViewer( _viewer );
} else } else
cerr << Warning( "%s already has a Etesian engine.", getString(cell).c_str() ) << endl; cerr << Warning( "%s already has a Etesian engine.", getString(cell).c_str() ) << endl;

View File

@ -1,4 +1,3 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
@ -16,7 +15,9 @@
#include "hurricane/isobar/PyCell.h" #include "hurricane/isobar/PyCell.h"
#include "hurricane/viewer/PyCellViewer.h"
#include "hurricane/Cell.h" #include "hurricane/Cell.h"
#include "hurricane/viewer/ExceptionWidget.h"
#include "etesian/PyEtesianEngine.h" #include "etesian/PyEtesianEngine.h"
# undef ACCESS_OBJECT # undef ACCESS_OBJECT
@ -37,6 +38,7 @@ namespace Etesian {
using Hurricane::in_trace; using Hurricane::in_trace;
using Hurricane::Error; using Hurricane::Error;
using Hurricane::Warning; using Hurricane::Warning;
using Hurricane::ExceptionWidget;
using Isobar::ProxyProperty; using Isobar::ProxyProperty;
using Isobar::ProxyError; using Isobar::ProxyError;
using Isobar::ConstructorError; using Isobar::ConstructorError;
@ -46,6 +48,7 @@ namespace Etesian {
using Isobar::ParseTwoArg; using Isobar::ParseTwoArg;
using Isobar::PyCell; using Isobar::PyCell;
using Isobar::PyCell_Link; using Isobar::PyCell_Link;
using Isobar::PyCellViewer;
using CRL::PyToolEngine; using CRL::PyToolEngine;
@ -101,14 +104,44 @@ extern "C" {
return PyEtesianEngine_Link(etesian); 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,runNegociate)
// DirectVoidMethod(EtesianEngine,etesian,printConfiguration)
// DirectVoidMethod(EtesianEngine,etesian,saveGlobalSolution)
// DirectVoidMethod(EtesianEngine,etesian,finalizeLayout)
// DirectVoidMethod(EtesianEngine,etesian,dumpMeasures)
// DirectGetBoolAttribute(PyEtesianEngine_getToolSuccess,getToolSuccess,PyEtesianEngine,EtesianEngine) // DirectGetBoolAttribute(PyEtesianEngine_getToolSuccess,getToolSuccess,PyEtesianEngine,EtesianEngine)
// Standart Destroy (Attribute). // Standart Destroy (Attribute).
@ -120,6 +153,8 @@ extern "C" {
, "Returns the Etesian engine attached to the Cell, None if there isn't." } , "Returns the Etesian engine attached to the Cell, None if there isn't." }
, { "create" , (PyCFunction)PyEtesianEngine_create , METH_VARARGS|METH_STATIC , { "create" , (PyCFunction)PyEtesianEngine_create , METH_VARARGS|METH_STATIC
, "Create an Etesian engine on this cell." } , "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 , { "place" , (PyCFunction)PyEtesianEngine_place , METH_NOARGS
, "Run the placer (Etesian)." } , "Run the placer (Etesian)." }
, { "destroy" , (PyCFunction)PyEtesianEngine_destroy , METH_NOARGS , { "destroy" , (PyCFunction)PyEtesianEngine_destroy , METH_NOARGS

View File

@ -28,6 +28,7 @@ namespace Hurricane {
class Net; class Net;
class Cell; class Cell;
class CellWidget; class CellWidget;
class CellViewer;
class Instance; class Instance;
} }
@ -52,47 +53,48 @@ namespace Etesian {
class EtesianEngine : public CRL::ToolEngine { class EtesianEngine : public CRL::ToolEngine {
public: public:
static const Name& staticGetName (); static const Name& staticGetName ();
static EtesianEngine* create ( Cell* ); static EtesianEngine* create ( Cell* );
static EtesianEngine* get ( const Cell* ); static EtesianEngine* get ( const Cell* );
public: public:
virtual Configuration* getConfiguration (); virtual Configuration* getConfiguration ();
virtual const Configuration* getConfiguration () const; virtual const Configuration* getConfiguration () const;
virtual const Name& getName () const; virtual const Name& getName () const;
inline CellGauge* getCellGauge () const; inline CellGauge* getCellGauge () const;
inline DbU::Unit getPitch () const; inline DbU::Unit getPitch () const;
inline DbU::Unit getSliceHeight () const; inline DbU::Unit getSliceHeight () const;
inline Effort getPlaceEffort () const; inline Effort getPlaceEffort () const;
inline GraphicUpdate getUpdateConf () const; inline GraphicUpdate getUpdateConf () const;
inline Density getSpreadingConf () const; inline Density getSpreadingConf () const;
inline bool getRoutingDriven () const; inline bool getRoutingDriven () const;
inline double getSpaceMargin () const; inline double getSpaceMargin () const;
inline double getAspectRatio () const; inline double getAspectRatio () const;
inline const FeedCells& getFeedCells () const; inline const FeedCells& getFeedCells () const;
inline void setCellWidget ( Hurricane::CellWidget* ); inline Hurricane::CellViewer* getViewer () const;
inline void setViewer ( Hurricane::CellViewer* );
void startMeasures (); void startMeasures ();
void stopMeasures (); void stopMeasures ();
void printMeasures ( std::string ) const; void printMeasures ( std::string ) const;
void setDefaultAb (); void setDefaultAb ();
void resetPlacement (); void resetPlacement ();
void toColoquinte (); void toColoquinte ();
void preplace (); void preplace ();
void roughLegalize ( float minDisruption, unsigned options ); void roughLegalize ( float minDisruption, unsigned options );
void globalPlace ( float initPenalty, float minDisruption, float targetImprovement, float minInc, float maxInc, unsigned options=0 ); 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 detailedPlace ( int iterations, int effort, unsigned options=0 );
void feedRoutingBack (); void feedRoutingBack ();
void place (); void place ();
inline void useFeed ( Cell* ); inline void useFeed ( Cell* );
size_t findYSpin (); size_t findYSpin ();
void addFeeds (); void addFeeds ();
virtual Record* _getRecord () const; virtual Record* _getRecord () const;
virtual std::string _getString () const; virtual std::string _getString () const;
virtual std::string _getTypeName () const; virtual std::string _getTypeName () const;
private: private:
// Attributes. // Attributes.
@ -110,7 +112,7 @@ namespace Etesian {
coloquinte::density_restrictions _densityLimits; coloquinte::density_restrictions _densityLimits;
std::unordered_map<string,unsigned int> _cellsToIds; std::unordered_map<string,unsigned int> _cellsToIds;
std::vector<Instance*> _idsToInsts; std::vector<Instance*> _idsToInsts;
Hurricane::CellWidget* _cellWidget; Hurricane::CellViewer* _viewer;
FeedCells _feedCells; FeedCells _feedCells;
size_t _yspinSlice0; size_t _yspinSlice0;
@ -131,18 +133,19 @@ namespace Etesian {
// Inline Functions. // Inline Functions.
inline void EtesianEngine::setCellWidget ( Hurricane::CellWidget* cw ) { _cellWidget = cw; } inline void EtesianEngine::setViewer ( Hurricane::CellViewer* viewer ) { _viewer = viewer; }
inline CellGauge* EtesianEngine::getCellGauge () const { return getConfiguration()->getCellGauge(); } inline Hurricane::CellViewer* EtesianEngine::getViewer () const { return _viewer; }
inline DbU::Unit EtesianEngine::getPitch () const { return getCellGauge()->getPitch(); } inline CellGauge* EtesianEngine::getCellGauge () const { return getConfiguration()->getCellGauge(); }
inline DbU::Unit EtesianEngine::getSliceHeight () const { return getCellGauge()->getSliceHeight(); } inline DbU::Unit EtesianEngine::getPitch () const { return getCellGauge()->getPitch(); }
inline Effort EtesianEngine::getPlaceEffort () const { return getConfiguration()->getPlaceEffort(); } inline DbU::Unit EtesianEngine::getSliceHeight () const { return getCellGauge()->getSliceHeight(); }
inline GraphicUpdate EtesianEngine::getUpdateConf () const { return getConfiguration()->getUpdateConf(); } inline Effort EtesianEngine::getPlaceEffort () const { return getConfiguration()->getPlaceEffort(); }
inline Density EtesianEngine::getSpreadingConf () const { return getConfiguration()->getSpreadingConf(); } inline GraphicUpdate EtesianEngine::getUpdateConf () const { return getConfiguration()->getUpdateConf(); }
inline bool EtesianEngine::getRoutingDriven () const { return getConfiguration()->getRoutingDriven(); } inline Density EtesianEngine::getSpreadingConf () const { return getConfiguration()->getSpreadingConf(); }
inline double EtesianEngine::getSpaceMargin () const { return getConfiguration()->getSpaceMargin(); } inline bool EtesianEngine::getRoutingDriven () const { return getConfiguration()->getRoutingDriven(); }
inline double EtesianEngine::getAspectRatio () const { return getConfiguration()->getAspectRatio(); } inline double EtesianEngine::getSpaceMargin () const { return getConfiguration()->getSpaceMargin(); }
inline void EtesianEngine::useFeed ( Cell* cell ) { _feedCells.useFeed(cell); } inline double EtesianEngine::getAspectRatio () const { return getConfiguration()->getAspectRatio(); }
inline const FeedCells& EtesianEngine::getFeedCells () const { return _feedCells; } inline void EtesianEngine::useFeed ( Cell* cell ) { _feedCells.useFeed(cell); }
inline const FeedCells& EtesianEngine::getFeedCells () const { return _feedCells; }
// Variables. // Variables.

View File

@ -18,8 +18,6 @@
// License along with Hurricane. If not, see // License along with Hurricane. If not, see
// <http://www.gnu.org/licenses/>. // <http://www.gnu.org/licenses/>.
// //
// ===================================================================
//
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | H U R R I C A N E | // | 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 | // | 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::_resolution = 0.1;
double DbU::_gridsPerLambda = 10.0; double DbU::_gridsPerLambda = 10.0;
double DbU::_physicalsPerGrid = 1.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; unsigned int DbU::_stringMode = DbU::Symbolic;
DbU::UnitPower DbU::_stringModeUnitPower = DbU::Nano; DbU::UnitPower DbU::_stringModeUnitPower = DbU::Nano;
DbU::Unit DbU::_symbolicSnapGridStep = DbU::lambda(1.0); DbU::Unit DbU::_symbolicSnapGridStep = DbU::fromLambda( 1.0);
DbU::Unit DbU::_realSnapGridStep = DbU::grid (10.0); DbU::Unit DbU::_realSnapGridStep = DbU::fromGrid (10.0);
const DbU::Unit DbU::Min = std::numeric_limits<long>::min(); const DbU::Unit DbU::Min = std::numeric_limits<long>::min();
const DbU::Unit DbU::Max = std::numeric_limits<long>::max(); const DbU::Unit DbU::Max = std::numeric_limits<long>::max();
@ -95,6 +96,42 @@ namespace Hurricane {
// Class : "Hurricane::DbU". // 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 () unsigned int DbU::getPrecision ()
{ return _precision; } { return _precision; }
@ -126,6 +163,8 @@ namespace Hurricane {
setSymbolicSnapGridStep ( DbU::lambda( 1.0) ); setSymbolicSnapGridStep ( DbU::lambda( 1.0) );
setRealSnapGridStep ( DbU::grid (10.0) ); setRealSnapGridStep ( DbU::grid (10.0) );
_updateBounds();
} }
@ -144,7 +183,10 @@ namespace Hurricane {
void DbU::setPhysicalsPerGrid ( double physicalsPerGrid, UnitPower p ) void DbU::setPhysicalsPerGrid ( double physicalsPerGrid, UnitPower p )
{ _physicalsPerGrid = physicalsPerGrid * getUnitPower(p); } {
_physicalsPerGrid = physicalsPerGrid * getUnitPower(p);
_updateBounds();
}
double DbU::getPhysicalsPerGrid () double DbU::getPhysicalsPerGrid ()
@ -170,6 +212,8 @@ namespace Hurricane {
DataBase::getDB()->getTechnology()->_onDbuChange ( scale ); DataBase::getDB()->getTechnology()->_onDbuChange ( scale );
setSymbolicSnapGridStep ( DbU::lambda(1) ); setSymbolicSnapGridStep ( DbU::lambda(1) );
_updateBounds();
} }

View File

@ -18,8 +18,6 @@
// License along with Hurricane. If not, see // License along with Hurricane. If not, see
// <http://www.gnu.org/licenses/>. // <http://www.gnu.org/licenses/>.
// //
// ===================================================================
//
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | H U R R I C A N E | // | 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 | // | 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: public:
static void checkGridBound ( double value );
static void checkLambdaBound ( double value );
static void checkPhysicalBound ( double value, UnitPower p );
// User to DB Converters. // User to DB Converters.
static inline Unit fromDb ( long value ); static inline Unit fromDb ( long value );
static inline Unit fromGrid ( double value ); static inline Unit fromGrid ( double value );
@ -120,6 +121,8 @@ namespace Hurricane {
static Slot* getValueSlot ( const string& name, const Unit* u ); static Slot* getValueSlot ( const string& name, const Unit* u );
static void setStringMode ( unsigned int mode, UnitPower p=Nano ); static void setStringMode ( unsigned int mode, UnitPower p=Nano );
static void getStringMode ( unsigned int& mode, UnitPower& p ); static void getStringMode ( unsigned int& mode, UnitPower& p );
private:
static void _updateBounds ();
public: public:
// Static Attributes: constants. // Static Attributes: constants.
@ -136,15 +139,18 @@ namespace Hurricane {
static DbU::UnitPower _stringModeUnitPower; static DbU::UnitPower _stringModeUnitPower;
static DbU::Unit _realSnapGridStep; static DbU::Unit _realSnapGridStep;
static DbU::Unit _symbolicSnapGridStep; static DbU::Unit _symbolicSnapGridStep;
static double _gridMax;
static double _lambdaMax;
static double _physicalMax;
}; };
// Inline Functions. // Inline Functions.
// New converter naming scheme. // New converter naming scheme.
inline DbU::Unit DbU::fromDb ( long value ) { return value; } 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::fromGrid ( double value ) { checkGridBound (value); return (long)rint( value/_resolution ); }
inline DbU::Unit DbU::fromLambda ( double value ) { return fromGrid(value*_gridsPerLambda); } inline DbU::Unit DbU::fromLambda ( double value ) { checkLambdaBound (value); return fromGrid(value*_gridsPerLambda); }
inline DbU::Unit DbU::fromPhysical ( double value, UnitPower p ) { return fromGrid((value*getUnitPower(p))/_physicalsPerGrid); } 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 long DbU::toDb ( DbU::Unit u ) { return u; }
inline double DbU::toGrid ( DbU::Unit u ) { return _resolution*(double)u; } inline double DbU::toGrid ( DbU::Unit u ) { return _resolution*(double)u; }
inline double DbU::toGrid ( double u ) { return _resolution*u; } inline double DbU::toGrid ( double u ) { return _resolution*u; }

View File

@ -22,6 +22,7 @@
// #define DEBUG 1 // #define DEBUG 1
#include "Python.h" #include "Python.h"
#include <exception>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <string> #include <string>
@ -1398,15 +1399,27 @@ extern "C" {
# define HCATCH \ # define HCATCH \
} \ } \
catch ( Error& e ) { \
std::string message = "\n" + getString(e); \
PyErr_SetString ( HurricaneError, message.c_str() ); \
return ( NULL ); \
} \
catch ( Warning& w ) { \ catch ( Warning& w ) { \
std::string message = "\n" + getString(w); \ std::string message = "\n" + getString(w); \
PyErr_Warn ( HurricaneWarning, const_cast<char*>(message.c_str()) ); \ 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". } // 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 { try {
method(); method();
failure = false;
} }
catch ( Error& e ) { catch ( Error& e ) {
ExceptionWidget::run( e ); ExceptionWidget::run( e );
@ -85,6 +87,7 @@ namespace Hurricane {
ExceptionWidget::run( message ); ExceptionWidget::run( message );
} }
return failure;
} }

View File

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

View File

@ -37,7 +37,7 @@ namespace Hurricane {
static void run ( Exception& ); static void run ( Exception& );
static void run ( std::exception& ); static void run ( std::exception& );
static void run ( const QString&, const QString& where="" ); static void run ( const QString&, const QString& where="" );
static void catchAllWrapper ( std::function< void() > method ); static bool catchAllWrapper ( std::function< void() > method );
public: public:
ExceptionWidget ( QWidget* parent=NULL); ExceptionWidget ( QWidget* parent=NULL);
void setMessage ( const QString& ); void setMessage ( const QString& );

View File

@ -49,7 +49,7 @@ extern "C" {
#define IsPyCellViewer(v) ( (v)->ob_type == &PyTypeCellViewer ) #define IsPyCellViewer(v) ( (v)->ob_type == &PyTypeCellViewer )
#define PYCELLVIEWER(v) ( (PyCellViewer*)(v) ) #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". } // End of extern "C".

View File

@ -15,7 +15,7 @@
#include "hurricane/isobar/PyCell.h" #include "hurricane/isobar/PyCell.h"
#include "hurricane/viewer/CellViewer.h" #include "hurricane/viewer/PyCellViewer.h"
#include "hurricane/viewer/ExceptionWidget.h" #include "hurricane/viewer/ExceptionWidget.h"
#include "hurricane/Cell.h" #include "hurricane/Cell.h"
#include "kite/PyKiteEngine.h" #include "kite/PyKiteEngine.h"
@ -48,6 +48,7 @@ namespace Kite {
using Isobar::ParseTwoArg; using Isobar::ParseTwoArg;
using Isobar::PyCell; using Isobar::PyCell;
using Isobar::PyCell_Link; using Isobar::PyCell_Link;
using Isobar::PyCellViewer;
using CRL::PyToolEngine; using CRL::PyToolEngine;
@ -61,12 +62,15 @@ extern "C" {
{ \ { \
trace << "Py" #SELF_TYPE "_" #FUNC_NAME "()" << endl; \ trace << "Py" #SELF_TYPE "_" #FUNC_NAME "()" << endl; \
HTRY \ HTRY \
METHOD_HEAD(#SELF_TYPE "." #FUNC_NAME "()") \ METHOD_HEAD(#SELF_TYPE "." #FUNC_NAME "()") \
if (SELF_OBJECT->getViewer()) { \ if (SELF_OBJECT->getViewer()) { \
ExceptionWidget::catchAllWrapper( std::bind(&KiteEngine::FUNC_NAME,SELF_OBJECT) ); \ if (ExceptionWidget::catchAllWrapper( std::bind(&KiteEngine::FUNC_NAME,SELF_OBJECT) )) { \
} else { \ PyErr_SetString( HurricaneError, #FUNC_NAME "() has thrown an exception (C++)." ); \
SELF_OBJECT->FUNC_NAME(); \ return NULL; \
} \ } \
} else { \
SELF_OBJECT->FUNC_NAME(); \
} \
HCATCH \ HCATCH \
Py_RETURN_NONE; \ 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 ) PyObject* PyKiteEngine_runGlobalRouter ( PyKiteEngine* self, PyObject* args )
{ {
trace << "PyKiteEngine_runGlobalRouter()" << endl; trace << "PyKiteEngine_runGlobalRouter()" << endl;
HTRY HTRY
METHOD_HEAD("KiteEngine.runGlobalRouter()") METHOD_HEAD("KiteEngine.runGlobalRouter()")
unsigned int flags = 0; unsigned int flags = 0;
if (PyArg_ParseTuple(args,"I:KiteEngine.runGlobalRouter", &flags)) { if (PyArg_ParseTuple(args,"I:KiteEngine.runGlobalRouter", &flags)) {
if (kite->getViewer()) { if (kite->getViewer()) {
ExceptionWidget::catchAllWrapper( std::bind(&KiteEngine::runGlobalRouter,kite,flags) ); 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 { } 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 HCATCH
Py_RETURN_NONE; Py_RETURN_NONE;
@ -177,7 +202,10 @@ extern "C" {
} }
if (kite->getViewer()) { 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 { } else {
kite->loadGlobalRouting(flags/*,*routingNets*/); kite->loadGlobalRouting(flags/*,*routingNets*/);
} }
@ -201,8 +229,14 @@ extern "C" {
if (PyArg_ParseTuple(args,"I:KiteEngine.layerAssign", &flags)) { if (PyArg_ParseTuple(args,"I:KiteEngine.layerAssign", &flags)) {
if (kite->getViewer()) { if (kite->getViewer()) {
ExceptionWidget::catchAllWrapper( std::bind(&KiteEngine::balanceGlobalDensity,kite) ); bool failure = ExceptionWidget::catchAllWrapper( std::bind(&KiteEngine::balanceGlobalDensity,kite) );
ExceptionWidget::catchAllWrapper( std::bind(&KiteEngine::layerAssign ,kite,flags) ); 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 { } else {
kite->balanceGlobalDensity(); kite->balanceGlobalDensity();
kite->layerAssign (flags); kite->layerAssign (flags);
@ -223,7 +257,10 @@ extern "C" {
HTRY HTRY
METHOD_HEAD("KiteEngine.runNegociatePreRouted()") METHOD_HEAD("KiteEngine.runNegociatePreRouted()")
if (kite->getViewer()) { 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 { } else {
kite->runNegociate( Kite::KtPreRoutedStage ); kite->runNegociate( Kite::KtPreRoutedStage );
} }
@ -238,7 +275,10 @@ extern "C" {
HTRY HTRY
METHOD_HEAD("KiteEngine.runNegociate()") METHOD_HEAD("KiteEngine.runNegociate()")
if (kite->getViewer()) { 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 { } else {
kite->runNegociate(); kite->runNegociate();
} }
@ -263,6 +303,8 @@ extern "C" {
, "Returns the Kite engine attached to the Cell, None if there isnt't." } , "Returns the Kite engine attached to the Cell, None if there isnt't." }
, { "create" , (PyCFunction)PyKiteEngine_create , METH_VARARGS|METH_STATIC , { "create" , (PyCFunction)PyKiteEngine_create , METH_VARARGS|METH_STATIC
, "Create a Kite engine on this cell." } , "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 , { "printConfiguration" , (PyCFunction)PyKiteEngine_printConfiguration , METH_NOARGS
, "Display on the console the configuration of Kite." } , "Display on the console the configuration of Kite." }
, { "saveGlobalSolution" , (PyCFunction)PyKiteEngine_saveGlobalSolution , METH_NOARGS , { "saveGlobalSolution" , (PyCFunction)PyKiteEngine_saveGlobalSolution , METH_NOARGS