Remove unconnected part of the nets after HFNS.

This was the reason why we, sometimes got "UNCONNECTED" errors in the
VHDL PORT MAP statements. This was the remnants of the originally
connected driver.

* Bug: In Etesian::BufferTree, as the root driver is disconnected from
    all the sinks, but the top tree buffer, we may end up with
    unconnected signal on instances that were using it.
      So now, call BufferTree::rcleaupNet() to remove the Net in
    the Cell that where used to "transmit" the original driver.
* Bug: In Etesian::BufferTree, no longer use a _isDeepNet attribute
    guessed from the occurrences pathes of the RoutingPad, but
    trust the Net::isDeepNet() method.
This commit is contained in:
Jean-Paul Chaput 2022-05-25 17:09:00 +02:00
parent 86d539fe5d
commit 2efae3507e
2 changed files with 37 additions and 6 deletions

View File

@ -38,6 +38,7 @@ namespace Etesian {
using Hurricane::tab; using Hurricane::tab;
using Hurricane::Warning; using Hurricane::Warning;
using Hurricane::Error; using Hurricane::Error;
using Hurricane::DebugSession;
using Hurricane::Path; using Hurricane::Path;
using Hurricane::Transformation; using Hurricane::Transformation;
using Hurricane::DataBase; using Hurricane::DataBase;
@ -249,6 +250,7 @@ namespace Etesian {
void Cluster::splitNet () void Cluster::splitNet ()
{ {
cdebug_log(123,0) << "Cluster::splitNet()" << endl;
createOutput(); createOutput();
for ( Cluster* cluster : _clusters ) { for ( Cluster* cluster : _clusters ) {
cluster->createInput( _driverNet ); cluster->createInput( _driverNet );
@ -291,10 +293,10 @@ namespace Etesian {
virtual void splitNet (); virtual void splitNet ();
void rpartition (); void rpartition ();
uint32_t build (); uint32_t build ();
bool rcleanupNet ( Net* );
string _getTypeName () const; string _getTypeName () const;
private: private:
SubNetNames _subNetNames; SubNetNames _subNetNames;
bool _isDeepNet;
Net* _rootNet; Net* _rootNet;
RoutingPad* _rpDriver; RoutingPad* _rpDriver;
vector< vector<Cluster*> > _clustersStack; vector< vector<Cluster*> > _clustersStack;
@ -304,7 +306,6 @@ namespace Etesian {
BufferTree::BufferTree ( EtesianEngine* etesian, Net* rootNet ) BufferTree::BufferTree ( EtesianEngine* etesian, Net* rootNet )
: Cluster(etesian) : Cluster(etesian)
, _subNetNames () , _subNetNames ()
, _isDeepNet (true)
, _rootNet (rootNet) , _rootNet (rootNet)
, _rpDriver (NULL) , _rpDriver (NULL)
, _clustersStack() , _clustersStack()
@ -331,14 +332,18 @@ namespace Etesian {
void BufferTree::splitNet () void BufferTree::splitNet ()
{ {
cdebug_log(123,0) << "BufferTree::splitNet()" << endl;
if (not _rpDriver) if (not _rpDriver)
throw Error( "BufferTree::splitNet(): Missing driver on %s.", getString(_rootNet).c_str() ); throw Error( "BufferTree::splitNet(): Missing driver on %s.", getString(_rootNet).c_str() );
Net* origDriver = _rootNet;
Cluster::splitNet(); Cluster::splitNet();
if (_isDeepNet) { if (_rootNet->isDeepNet()) {
Cell* topCell = getEtesian()->getCell(); Cell* topCell = getEtesian()->getCell();
Name topNetName = _rootNet->getName(); Name topNetName = _rootNet->getName();
Occurrence driverRpOcc = _rpDriver->getPlugOccurrence(); Occurrence driverRpOcc = _rpDriver->getPlugOccurrence();
origDriver = dynamic_cast<Net*>( static_cast<DeepNet*>( _rootNet )->getRootNetOccurrence().getEntity() );
_rootNet->destroy(); _rootNet->destroy();
_rootNet = Net::create( topCell, topNetName ); _rootNet = Net::create( topCell, topNetName );
Net* deepDriverNet = raddTransNet( _rootNet, driverRpOcc.getPath(), AS_DRIVER ); Net* deepDriverNet = raddTransNet( _rootNet, driverRpOcc.getPath(), AS_DRIVER );
@ -346,6 +351,7 @@ namespace Etesian {
RoutingPad::create( _rootNet, driverRpOcc, RoutingPad::BiggestArea ); RoutingPad::create( _rootNet, driverRpOcc, RoutingPad::BiggestArea );
} }
createInput( _rootNet ); createInput( _rootNet );
rcleanupNet( origDriver );
} }
@ -361,16 +367,15 @@ namespace Etesian {
RoutingPad* rpPin = NULL; RoutingPad* rpPin = NULL;
for ( RoutingPad* rp : _rootNet->getRoutingPads() ) { for ( RoutingPad* rp : _rootNet->getRoutingPads() ) {
Occurrence rpOccurrence = rp->getPlugOccurrence(); Occurrence rpOccurrence = rp->getPlugOccurrence();
if (rpOccurrence.getPath().isEmpty())
_isDeepNet = false;
Pin* pin = dynamic_cast<Pin* >( rpOccurrence.getEntity() ); Pin* pin = dynamic_cast<Pin* >( rpOccurrence.getEntity() );
if (pin) { if (pin) {
if (not rpPin) { if (not rpPin) {
if (dynamic_cast<Pin* >( rpOccurrence.getEntity() )) { if (dynamic_cast<Pin* >( rpOccurrence.getEntity() )) {
cdebug_log(123,0) << "pin: " << rp << endl;
rpPin = rp; rpPin = rp;
} }
} }
cdebug_log(123,0) << "Excluded: " << pin << endl; cdebug_log(123,0) << "Excluded second pin: " << pin << endl;
continue; continue;
} }
Plug* rpPlug = dynamic_cast<Plug*>( rpOccurrence.getEntity() ); Plug* rpPlug = dynamic_cast<Plug*>( rpOccurrence.getEntity() );
@ -383,6 +388,7 @@ namespace Etesian {
cdebug_log(123,0) << "merge: " << _clustersStack[0].back()->getSize() << " " << rp << endl; cdebug_log(123,0) << "merge: " << _clustersStack[0].back()->getSize() << " " << rp << endl;
_clustersStack[0].back()->merge( rp ); _clustersStack[0].back()->merge( rp );
} else { } else {
cdebug_log(123,0) << "driver: " << rp << endl;
_rpDriver = rp; _rpDriver = rp;
} }
} }
@ -432,6 +438,8 @@ namespace Etesian {
uint32_t BufferTree::build () uint32_t BufferTree::build ()
{ {
DebugSession::open( _rootNet, 120, 130 );
cdebug_log(123,1) << "BufferTree::build() " << _rootNet << endl;
uint32_t bufferCount = 0; uint32_t bufferCount = 0;
rpartition(); rpartition();
for ( vector<Cluster*>& clusters : _clustersStack ) { for ( vector<Cluster*>& clusters : _clustersStack ) {
@ -440,9 +448,29 @@ namespace Etesian {
++bufferCount; ++bufferCount;
} }
} }
cdebug_tabw(123,-1);
DebugSession::close();
return bufferCount; return bufferCount;
} }
bool BufferTree::rcleanupNet ( Net* net )
{
if (net->getCell()->isTerminalNetlist() or net->getCell()->isTerminal())
return false;
vector<Plug*> plugs;
for ( Plug* plug : net->getPlugs() ) plugs.push_back( plug );
for ( Plug* plug : plugs ) {
rcleanupNet( plug->getMasterNet() );
}
if (net->getPlugs().getFirst() == nullptr) {
cdebug_log(123,0) << "BufferTree::rcleanupNet() " << net << " of " << net->getCell() << endl;
net->destroy();
return true;
}
return false;
}
string BufferTree::_getTypeName () const string BufferTree::_getTypeName () const
{ return "BufferTree"; } { return "BufferTree"; }
@ -484,6 +512,7 @@ namespace Etesian {
} }
} }
//DebugSession::open( 120, 130 );
UpdateSession::open(); UpdateSession::open();
Go::disableAutoMaterialization(); Go::disableAutoMaterialization();
_bufferCount = 0; _bufferCount = 0;
@ -508,6 +537,7 @@ namespace Etesian {
// } // }
Go::enableAutoMaterialization(); Go::enableAutoMaterialization();
UpdateSession::close(); UpdateSession::close();
//DebugSession::close();
stopMeasures(); stopMeasures();
printMeasures(); printMeasures();

View File

@ -777,6 +777,7 @@ string Net::_getString() const
{ {
string bs = Inherit::_getString(); string bs = Inherit::_getString();
string ds = "\"" + getString(_name) + "\" "; string ds = "\"" + getString(_name) + "\" ";
ds += ((isDeepNet() ) ? "d" : "-");
ds += ((_isExternal ) ? "e" : "-"); ds += ((_isExternal ) ? "e" : "-");
ds += ((_isGlobal ) ? "g" : "-"); ds += ((_isGlobal ) ? "g" : "-");
ds += ((_isAutomatic) ? "a" : "-"); ds += ((_isAutomatic) ? "a" : "-");