Added Net direction checker/setter in CRL Core.

* New: CRL::restoreNetsdirection() (in ToolBox) that checks the coherency
    of all Nets direction through a complete hierarchy of cells.
      Stops at Cells flagged "TerminalNetlist".
      Directions are rebuilt for all the Cells part of the hierarchy
    in a bottom up fashion. It is also checked that Nets have only one
    driver (we assume there is no three-state busses).
      To sort cells in hierarchical order (bottom up according to their
    depth), copy the DepthOrder class from the GDSII driver. Will unify
    them later.
      exported to the Python interface.
* New: In cumulus/tools/blif2vst.py, add a call to restoreNetsdirection()
    before saving.
This commit is contained in:
Jean-Paul Chaput 2021-03-15 23:57:15 +01:00
parent 11390867f1
commit 1b5327313a
7 changed files with 220 additions and 50 deletions

View File

@ -553,7 +553,8 @@ namespace {
net->setDirection( (Net::Direction::Code)direction ); net->setDirection( (Net::Direction::Code)direction );
if (isClock) net->setType( Net::Type::CLOCK ); if (isClock) net->setType( Net::Type::CLOCK );
if (_cell->getName() == "sm0") cerr << "sm0 netPlug:" << name << endl; // if (_cell->getName() == "ALU_dec19")
// cerr << "ALU_dec19 net create:" << direction << " " << net << endl;
} else { } else {
net->addAlias( name ); net->addAlias( name );
if (isExternal) net->setExternal( true ); if (isExternal) net->setExternal( true );
@ -562,7 +563,8 @@ namespace {
net->setDirection( (Net::Direction::Code)direction ); net->setDirection( (Net::Direction::Code)direction );
if (isClock) net->setType( Net::Type::CLOCK ); if (isClock) net->setType( Net::Type::CLOCK );
if (_cell->getName() == "sm0") cerr << "sm0 netPlug:" << name << endl; // if (_cell->getName() == "ALU_dec19")
// cerr << "ALU_dec19 net merge:" << direction << " " << net << endl;
} }
return net; return net;
} }

View File

@ -14,9 +14,7 @@
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
#ifndef CRL_TOOLBOX_H #pragma once
#define CRL_TOOLBOX_H
#include <functional> #include <functional>
#include "hurricane/Cell.h" #include "hurricane/Cell.h"
#include "hurricane/Net.h" #include "hurricane/Net.h"
@ -58,6 +56,7 @@ namespace CRL {
void connectPlugHooks ( Cell* ); void connectPlugHooks ( Cell* );
size_t getInstancesCount ( const Cell* cell ); size_t getInstancesCount ( const Cell* cell );
void setNetsPosition ( Cell* ); void setNetsPosition ( Cell* );
void restoreNetsDirection ( Cell* , Cell::Flags );
class NamingScheme { class NamingScheme {
@ -89,5 +88,3 @@ namespace CRL {
} // CRL namespace. } // CRL namespace.
#endif // CRL_TOOLBOX_H

View File

@ -18,6 +18,7 @@
#include "hurricane/Pin.h" #include "hurricane/Pin.h"
#include "hurricane/Library.h" #include "hurricane/Library.h"
#include "hurricane/Net.h" #include "hurricane/Net.h"
#include "hurricane/HyperNet.h"
#include "hurricane/Cell.h" #include "hurricane/Cell.h"
#include "hurricane/Instance.h" #include "hurricane/Instance.h"
#include "hurricane/Segment.h" #include "hurricane/Segment.h"
@ -26,6 +27,7 @@
#include "hurricane/Warning.h" #include "hurricane/Warning.h"
using namespace Hurricane; using namespace Hurricane;
#include "crlcore/Utilities.h"
#include "crlcore/ToolBox.h" #include "crlcore/ToolBox.h"
@ -54,7 +56,70 @@ namespace {
} }
} // End of anonymous namespace. // -------------------------------------------------------------------
// Class : "::DepthOrder".
class DepthOrder {
private:
typedef map <const Cell*,size_t,Entity::CompareById> CellMap;
typedef pair<const Cell*,size_t> CellDepth;
class CompareDepth {
public:
inline bool operator() ( const CellDepth& lhs, const CellDepth& rhs );
};
public:
DepthOrder ( const Cell*, Cell::Flags stopMask=Cell::Flags::NoFlags );
inline const vector<CellDepth>& getCellDepths () const;
private:
size_t computeDepth ( CellMap&, const Cell* );
private:
Cell::Flags _stopMask;
vector<CellDepth> _cellDepths;
};
inline bool DepthOrder::CompareDepth::operator() ( const CellDepth& lhs, const CellDepth& rhs )
{
if (lhs.second < rhs.second) return true;
if (lhs.second > rhs.second) return false;
return lhs.first->getId() < rhs.first->getId();
}
inline const vector<DepthOrder::CellDepth>& DepthOrder::getCellDepths () const { return _cellDepths; }
DepthOrder::DepthOrder ( const Cell* top, Cell::Flags stopMask )
: _stopMask (stopMask)
, _cellDepths()
{
CellMap cellMap;
computeDepth( cellMap, top );
for ( auto element : cellMap ) _cellDepths.push_back( element );
sort( _cellDepths.begin(), _cellDepths.end(), CompareDepth() );
}
size_t DepthOrder::computeDepth ( CellMap& cellMap, const Cell* cell )
{
auto ielement = cellMap.find( cell );
if (ielement != cellMap.end()) return (*ielement).second;
size_t depth = 0;
for ( const Instance* instance : cell->getInstances() ) {
if (not (instance->getMasterCell()->getFlags() & _stopMask)) {
depth = std::max( depth, computeDepth(cellMap,instance->getMasterCell()) + 1 );
}
}
cellMap.insert( make_pair(cell,depth) );
return depth;
}
} // Anonymous namespace.
namespace CRL { namespace CRL {
@ -562,4 +627,101 @@ void ConnectPlugHooks(Cell* cell)
} }
void _restoreNetsDirection ( Cell* cell )
{
for ( Net* net : cell->getNets() ) {
if (not net->isExternal()) continue;
if (net->isSupply()) continue;
size_t drivers = 0;
size_t sinks = 0;
for ( Plug* plug : net->getPlugs() ) {
Net* masterNet = plug->getMasterNet();
Net::Direction direction = masterNet->getDirection();
if (direction & Net::Direction::DirIn) {
sinks += 1;
} else {
if (direction & Net::Direction::DirOut) {
drivers += 1;
}
}
if ((direction & Net::Direction::INOUT) == Net::Direction::INOUT) {
cparanoid << Warning( "Net \"%s\" of cell \"%s\" has INOUT plug, considered as IN."
, getString(net->getName()).c_str()
, getString(cell->getName()).c_str()
) << endl;
}
}
if ((drivers == 0) and (sinks == 0)) {
cparanoid << Warning( "Net \"%s\" of cell \"%s\" has neither driver nor sink, default as IN."
, getString(net->getName()).c_str()
, getString(cell->getName()).c_str()
) << endl;
net->setDirection( Net::Direction::DirIn );
continue;
}
Net::Direction direction = net->getDirection();
if (drivers == 0) {
if (not (direction & Net::Direction::DirIn)) {
cerr << Warning( "In Cell \"%s\" restoring %s as input (d=%d, s=%d)."
, getString(cell->getName()).c_str()
, getString(net).c_str()
, drivers
, sinks
) << endl;
net->setDirection( Net::Direction::DirIn );
}
continue;
}
if (not (direction & Net::Direction::DirOut)) {
cerr << Warning( "In Cell \"%s\" restoring %s as output (d=%d, s=%d)."
, getString(cell->getName()).c_str()
, getString(net).c_str()
, drivers
, sinks
) << endl;
net->setDirection( Net::Direction::DirOut );
for ( Occurrence occurrence : HyperNet(Occurrence(net)).getComponentOccurrences() ) {
Plug* plug = dynamic_cast<Plug*>( occurrence.getEntity() );
if (plug) {
cerr << " | " << occurrence.getPath().getCompactString(false)
<< "." << plug->getInstance()->getName()
<< ":" << plug->getMasterNet()->getName()
<< " (" << plug->getMasterNet()->getCell()->getName() << ")" << endl;
} else {
cerr << " | " << occurrence << endl;
}
}
}
if (drivers > 1) {
cerr << Warning( "In Cell \"%s\", %s has more than one driver (%d)."
, getString(cell->getName()).c_str()
, getString(net).c_str()
, drivers
) << endl;
for ( Occurrence occurrence : HyperNet(Occurrence(net)).getComponentOccurrences() ) {
Plug* plug = dynamic_cast<Plug*>( occurrence.getEntity() );
if (plug) {
cerr << " | " << occurrence.getPath().getCompactString(false)
<< "." << plug->getInstance()->getName()
<< ":" << plug->getMasterNet()->getName()
<< " (" << plug->getMasterNet()->getCell()->getName() << ")" << endl;
} else {
cerr << " | " << occurrence << endl;
}
}
}
}
}
void restoreNetsDirection ( Cell* topCell, Cell::Flags mask )
{
DepthOrder cellOrder ( topCell, mask );
for ( auto item : cellOrder.getCellDepths() ) {
_restoreNetsDirection( const_cast<Cell*>( item.first ) );
}
}
} // End of CRL namespace. } // End of CRL namespace.

View File

@ -79,11 +79,9 @@ extern "C" {
static PyObject* PyVhdl_destroyAllVHDL ( PyObject* module ) static PyObject* PyVhdl_destroyAllVHDL ( PyObject* module )
{ {
cdebug_log(30,0) << "PyVhdl_destroyAllVHDL()" << endl; cdebug_log(30,0) << "PyVhdl_destroyAllVHDL()" << endl;
HTRY HTRY
EntityExtension::destroyAll(); EntityExtension::destroyAll();
HCATCH HCATCH
Py_RETURN_NONE; Py_RETURN_NONE;
} }
@ -94,9 +92,11 @@ extern "C" {
static PyMethodDef PyCRL_Methods[] = static PyMethodDef PyCRL_Methods[] =
{ { "createPartRing" , (PyCFunction)PyToolBox_createPartRing, METH_VARARGS { { "createPartRing" , (PyCFunction)PyToolBox_createPartRing , METH_VARARGS
, "Partial build of a ring" } , "Partial build of a ring" }
, { "destroyAllVHDL" , (PyCFunction)PyVhdl_destroyAllVHDL, METH_NOARGS , { "restoreNetsDirection", (PyCFunction)PyToolBox_restoreNetsDirection, METH_VARARGS
, "Compute and set nets direction of a complete cell hierarchy." }
, { "destroyAllVHDL" , (PyCFunction)PyVhdl_destroyAllVHDL , METH_NOARGS
, "Clear all VHDL informations on all cells." } , "Clear all VHDL informations on all cells." }
, {NULL, NULL, 0, NULL} /* sentinel */ , {NULL, NULL, 0, NULL} /* sentinel */
}; };

View File

@ -33,6 +33,7 @@ namespace CRL {
using std::cerr; using std::cerr;
using std::endl; using std::endl;
using std::hex; using std::hex;
using std::string;
using std::ostringstream; using std::ostringstream;
using Hurricane::tab; using Hurricane::tab;
using Hurricane::Exception; using Hurricane::Exception;
@ -45,6 +46,8 @@ namespace CRL {
using Isobar::HurricaneError; using Isobar::HurricaneError;
using Isobar::HurricaneWarning; using Isobar::HurricaneWarning;
using Isobar::getPyHash; using Isobar::getPyHash;
using Isobar::__cs;
using Isobar::Converter;
using Isobar::ParseOneArg; using Isobar::ParseOneArg;
using Isobar::ParseTwoArg; using Isobar::ParseTwoArg;
using Isobar::PyCell; using Isobar::PyCell;
@ -72,21 +75,44 @@ extern "C" {
extern PyObject* PyToolBox_createPartRing ( PyObject* module, PyObject* args ) extern PyObject* PyToolBox_createPartRing ( PyObject* module, PyObject* args )
{ {
cdebug_log(30,0) << "PyToolBox_createPartRing ()" << endl; cdebug_log(30,0) << "PyToolBox_createPartRing ()" << endl;
HTRY HTRY
PyObject* arg0; PyObject* arg0;
PyObject* arg1; PyObject* arg1;
if ( not ParseTwoArg( "CRL.createPartRing", args, CELL_STRING_ARG, &arg0, &arg1 ) )
if ( not ParseTwoArg ( "CRL.createPartRing", args, CELL_STRING_ARG, &arg0, &arg1 ) ) return NULL;
return NULL; createPartRing( PYCELL_O(arg0), PyString_AsString(arg1) );
HCATCH
createPartRing ( PYCELL_O(arg0), PyString_AsString(arg1) );
HCATCH
Py_RETURN_NONE; Py_RETURN_NONE;
} }
extern PyObject* PyToolBox_restoreNetsDirection ( PyObject* module, PyObject* args )
{
cdebug_log(30,0) << "PyToolbox_restoreNetsDirection()" << endl;
HTRY
PyObject* arg0 = NULL;
PyObject* arg1 = NULL;
__cs.init( "CRL.restoreNetsDirection" );
if (not PyArg_ParseTuple(args,"O&O&:CRL.restoreNetsDirection"
,Converter,&arg0
,Converter,&arg1
)) {
PyErr_SetString( ConstructorError, "CRL.restoreNetsDirection(): Takes exactly two parameters." );
return NULL;
}
if (__cs.getObjectIds() == ":ent:int") {
restoreNetsDirection( PYCELL_O(arg0), PyInt_AsLong(arg1) );
} else {
string message = "CRL.restoreNetsDirection(): Bad type of parameter(s), \"" + __cs.getObjectIds() + "\".";
PyErr_SetString( ConstructorError, message.c_str() );
return NULL;
}
HCATCH
Py_RETURN_NONE;
}
#endif // End of Shared Library Code Part. #endif // End of Shared Library Code Part.

View File

@ -2,49 +2,35 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2010-2010, All Rights Reserved // Copyright (c) SU/LIP6 2010-2021, All Rights Reserved
// //
// =================================================================== // +-----------------------------------------------------------------+
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S | // | C O R I O L I S |
// | Alliance / Hurricane Interface | // | Alliance / Hurricane Interface |
// | | // | |
// | Author : Jean-Paul CHAPUT | // | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== | // | =============================================================== |
// | C++ Header : "./PyToolBox.h" | // | C++ Header : "./PyToolBox.h" |
// | *************************************************************** | // +-----------------------------------------------------------------+
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#ifndef __PY_CRL_TOOLBOX__ #pragma once
#define __PY_CRL_TOOLBOX__
#include "hurricane/isobar/PyHurricane.h" #include "hurricane/isobar/PyHurricane.h"
namespace CRL { namespace CRL {
extern "C" { extern "C" {
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Functions & Types exported to "PyCRL.ccp". // Functions & Types exported to "PyCRL.ccp".
extern PyObject* PyToolBox_createPartRing ( PyObject* module, PyObject* args ); extern PyObject* PyToolBox_createPartRing ( PyObject* module, PyObject* args );
extern PyObject* PyToolBox_restoreNetsDirection ( PyObject* module, PyObject* args );
} // End of extern "C". } // End of extern "C".
} // End of CRL namespace. } // End of CRL namespace.
#endif // __PY_CRL_TOOLBOX__

View File

@ -7,16 +7,12 @@ try:
import optparse import optparse
import helpers import helpers
from helpers import showPythonTrace from helpers import showPythonTrace
from helpers.io import ErrorMessage from helpers.io import ErrorMessage, catch
from helpers.io import catch
helpers.loadUserSettings() helpers.loadUserSettings()
import Cfg import Cfg
import Hurricane import Hurricane
from Hurricane import DbU from Hurricane import DbU, UpdateSession, Breakpoint, Transformation, \
from Hurricane import UpdateSession Cell, Instance
from Hurricane import Breakpoint
from Hurricane import Transformation
from Hurricane import Instance
import Viewer import Viewer
import CRL import CRL
import plugins.rsave import plugins.rsave
@ -73,6 +69,7 @@ if __name__ == '__main__':
print ' o Renaming RTLIL anonymous top cell "top" into "%s".' % options.cellName print ' o Renaming RTLIL anonymous top cell "top" into "%s".' % options.cellName
cell.setName( options.cellName ) cell.setName( options.cellName )
renameNMigenUniquify( cell ) renameNMigenUniquify( cell )
CRL.restoreNetsDirection( cell, Cell.Flags_TerminalNetlist )
kw = {} kw = {}
kw['views'] = views kw['views'] = views