attachPlugOrPin() do not core-dump when there is 0 plugs+pins.

* Bug: In CRL::ToolBox::attachPlugOrPin(), simply returns when there is
    no plugs/pins to connect instead of doing an assert().
* Change: In Hurricane, more informative trace information for Python
    ProxyProperty managment.
* Bug: In Stratus, when merging nets with the "<=" operator some table
    of lookup of Hurricane Net are not updated correctly. As I don't
    understand well enough the Stratus code **is is not corrected**.
This commit is contained in:
Jean-Paul Chaput 2016-11-27 00:04:58 +01:00
parent a6cbdb8aa8
commit 3758bd098e
6 changed files with 128 additions and 130 deletions

View File

@ -212,70 +212,56 @@ void placePlugs ( Cell* cell )
// } // }
//} //}
static void AttachPlugOrPin(Net& net) static void attachPlugOrPin ( Net* net )
{ {
unsigned nbPlugs = 0; unsigned int nbPlugs = 0;
unsigned nbPins = 0; unsigned int nbPins = 0;
unsigned nbUnattachedPlugs = 0; unsigned int nbUnattachedPlugs = 0;
unsigned nbUnattachedPins = 0; unsigned int nbUnattachedPins = 0;
Component* firstAttachedComponent = NULL;
Component* firstUnattachedComponent = NULL;
Component* secondUnattachedComponent = NULL;
Component* firstAttachedComponent = NULL; for ( Plug* plug : net->getPlugs() ) {
Component* firstUnattachedComponent = NULL; nbPlugs++;
Component* secondUnattachedComponent = NULL; if (not plug->getBodyHook()->isAttached()) {
if (not firstUnattachedComponent) firstUnattachedComponent = plug;
for_each_plug ( plug, net.getPlugs() ) { else if (not secondUnattachedComponent) secondUnattachedComponent = plug;
nbPlugs++; nbUnattachedPlugs++;
if ( !plug->getBodyHook()->isAttached() ) { } else {
if ( !firstUnattachedComponent ) if (not firstAttachedComponent ) firstAttachedComponent = plug;
firstUnattachedComponent = plug;
else
if ( !secondUnattachedComponent )
secondUnattachedComponent = plug;
nbUnattachedPlugs++;
}
else {
if ( !firstAttachedComponent )
firstAttachedComponent = plug;
}
end_for
} }
}
for_each_pin ( pin, net.getPins() ) { for ( Pin* pin : net->getPins() ) {
nbPins++; nbPins++;
if ( !pin->getBodyHook()->isAttached() ) { if (not pin->getBodyHook()->isAttached()) {
if ( !firstUnattachedComponent ) if (not firstUnattachedComponent ) firstUnattachedComponent = pin;
firstUnattachedComponent = pin; else if (not secondUnattachedComponent) secondUnattachedComponent = pin;
else nbUnattachedPins++;
if ( !secondUnattachedComponent ) } else {
secondUnattachedComponent = pin; if (not firstAttachedComponent ) firstAttachedComponent = pin;
nbUnattachedPins++;
}
else {
if ( !firstAttachedComponent )
firstAttachedComponent = pin;
}
end_for
} }
}
if ( (nbPlugs + nbPins) == 1 ) if (nbPlugs + nbPins < 2) return;
return;
if ( (nbPlugs + nbPins > 2) and (nbUnattachedPlugs + nbUnattachedPins != 1) ) {
if ( ((nbPlugs + nbPins) > 2) && ((nbUnattachedPlugs + nbUnattachedPins) != 1) ) { throw Error( "attachPlugOrPin(): Net \"%s\" has %u unattached Plugs/Pins,"
string message = "AttachPlugOrPin() : Net " + getString(&net) + " has " + getString(nbUnattachedPlugs + nbUnattachedPins) " while it should have only one."
+ " unattached plugs/pins : it should have only one unattached plug/pin."; , getString(net->getName()).c_str()
throw Error(message); , nbUnattachedPlugs + nbUnattachedPins
} );
}
if ( !firstAttachedComponent ) {
assert ( firstUnattachedComponent );
assert ( secondUnattachedComponent );
firstUnattachedComponent->getBodyHook()->attach ( secondUnattachedComponent->getBodyHook() );
}
else {
assert ( firstUnattachedComponent );
firstUnattachedComponent->getBodyHook()->attach ( firstAttachedComponent->getBodyHook() );
}
if (not firstAttachedComponent) {
assert( firstUnattachedComponent );
assert( secondUnattachedComponent );
firstUnattachedComponent->getBodyHook()->attach( secondUnattachedComponent->getBodyHook() );
} else {
assert( firstUnattachedComponent );
firstUnattachedComponent->getBodyHook()->attach( firstAttachedComponent->getBodyHook() );
}
} }
@ -303,7 +289,7 @@ void createPartRing2(Net& net)
if (net.isGlobal()) if (net.isGlobal())
throw Warning("Cannot create plugs ring on global Net"); throw Warning("Cannot create plugs ring on global Net");
AttachPlugOrPin(net); attachPlugOrPin(&net);
UpdateSession::close(); UpdateSession::close();
} }

View File

@ -623,6 +623,8 @@ static void mergeNets(Net* net1, Net* net2)
void Net::merge(Net* net) void Net::merge(Net* net)
// ********************** // **********************
{ {
cdebug_log(18,0) << "Net::merge(): " << this << " with " << net << " (deleted)." << endl;
if (!net) if (!net)
throw Error("Can't merge net : null net"); throw Error("Can't merge net : null net");
@ -706,38 +708,41 @@ void Net::_postCreate()
void Net::_preDestroy() void Net::_preDestroy()
// ******************* // *******************
{ {
Inherit::_preDestroy(); cdebug_log(18,1) << "entering Net::_preDestroy: " << this << endl;
Plugs plugs = getSlavePlugs(); Inherit::_preDestroy();
while ( plugs.getFirst() ) plugs.getFirst()->_destroy();
unmaterialize(); Plugs plugs = getSlavePlugs();
while ( plugs.getFirst() ) plugs.getFirst()->_destroy();
Rubbers rubbers = getRubbers(); unmaterialize();
while ( rubbers.getFirst() ) rubbers.getFirst()->_destroy();
for_each_component(component, getComponents()) { Rubbers rubbers = getRubbers();
for_each_hook(hook, component->getHooks()) { while ( rubbers.getFirst() ) rubbers.getFirst()->_destroy();
// 15 05 2006 xtof : detach all hooks in rings when
// a net deletion occurs, can't see why master hooks were not detached. for ( Component* component : getComponents() ) {
//if (!hook->IsMaster()) hook->detach(); for ( Hook* hook : component->getHooks() ) {
hook->detach(); // 15 05 2006 xtof : detach all hooks in rings when
end_for; // a net deletion occurs, can't see why master hooks were not detached.
// 24/02/2016 jpc: the answer, at last... we cannot iterate //if (!hook->IsMaster()) hook->detach();
// over a collection as it is modificated/destroyed! hook->detach();
} // 24/02/2016 jpc: the answer, at last... we cannot iterate
end_for; // over a collection as it is modificated/destroyed!
} }
}
Components components = getComponents();
while ( components.getFirst() ) {
Component* component = components.getFirst();
if (!dynamic_cast<Plug*>(component)) component->destroy();
else (static_cast<Plug*>(component))->setNet(NULL);
}
Components components = getComponents(); _mainName.clear();
while ( components.getFirst() ) { _cell->_getNetMap()._remove(this);
Component* component = components.getFirst();
if (!dynamic_cast<Plug*>(component)) component->destroy();
else (static_cast<Plug*>(component))->setNet(NULL);
}
_mainName.clear(); cdebug_log(18,0) << "exiting Net::_preDestroy: " << this << endl;
_cell->_getNetMap()._remove(this); cdebug_tabw(18,-1);
} }
string Net::_getString() const string Net::_getString() const

View File

@ -2,7 +2,7 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved // Copyright (c) UPMC 2008-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -44,20 +44,12 @@ namespace {
} }
// x-----------------------------------------------------------------x // -------------------------------------------------------------------
// | "::ProxyProperty" Global Variables | // Class : "ProxyProperty".
// x-----------------------------------------------------------------x
Name ProxyProperty::_name = "Isobar::ProxyProperty"; Name ProxyProperty::_name = "Isobar::ProxyProperty";
int ProxyProperty::_offset = -1; int ProxyProperty::_offset = -1;
// x-----------------------------------------------------------------x
// | "::ProxyProperty" Class Definitions |
// x-----------------------------------------------------------------x
ProxyProperty::ProxyProperty ( void* shadow ) ProxyProperty::ProxyProperty ( void* shadow )
@ -67,11 +59,15 @@ ProxyProperty::ProxyProperty ( void* shadow )
{ } { }
ProxyProperty* ProxyProperty::create ( void* shadow ) { ProxyProperty* ProxyProperty::create ( void* shadow )
{
if (not shadow)
throw Error( "ProxyProperty::create(): Empty \"shadow\" argument." );
ProxyProperty* property = new ProxyProperty ( shadow ); ProxyProperty* property = new ProxyProperty ( shadow );
if ( property == NULL ) if (not property)
throw Error ( "ProxyProperty::create()" ); throw Error( "ProxyProperty::create()" );
return property; return property;
} }
@ -80,12 +76,13 @@ ProxyProperty* ProxyProperty::create ( void* shadow ) {
void ProxyProperty::_preDestroy () { void ProxyProperty::_preDestroy () {
if ( _owner ) _owner->_onDestroyed ( this ); if ( _owner ) _owner->_onDestroyed ( this );
cdebug_log(20,0) << "ProxyProperty::_owner := " << hex << (void*)_owner << endl; cdebug_log(20,0) << "ProxyProperty::_owner: " << (void*)_owner << endl;
cdebug_log(20,0) << "ProxyProperty::_shadow: " << (void*)_shadow << endl;
if ( _offset > 0 ) { if ( _offset > 0 ) {
void** shadowMember = ( (void**)( (unsigned long)_shadow + _offset ) ); void** shadowMember = ( (void**)( (unsigned long)_shadow + _offset ) );
cdebug_log(20,0) << "ProxyProperty::_shadowMember := " << hex << *shadowMember << endl; cdebug_log(20,0) << "ProxyProperty::_shadowMember: " << (void*)*shadowMember << endl;
*shadowMember = NULL; *shadowMember = NULL;
} }

View File

@ -2,7 +2,7 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved // Copyright (c) UPMC 2008-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -15,8 +15,8 @@
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
#ifndef __PROXY_PROPERTY__ #ifndef ISOBAR_PROXY_PROPERTY_H
#define __PROXY_PROPERTY__ #define ISOBAR_PROXY_PROPERTY_H
#include "hurricane/DBo.h" #include "hurricane/DBo.h"
#include "hurricane/Property.h" #include "hurricane/Property.h"
@ -44,7 +44,7 @@ using namespace Hurricane;
static const Name& getPropertyName () { return _name; } static const Name& getPropertyName () { return _name; }
static int getOffset () { return _offset; }; static int getOffset () { return _offset; };
static void setOffset ( int offset ); static void setOffset ( int offset );
static ProxyProperty* create ( void* _shadow=NULL ); static ProxyProperty* create ( void* shadow=NULL );
public: public:
DBo* getOwner () const { return _owner; }; DBo* getOwner () const { return _owner; };
void* getShadow () const { return _shadow; }; void* getShadow () const { return _shadow; };

View File

@ -764,7 +764,7 @@ extern "C" {
\ \
extern void Py##TYPE##Collection_LinkPyType () \ extern void Py##TYPE##Collection_LinkPyType () \
{ \ { \
cdebug_log(20,0) << "Py"#TYPE"Collection_LinkType()" << endl; \ cdebug_log(20,0) << "Py"#TYPE"Collection_LinkType()" << endl; \
PyType##TYPE##Collection.tp_iter = (getiterfunc)GetLocator; \ PyType##TYPE##Collection.tp_iter = (getiterfunc)GetLocator; \
PyType##TYPE##Collection.tp_dealloc = (destructor)Py##TYPE##Collection_DeAlloc; \ PyType##TYPE##Collection.tp_dealloc = (destructor)Py##TYPE##Collection_DeAlloc; \
PyType##TYPE##CollectionLocator.tp_dealloc = (destructor)Py##TYPE##CollectionLocatorDeAlloc; \ PyType##TYPE##CollectionLocator.tp_dealloc = (destructor)Py##TYPE##CollectionLocatorDeAlloc; \
@ -964,19 +964,22 @@ extern "C" {
// Attribute Method For Repr. // Attribute Method For Repr.
#define DirectReprMethod(PY_FUNC_NAME,PY_SELF_TYPE,SELF_TYPE) \ #define DirectReprMethod(PY_FUNC_NAME,PY_SELF_TYPE,SELF_TYPE) \
static PyObject* PY_FUNC_NAME ( PY_SELF_TYPE *self ) \ static PyObject* PY_FUNC_NAME ( PY_SELF_TYPE *self ) \
{ \ { \
if ( self->ACCESS_OBJECT == NULL ) \ if (self->ACCESS_OBJECT == NULL) { \
return ( PyString_FromString("<PyObject unbound>") ); \ ostringstream repr; \
SELF_TYPE* object = dynamic_cast<SELF_TYPE*>(self->ACCESS_OBJECT); \ repr << "<" #PY_SELF_TYPE " [" << (void*)self << " <-> NULL] unbound>"; \
if ( object == NULL ) \ return PyString_FromString( repr.str().c_str() ); \
return ( PyString_FromString("<PyObject invalid dynamic-cast>") ); \ } \
\ SELF_TYPE* object = dynamic_cast<SELF_TYPE*>(self->ACCESS_OBJECT); \
ostringstream repr; \ if (object == NULL) \
return PyString_FromString( "<PyObject invalid dynamic_cast>" ); \
\
ostringstream repr; \
repr << "[" << (void*)self << "<->" << (void*)object << " " << getString(object) << "]"; \ repr << "[" << (void*)self << "<->" << (void*)object << " " << getString(object) << "]"; \
\ \
return ( PyString_FromString(repr.str().c_str()) ); \ return PyString_FromString(repr.str().c_str() ); \
} }
@ -985,16 +988,19 @@ extern "C" {
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Attribute Method For Str. // Attribute Method For Str.
# define DirectStrMethod(PY_FUNC_NAME,PY_SELF_TYPE,SELF_TYPE) \ # define DirectStrMethod(PY_FUNC_NAME,PY_SELF_TYPE,SELF_TYPE) \
static PyObject* PY_FUNC_NAME ( PY_SELF_TYPE *self ) \ static PyObject* PY_FUNC_NAME ( PY_SELF_TYPE *self ) \
{ \ { \
if ( self->ACCESS_OBJECT == NULL ) \ if (self->ACCESS_OBJECT == NULL) { \
return ( PyString_FromString("<PyObject unbound>") ); \ ostringstream repr; \
SELF_TYPE* object = dynamic_cast<SELF_TYPE*>(self->ACCESS_OBJECT); \ repr << "<" #PY_SELF_TYPE " [" << (void*)self << " <-> NULL] unbound>"; \
if ( object == NULL ) \ return PyString_FromString( repr.str().c_str() ); \
return ( PyString_FromString("<PyObject invalid dynamic_cast>") ); \ } \
\ SELF_TYPE* object = dynamic_cast<SELF_TYPE*>(self->ACCESS_OBJECT); \
return ( PyString_FromString(getString(object).c_str()) ); \ if (object == NULL) \
return PyString_FromString("<PyObject invalid dynamic_cast>" ); \
\
return PyString_FromString(getString(object).c_str() ); \
} }
@ -1070,6 +1076,8 @@ extern "C" {
PyErr_SetString( ProxyError, message.str().c_str() ); \ PyErr_SetString( ProxyError, message.str().c_str() ); \
return NULL; \ return NULL; \
} \ } \
cdebug_log(20,0) << #PY_FUNC_NAME "(" << (void*)self << ") " \
<< (void*)self->ACCESS_OBJECT << ":" << self->ACCESS_OBJECT << endl; \
self->ACCESS_OBJECT->destroy(); \ self->ACCESS_OBJECT->destroy(); \
self->ACCESS_OBJECT = NULL; \ self->ACCESS_OBJECT = NULL; \
HCATCH \ HCATCH \

View File

@ -311,8 +311,10 @@ class Inst :
else : else :
hurNet = realNet._hur_net[i] hurNet = realNet._hur_net[i]
if mapNet._arity == 1 : tempNet = self._hur_masterCell.getNet ( pin.lower() ) if mapNet._arity == 1:
else : tempNet = self._hur_masterCell.getNet ( pin.lower() + "(" + str(j+lsb) + ")" ) tempNet = self._hur_masterCell.getNet ( pin.lower() )
else:
tempNet = self._hur_masterCell.getNet ( pin.lower() + "(" + str(j+lsb) + ")" )
j += 1 j += 1
if not ( tempNet ) : if not ( tempNet ) :