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.
This commit is contained in:
Jean-Paul Chaput 2021-04-16 00:05:04 +02:00
parent 813d0860fd
commit 8279e76070
1 changed files with 20 additions and 12 deletions

View File

@ -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,8 +169,11 @@ 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 );
@ -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<Pin*>(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<Plug*>( driverRpOcc.getEntity() )->setNet( deepDriverNet );
RoutingPad::create( _rootNet, driverRpOcc, RoutingPad::BiggestArea );
}