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:
parent
11390867f1
commit
1b5327313a
|
@ -553,7 +553,8 @@ namespace {
|
|||
net->setDirection( (Net::Direction::Code)direction );
|
||||
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 {
|
||||
net->addAlias( name );
|
||||
if (isExternal) net->setExternal( true );
|
||||
|
@ -562,7 +563,8 @@ namespace {
|
|||
net->setDirection( (Net::Direction::Code)direction );
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -14,9 +14,7 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#ifndef CRL_TOOLBOX_H
|
||||
#define CRL_TOOLBOX_H
|
||||
|
||||
#pragma once
|
||||
#include <functional>
|
||||
#include "hurricane/Cell.h"
|
||||
#include "hurricane/Net.h"
|
||||
|
@ -58,6 +56,7 @@ namespace CRL {
|
|||
void connectPlugHooks ( Cell* );
|
||||
size_t getInstancesCount ( const Cell* cell );
|
||||
void setNetsPosition ( Cell* );
|
||||
void restoreNetsDirection ( Cell* , Cell::Flags );
|
||||
|
||||
|
||||
class NamingScheme {
|
||||
|
@ -89,5 +88,3 @@ namespace CRL {
|
|||
|
||||
|
||||
} // CRL namespace.
|
||||
|
||||
#endif // CRL_TOOLBOX_H
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "hurricane/Pin.h"
|
||||
#include "hurricane/Library.h"
|
||||
#include "hurricane/Net.h"
|
||||
#include "hurricane/HyperNet.h"
|
||||
#include "hurricane/Cell.h"
|
||||
#include "hurricane/Instance.h"
|
||||
#include "hurricane/Segment.h"
|
||||
|
@ -26,6 +27,7 @@
|
|||
#include "hurricane/Warning.h"
|
||||
using namespace Hurricane;
|
||||
|
||||
#include "crlcore/Utilities.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 {
|
||||
|
@ -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.
|
||||
|
|
|
@ -79,11 +79,9 @@ extern "C" {
|
|||
static PyObject* PyVhdl_destroyAllVHDL ( PyObject* module )
|
||||
{
|
||||
cdebug_log(30,0) << "PyVhdl_destroyAllVHDL()" << endl;
|
||||
|
||||
HTRY
|
||||
EntityExtension::destroyAll();
|
||||
HCATCH
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
@ -94,9 +92,11 @@ extern "C" {
|
|||
|
||||
|
||||
static PyMethodDef PyCRL_Methods[] =
|
||||
{ { "createPartRing" , (PyCFunction)PyToolBox_createPartRing, METH_VARARGS
|
||||
{ { "createPartRing" , (PyCFunction)PyToolBox_createPartRing , METH_VARARGS
|
||||
, "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." }
|
||||
, {NULL, NULL, 0, NULL} /* sentinel */
|
||||
};
|
||||
|
|
|
@ -33,6 +33,7 @@ namespace CRL {
|
|||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::hex;
|
||||
using std::string;
|
||||
using std::ostringstream;
|
||||
using Hurricane::tab;
|
||||
using Hurricane::Exception;
|
||||
|
@ -45,6 +46,8 @@ namespace CRL {
|
|||
using Isobar::HurricaneError;
|
||||
using Isobar::HurricaneWarning;
|
||||
using Isobar::getPyHash;
|
||||
using Isobar::__cs;
|
||||
using Isobar::Converter;
|
||||
using Isobar::ParseOneArg;
|
||||
using Isobar::ParseTwoArg;
|
||||
using Isobar::PyCell;
|
||||
|
@ -72,21 +75,44 @@ extern "C" {
|
|||
extern PyObject* PyToolBox_createPartRing ( PyObject* module, PyObject* args )
|
||||
{
|
||||
cdebug_log(30,0) << "PyToolBox_createPartRing ()" << endl;
|
||||
|
||||
HTRY
|
||||
PyObject* arg0;
|
||||
PyObject* arg1;
|
||||
|
||||
if ( not ParseTwoArg ( "CRL.createPartRing", args, CELL_STRING_ARG, &arg0, &arg1 ) )
|
||||
return NULL;
|
||||
|
||||
createPartRing ( PYCELL_O(arg0), PyString_AsString(arg1) );
|
||||
HCATCH
|
||||
|
||||
PyObject* arg0;
|
||||
PyObject* arg1;
|
||||
if ( not ParseTwoArg( "CRL.createPartRing", args, CELL_STRING_ARG, &arg0, &arg1 ) )
|
||||
return NULL;
|
||||
createPartRing( PYCELL_O(arg0), PyString_AsString(arg1) );
|
||||
HCATCH
|
||||
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.
|
||||
|
||||
|
||||
|
|
|
@ -2,49 +2,35 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// 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 |
|
||||
// | Alliance / Hurricane Interface |
|
||||
// | |
|
||||
// | Author : Jean-Paul CHAPUT |
|
||||
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
|
||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Header : "./PyToolBox.h" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#ifndef __PY_CRL_TOOLBOX__
|
||||
#define __PY_CRL_TOOLBOX__
|
||||
|
||||
#pragma once
|
||||
#include "hurricane/isobar/PyHurricane.h"
|
||||
|
||||
|
||||
namespace CRL {
|
||||
|
||||
|
||||
extern "C" {
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// 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 CRL namespace.
|
||||
|
||||
|
||||
#endif // __PY_CRL_TOOLBOX__
|
||||
|
|
|
@ -7,16 +7,12 @@ try:
|
|||
import optparse
|
||||
import helpers
|
||||
from helpers import showPythonTrace
|
||||
from helpers.io import ErrorMessage
|
||||
from helpers.io import catch
|
||||
from helpers.io import ErrorMessage, catch
|
||||
helpers.loadUserSettings()
|
||||
import Cfg
|
||||
import Hurricane
|
||||
from Hurricane import DbU
|
||||
from Hurricane import UpdateSession
|
||||
from Hurricane import Breakpoint
|
||||
from Hurricane import Transformation
|
||||
from Hurricane import Instance
|
||||
from Hurricane import DbU, UpdateSession, Breakpoint, Transformation, \
|
||||
Cell, Instance
|
||||
import Viewer
|
||||
import CRL
|
||||
import plugins.rsave
|
||||
|
@ -73,6 +69,7 @@ if __name__ == '__main__':
|
|||
print ' o Renaming RTLIL anonymous top cell "top" into "%s".' % options.cellName
|
||||
cell.setName( options.cellName )
|
||||
renameNMigenUniquify( cell )
|
||||
CRL.restoreNetsDirection( cell, Cell.Flags_TerminalNetlist )
|
||||
|
||||
kw = {}
|
||||
kw['views'] = views
|
||||
|
|
Loading…
Reference in New Issue