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

View File

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

View File

@ -2,7 +2,7 @@
// -*- C++ -*-
//
// 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 |
@ -44,20 +44,12 @@ namespace {
}
// x-----------------------------------------------------------------x
// | "::ProxyProperty" Global Variables |
// x-----------------------------------------------------------------x
// -------------------------------------------------------------------
// Class : "ProxyProperty".
Name ProxyProperty::_name = "Isobar::ProxyProperty";
int ProxyProperty::_offset = -1;
// x-----------------------------------------------------------------x
// | "::ProxyProperty" Class Definitions |
// x-----------------------------------------------------------------x
Name ProxyProperty::_name = "Isobar::ProxyProperty";
int ProxyProperty::_offset = -1;
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 );
if ( property == NULL )
throw Error ( "ProxyProperty::create()" );
if (not property)
throw Error( "ProxyProperty::create()" );
return property;
}
@ -80,12 +76,13 @@ ProxyProperty* ProxyProperty::create ( void* shadow ) {
void ProxyProperty::_preDestroy () {
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 ) {
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;
}

View File

@ -2,7 +2,7 @@
// -*- C++ -*-
//
// 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 |
@ -15,8 +15,8 @@
// +-----------------------------------------------------------------+
#ifndef __PROXY_PROPERTY__
#define __PROXY_PROPERTY__
#ifndef ISOBAR_PROXY_PROPERTY_H
#define ISOBAR_PROXY_PROPERTY_H
#include "hurricane/DBo.h"
#include "hurricane/Property.h"
@ -44,7 +44,7 @@ using namespace Hurricane;
static const Name& getPropertyName () { return _name; }
static int getOffset () { return _offset; };
static void setOffset ( int offset );
static ProxyProperty* create ( void* _shadow=NULL );
static ProxyProperty* create ( void* shadow=NULL );
public:
DBo* getOwner () const { return _owner; };
void* getShadow () const { return _shadow; };

View File

@ -764,7 +764,7 @@ extern "C" {
\
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_dealloc = (destructor)Py##TYPE##Collection_DeAlloc; \
PyType##TYPE##CollectionLocator.tp_dealloc = (destructor)Py##TYPE##CollectionLocatorDeAlloc; \
@ -964,19 +964,22 @@ extern "C" {
// Attribute Method For Repr.
#define DirectReprMethod(PY_FUNC_NAME,PY_SELF_TYPE,SELF_TYPE) \
static PyObject* PY_FUNC_NAME ( PY_SELF_TYPE *self ) \
{ \
if ( self->ACCESS_OBJECT == NULL ) \
return ( PyString_FromString("<PyObject unbound>") ); \
SELF_TYPE* object = dynamic_cast<SELF_TYPE*>(self->ACCESS_OBJECT); \
if ( object == NULL ) \
return ( PyString_FromString("<PyObject invalid dynamic-cast>") ); \
\
ostringstream repr; \
#define DirectReprMethod(PY_FUNC_NAME,PY_SELF_TYPE,SELF_TYPE) \
static PyObject* PY_FUNC_NAME ( PY_SELF_TYPE *self ) \
{ \
if (self->ACCESS_OBJECT == NULL) { \
ostringstream repr; \
repr << "<" #PY_SELF_TYPE " [" << (void*)self << " <-> NULL] unbound>"; \
return PyString_FromString( repr.str().c_str() ); \
} \
SELF_TYPE* object = dynamic_cast<SELF_TYPE*>(self->ACCESS_OBJECT); \
if (object == NULL) \
return PyString_FromString( "<PyObject invalid dynamic_cast>" ); \
\
ostringstream repr; \
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.
# define DirectStrMethod(PY_FUNC_NAME,PY_SELF_TYPE,SELF_TYPE) \
static PyObject* PY_FUNC_NAME ( PY_SELF_TYPE *self ) \
{ \
if ( self->ACCESS_OBJECT == NULL ) \
return ( PyString_FromString("<PyObject unbound>") ); \
SELF_TYPE* object = dynamic_cast<SELF_TYPE*>(self->ACCESS_OBJECT); \
if ( object == NULL ) \
return ( PyString_FromString("<PyObject invalid dynamic_cast>") ); \
\
return ( PyString_FromString(getString(object).c_str()) ); \
# define DirectStrMethod(PY_FUNC_NAME,PY_SELF_TYPE,SELF_TYPE) \
static PyObject* PY_FUNC_NAME ( PY_SELF_TYPE *self ) \
{ \
if (self->ACCESS_OBJECT == NULL) { \
ostringstream repr; \
repr << "<" #PY_SELF_TYPE " [" << (void*)self << " <-> NULL] unbound>"; \
return PyString_FromString( repr.str().c_str() ); \
} \
SELF_TYPE* object = dynamic_cast<SELF_TYPE*>(self->ACCESS_OBJECT); \
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() ); \
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 = NULL; \
HCATCH \

View File

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