From 2efae3507ea9cedc87c6e4f5e85139e3c2fd65f9 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Wed, 25 May 2022 17:09:00 +0200 Subject: [PATCH] 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. --- etesian/src/HFNS.cpp | 42 ++++++++++++++++++++++++++++----- hurricane/src/hurricane/Net.cpp | 1 + 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/etesian/src/HFNS.cpp b/etesian/src/HFNS.cpp index dee8d27b..a6653083 100644 --- a/etesian/src/HFNS.cpp +++ b/etesian/src/HFNS.cpp @@ -38,6 +38,7 @@ namespace Etesian { using Hurricane::tab; using Hurricane::Warning; using Hurricane::Error; + using Hurricane::DebugSession; using Hurricane::Path; using Hurricane::Transformation; using Hurricane::DataBase; @@ -249,6 +250,7 @@ namespace Etesian { void Cluster::splitNet () { + cdebug_log(123,0) << "Cluster::splitNet()" << endl; createOutput(); for ( Cluster* cluster : _clusters ) { cluster->createInput( _driverNet ); @@ -291,10 +293,10 @@ namespace Etesian { virtual void splitNet (); void rpartition (); uint32_t build (); + bool rcleanupNet ( Net* ); string _getTypeName () const; private: SubNetNames _subNetNames; - bool _isDeepNet; Net* _rootNet; RoutingPad* _rpDriver; vector< vector > _clustersStack; @@ -304,7 +306,6 @@ namespace Etesian { BufferTree::BufferTree ( EtesianEngine* etesian, Net* rootNet ) : Cluster(etesian) , _subNetNames () - , _isDeepNet (true) , _rootNet (rootNet) , _rpDriver (NULL) , _clustersStack() @@ -331,14 +332,18 @@ namespace Etesian { void BufferTree::splitNet () { + cdebug_log(123,0) << "BufferTree::splitNet()" << endl; if (not _rpDriver) throw Error( "BufferTree::splitNet(): Missing driver on %s.", getString(_rootNet).c_str() ); + Net* origDriver = _rootNet; + Cluster::splitNet(); - if (_isDeepNet) { + if (_rootNet->isDeepNet()) { Cell* topCell = getEtesian()->getCell(); Name topNetName = _rootNet->getName(); Occurrence driverRpOcc = _rpDriver->getPlugOccurrence(); + origDriver = dynamic_cast( static_cast( _rootNet )->getRootNetOccurrence().getEntity() ); _rootNet->destroy(); _rootNet = Net::create( topCell, topNetName ); Net* deepDriverNet = raddTransNet( _rootNet, driverRpOcc.getPath(), AS_DRIVER ); @@ -346,6 +351,7 @@ namespace Etesian { RoutingPad::create( _rootNet, driverRpOcc, RoutingPad::BiggestArea ); } createInput( _rootNet ); + rcleanupNet( origDriver ); } @@ -361,16 +367,15 @@ namespace Etesian { RoutingPad* rpPin = NULL; for ( RoutingPad* rp : _rootNet->getRoutingPads() ) { Occurrence rpOccurrence = rp->getPlugOccurrence(); - if (rpOccurrence.getPath().isEmpty()) - _isDeepNet = false; Pin* pin = dynamic_cast( rpOccurrence.getEntity() ); if (pin) { if (not rpPin) { if (dynamic_cast( rpOccurrence.getEntity() )) { + cdebug_log(123,0) << "pin: " << rp << endl; rpPin = rp; } } - cdebug_log(123,0) << "Excluded: " << pin << endl; + cdebug_log(123,0) << "Excluded second pin: " << pin << endl; continue; } Plug* rpPlug = dynamic_cast( rpOccurrence.getEntity() ); @@ -383,6 +388,7 @@ namespace Etesian { cdebug_log(123,0) << "merge: " << _clustersStack[0].back()->getSize() << " " << rp << endl; _clustersStack[0].back()->merge( rp ); } else { + cdebug_log(123,0) << "driver: " << rp << endl; _rpDriver = rp; } } @@ -432,6 +438,8 @@ namespace Etesian { uint32_t BufferTree::build () { + DebugSession::open( _rootNet, 120, 130 ); + cdebug_log(123,1) << "BufferTree::build() " << _rootNet << endl; uint32_t bufferCount = 0; rpartition(); for ( vector& clusters : _clustersStack ) { @@ -440,9 +448,29 @@ namespace Etesian { ++bufferCount; } } + cdebug_tabw(123,-1); + DebugSession::close(); return bufferCount; } + + bool BufferTree::rcleanupNet ( Net* net ) + { + if (net->getCell()->isTerminalNetlist() or net->getCell()->isTerminal()) + return false; + vector 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 { return "BufferTree"; } @@ -484,6 +512,7 @@ namespace Etesian { } } + //DebugSession::open( 120, 130 ); UpdateSession::open(); Go::disableAutoMaterialization(); _bufferCount = 0; @@ -508,6 +537,7 @@ namespace Etesian { // } Go::enableAutoMaterialization(); UpdateSession::close(); + //DebugSession::close(); stopMeasures(); printMeasures(); diff --git a/hurricane/src/hurricane/Net.cpp b/hurricane/src/hurricane/Net.cpp index e1e3e033..643cb1ac 100644 --- a/hurricane/src/hurricane/Net.cpp +++ b/hurricane/src/hurricane/Net.cpp @@ -777,6 +777,7 @@ string Net::_getString() const { string bs = Inherit::_getString(); string ds = "\"" + getString(_name) + "\" "; + ds += ((isDeepNet() ) ? "d" : "-"); ds += ((_isExternal ) ? "e" : "-"); ds += ((_isGlobal ) ? "g" : "-"); ds += ((_isAutomatic) ? "a" : "-");