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:
parent
909f86b4fc
commit
f8a72288aa
|
@ -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"
|
||||
)))))
|
|
@ -5,6 +5,10 @@
|
|||
*.bak
|
||||
|
||||
TAGS
|
||||
GTAGS
|
||||
GPATH
|
||||
GRTAGS
|
||||
|
||||
|
||||
man/
|
||||
rtf/
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
-*.fig
|
||||
-*.png
|
||||
-*.eps
|
||||
-*.pdf
|
||||
-*.aux
|
||||
-*.bb
|
|
@ -33,6 +33,9 @@
|
|||
#include "crlcore/AllianceFramework.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
namespace CRL {
|
||||
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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 ) )
|
||||
|
|
|
@ -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 ):
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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".
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 ) {
|
||||
|
|
|
@ -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& );
|
||||
|
|
|
@ -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".
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue