From 8279e76070fb81a58f2c3b03643e6a68a73daf0e Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Fri, 16 Apr 2021 00:05:04 +0200 Subject: [PATCH] In Etesian, set correct direction for buffereds HFNS nets. * Bug: In Etesian::HFNS::Cluster, all the created nets were systematically created in the IN direction, which is obviously wrong for the driver. Now Slice::raddTransPlug() accept a third argument stating if we are creating a driver or a sink. Direction of the net is now combining and can be IN, OUT or sometimes INOUT. The VHDL files where reflecting that problem and made GHDL choke. * Change: In Etesian::HFNS::Cluster, prefix the instance name by "cmpt_" so it doesn't clash with the signal name in VHDL. --- etesian/src/HFNS.cpp | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/etesian/src/HFNS.cpp b/etesian/src/HFNS.cpp index 88ce5217..47a0ec1b 100644 --- a/etesian/src/HFNS.cpp +++ b/etesian/src/HFNS.cpp @@ -59,6 +59,9 @@ namespace Etesian { // Class : "::Cluster". class Cluster { + public: + const uint32_t AS_DRIVER = (1<<0); + const uint32_t AS_SINK = (1<<1); public: Cluster ( EtesianEngine* ); virtual ~Cluster (); @@ -72,8 +75,8 @@ namespace Etesian { inline void swapRps ( Cluster* ); inline Net* getInputNet (); inline Net* getOutputNet (); - Plug* raddTransPlug ( Net* topNet, Path ); - Net* raddTransNet ( Net* topNet, Path ); + Plug* raddTransPlug ( Net* topNet, Path, uint32_t flags ); + Net* raddTransNet ( Net* topNet, Path, uint32_t flags ); Plug* getPlugByNet ( Instance* instance, Net* cellNet ); void createInput ( Net* ); void createOutput (); @@ -143,7 +146,7 @@ namespace Etesian { } - Plug* Cluster::raddTransPlug ( Net* topNet, Path path ) + Plug* Cluster::raddTransPlug ( Net* topNet, Path path, uint32_t flags ) { if (path.isEmpty()) return NULL; if (topNet->getCell() != path.getOwnerCell() ) { @@ -166,9 +169,12 @@ namespace Etesian { if (not masterNet) { masterNet = Net::create( masterCell, topNet->getName() ); masterNet->setType ( topNet->getType() ); - masterNet->setDirection( Net::Direction::IN ); } - + uint32_t direction = masterNet->getDirection(); + if (flags & AS_DRIVER) direction |= Net::Direction::OUT; + if (flags & AS_SINK ) direction |= Net::Direction::IN; + masterNet->setDirection( (Net::Direction::Code)direction ); + masterNet->setExternal( true ); headPlug = headInstance->getPlug( masterNet ); if (not headPlug) @@ -182,16 +188,16 @@ namespace Etesian { } if (not tailPath.isEmpty()) - headPlug = raddTransPlug( masterNet, tailPath ); + headPlug = raddTransPlug( masterNet, tailPath, flags ); return headPlug; } - Net* Cluster::raddTransNet ( Net* topNet, Path path ) + Net* Cluster::raddTransNet ( Net* topNet, Path path, uint32_t flags ) { if (path.isEmpty()) return topNet; - return raddTransPlug( topNet, path )->getMasterNet(); + return raddTransPlug( topNet, path, flags )->getMasterNet(); } @@ -206,7 +212,7 @@ namespace Etesian { if (topCell != cellPnR) { inputPath = Path( instancePnR ); - blockNet = raddTransNet( upDriver, inputPath ); + blockNet = raddTransNet( upDriver, inputPath, AS_SINK ); } Plug* inputPlug = bufferDatas->getInput( _buffer ); inputPlug->setNet( blockNet ); @@ -224,14 +230,16 @@ namespace Etesian { Net* blockNet = NULL; Path outputPath = Path(); + driverName.insert( 0, "cmpt_" ); _buffer = Instance::create( cellPnR, driverName, bufferDatas->getCell() ); getSubNetNames()->nextSubNet(); _driverNet = Net::create( topCell, driverName ); + _driverNet->setDirection( Net::Direction::OUT ); if (topCell == cellPnR) blockNet = _driverNet; else { outputPath = Path( instancePnR ); - blockNet = raddTransNet( _driverNet, outputPath ); + blockNet = raddTransNet( _driverNet, outputPath, AS_DRIVER ); } Plug* outputPlug = bufferDatas->getOutput( _buffer ); outputPlug->setNet( blockNet ); @@ -247,7 +255,7 @@ namespace Etesian { } for ( RoutingPad* rp : _rps ) { Occurrence plugOcc = rp->getPlugOccurrence(); - Net* deepNet = raddTransNet( _driverNet, plugOcc.getPath() ); + Net* deepNet = raddTransNet( _driverNet, plugOcc.getPath(), AS_SINK ); if (dynamic_cast(plugOcc.getEntity())) { continue; } @@ -333,7 +341,7 @@ namespace Etesian { Occurrence driverRpOcc = _rpDriver->getPlugOccurrence(); _rootNet->destroy(); _rootNet = Net::create( topCell, topNetName ); - Net* deepDriverNet = raddTransNet( _rootNet, driverRpOcc.getPath() ); + Net* deepDriverNet = raddTransNet( _rootNet, driverRpOcc.getPath(), AS_DRIVER ); dynamic_cast( driverRpOcc.getEntity() )->setNet( deepDriverNet ); RoutingPad::create( _rootNet, driverRpOcc, RoutingPad::BiggestArea ); }