mirror of https://github.com/YosysHQ/abc.git
Added printout of library cells.
This commit is contained in:
parent
a6bfd49591
commit
7772a4af05
|
|
@ -2369,6 +2369,10 @@ SOURCE=.\src\map\scl\sclSize.c
|
|||
|
||||
SOURCE=.\src\map\scl\sclTime.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\map\scl\sclUtil.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Group
|
||||
# Begin Group "misc"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
SRC += src/map/scl/scl.c \
|
||||
src/map/scl/sclFile.c \
|
||||
src/map/scl/sclSize.c \
|
||||
src/map/scl/sclTime.c
|
||||
src/map/scl/sclTime.c \
|
||||
src/map/scl/sclUtil.c
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
|
||||
static int Scl_CommandRead ( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
static int Scl_CommandWrite( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
static int Scl_CommandPrint( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
static int Scl_CommandStime( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
static int Scl_CommandGsize( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
|
||||
|
|
@ -51,6 +52,7 @@ void Scl_Init( Abc_Frame_t * pAbc )
|
|||
{
|
||||
Cmd_CommandAdd( pAbc, "SC mapping", "read_scl", Scl_CommandRead, 0 );
|
||||
Cmd_CommandAdd( pAbc, "SC mapping", "write_scl", Scl_CommandWrite, 0 );
|
||||
Cmd_CommandAdd( pAbc, "SC mapping", "print_scl", Scl_CommandPrint, 0 );
|
||||
Cmd_CommandAdd( pAbc, "SC mapping", "stime", Scl_CommandStime, 0 );
|
||||
Cmd_CommandAdd( pAbc, "SC mapping", "gsize", Scl_CommandGsize, 1 );
|
||||
}
|
||||
|
|
@ -170,6 +172,49 @@ usage:
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Scl_CommandPrint( Abc_Frame_t * pAbc, int argc, char **argv )
|
||||
{
|
||||
int c;
|
||||
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
if ( pAbc->pLibScl == NULL )
|
||||
{
|
||||
fprintf( pAbc->Err, "There is no Liberty library available.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
// save current library
|
||||
Abc_SclPrintCells( pAbc->pLibScl );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pAbc->Err, "usage: print_scl [-h]\n" );
|
||||
fprintf( pAbc->Err, "\t prints statistics of Liberty library\n" );
|
||||
fprintf( pAbc->Err, "\t-h : print the help massage\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
|
|||
|
|
@ -146,53 +146,6 @@ static inline char Vec_StrGetC( Vec_Str_t * vOut, int * pPos )
|
|||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Reading library from file.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static unsigned Abc_SclHashString( char * pName, int TableSize )
|
||||
{
|
||||
static int s_Primes[10] = { 1291, 1699, 2357, 4177, 5147, 5647, 6343, 7103, 7873, 8147 };
|
||||
unsigned i, Key = 0;
|
||||
for ( i = 0; pName[i] != '\0'; i++ )
|
||||
Key += s_Primes[i%10]*pName[i]*pName[i];
|
||||
return Key % TableSize;
|
||||
}
|
||||
int * Abc_SclHashLookup( SC_Lib * p, char * pName )
|
||||
{
|
||||
int i;
|
||||
for ( i = Abc_SclHashString(pName, p->nBins); i < p->nBins; i = (i + 1) % p->nBins )
|
||||
if ( p->pBins[i] == -1 || !strcmp(pName, SC_LibCell(p, p->pBins[i])->name) )
|
||||
return p->pBins + i;
|
||||
assert( 0 );
|
||||
return NULL;
|
||||
}
|
||||
void Abc_SclHashGates( SC_Lib * p )
|
||||
{
|
||||
SC_Cell * pCell;
|
||||
int i, * pPlace;
|
||||
assert( p->nBins == 0 );
|
||||
p->nBins = Abc_PrimeCudd( 5 * Vec_PtrSize(p->vCells) );
|
||||
p->pBins = ABC_FALLOC( int, p->nBins );
|
||||
Vec_PtrForEachEntry( SC_Cell *, p->vCells, pCell, i )
|
||||
{
|
||||
pPlace = Abc_SclHashLookup( p, pCell->name );
|
||||
assert( *pPlace == -1 );
|
||||
*pPlace = i;
|
||||
}
|
||||
}
|
||||
int Abc_SclCellFind( SC_Lib * p, char * pName )
|
||||
{
|
||||
return *Abc_SclHashLookup( p, pName );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Reading library from file.]
|
||||
|
|
@ -375,7 +328,8 @@ SC_Lib * Abc_SclRead( char * pFileName )
|
|||
assert( Pos == Vec_StrSize(vOut) );
|
||||
Vec_StrFree( vOut );
|
||||
// hash gates by name
|
||||
Abc_SclHashGates( p );
|
||||
Abc_SclHashCells( p );
|
||||
Abc_SclLinkCells( p );
|
||||
return p;
|
||||
}
|
||||
void Abc_SclLoad( char * pFileName, void ** ppScl )
|
||||
|
|
@ -482,12 +436,12 @@ static void Abc_SclWriteLibrary( Vec_Str_t * vOut, SC_Lib * p )
|
|||
|
||||
// Write 'cells' vector:
|
||||
n_valid_cells = 0;
|
||||
Vec_PtrForEachEntry( SC_Cell *, p->vCells, pCell, i )
|
||||
SC_LitForEachCell( p, pCell, i )
|
||||
if ( !(pCell->seq || pCell->unsupp) )
|
||||
n_valid_cells++;
|
||||
|
||||
Vec_StrPutI( vOut, n_valid_cells );
|
||||
Vec_PtrForEachEntry( SC_Cell *, p->vCells, pCell, i )
|
||||
SC_LitForEachCell( p, pCell, i )
|
||||
{
|
||||
if ( pCell->seq || pCell->unsupp )
|
||||
continue;
|
||||
|
|
@ -686,11 +640,11 @@ static void Abc_SclWriteLibraryText( FILE * s, SC_Lib * p )
|
|||
|
||||
// Write 'cells' vector:
|
||||
n_valid_cells = 0;
|
||||
Vec_PtrForEachEntry( SC_Cell *, p->vCells, pCell, i )
|
||||
SC_LitForEachCell( p, pCell, i )
|
||||
if ( !(pCell->seq || pCell->unsupp) )
|
||||
n_valid_cells++;
|
||||
|
||||
Vec_PtrForEachEntry( SC_Cell *, p->vCells, pCell, i )
|
||||
SC_LitForEachCell( p, pCell, i )
|
||||
{
|
||||
if ( pCell->seq || pCell->unsupp )
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -145,6 +145,8 @@ struct SC_Cell_
|
|||
Vec_Ptr_t * vPins; // NamedSet<SC_Pin>
|
||||
int n_inputs; // -- 'pins[0 .. n_inputs-1]' are input pins
|
||||
int n_outputs; // -- 'pins[n_inputs .. n_inputs+n_outputs-1]' are output pins
|
||||
SC_Cell * pNext; // same-functionality cells linked into a ring by area
|
||||
SC_Cell * pPrev; // same-functionality cells linked into a ring by area
|
||||
};
|
||||
|
||||
struct SC_Lib_
|
||||
|
|
@ -160,6 +162,7 @@ struct SC_Lib_
|
|||
Vec_Ptr_t * vWireLoadSels; // NamedSet<SC_WireLoadSel>
|
||||
Vec_Ptr_t * vTempls; // NamedSet<SC_TableTempl>
|
||||
Vec_Ptr_t * vCells; // NamedSet<SC_Cell>
|
||||
Vec_Ptr_t * vCellOrder; // NamedSet<SC_Cell>
|
||||
int * pBins; // hashing gateName -> gateId
|
||||
int nBins;
|
||||
};
|
||||
|
|
@ -172,8 +175,16 @@ struct SC_Lib_
|
|||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline SC_Cell * SC_LibCell( SC_Lib * p, int i ) { return (SC_Cell *)Vec_PtrEntry(p->vCells, i); }
|
||||
static inline SC_Pin * SC_CellPin( SC_Cell * p, int i ) { return (SC_Pin *)Vec_PtrEntry(p->vPins, i); }
|
||||
static inline SC_Cell * SC_LibCell( SC_Lib * p, int i ) { return (SC_Cell *)Vec_PtrEntry(p->vCells, i); }
|
||||
static inline SC_Pin * SC_CellPin( SC_Cell * p, int i ) { return (SC_Pin *)Vec_PtrEntry(p->vPins, i); }
|
||||
static inline Vec_Wrd_t * SC_CellFunc( SC_Cell * p ) { return SC_CellPin(p, p->n_inputs)->vFunc; }
|
||||
|
||||
#define SC_LitForEachCell( p, pCell, i ) Vec_PtrForEachEntry( SC_Cell *, p->vCells, pCell, i )
|
||||
#define SC_CellForEachPin( p, pPin, i ) Vec_PtrForEachEntry( SC_Pin *, pCell->vPins, pPin, i )
|
||||
#define SC_CellForEachPinIn( p, pPin, i ) Vec_PtrForEachEntryStop( SC_Pin *, pCell->vPins, pPin, i, pCell->n_inputs )
|
||||
#define SC_CellForEachPinOut( p, pPin, i ) Vec_PtrForEachEntryStart( SC_Pin *, pCell->vPins, pPin, i, pCell->n_inputs )
|
||||
|
||||
#define SC_RingForEachCell( pRing, pCell, i ) for ( i = 0, pCell = pRing; i == 0 || pCell != pRing; pCell = pCell->pNext, i++ )
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
|
|
@ -258,6 +269,7 @@ static inline SC_Lib * Abc_SclLibAlloc()
|
|||
p->vWireLoadSels = Vec_PtrAlloc( 0 );
|
||||
p->vTempls = Vec_PtrAlloc( 0 );
|
||||
p->vCells = Vec_PtrAlloc( 0 );
|
||||
p->vCellOrder = Vec_PtrAlloc( 0 );
|
||||
return p;
|
||||
}
|
||||
|
||||
|
|
@ -350,9 +362,10 @@ static inline void Abc_SclLibFree( SC_Lib * p )
|
|||
Vec_PtrForEachEntry( SC_TableTempl *, p->vTempls, pTemp3, i )
|
||||
Abc_SclTableTemplFree( pTemp3 );
|
||||
Vec_PtrFree( p->vTempls );
|
||||
Vec_PtrForEachEntry( SC_Cell *, p->vCells, pTemp4, i )
|
||||
SC_LitForEachCell( p, pTemp4, i )
|
||||
Abc_SclCellFree( pTemp4 );
|
||||
Vec_PtrFree( p->vCells );
|
||||
Vec_PtrFree( p->vCellOrder );
|
||||
ABC_FREE( p->lib_name );
|
||||
ABC_FREE( p->default_wire_load );
|
||||
ABC_FREE( p->default_wire_load_sel );
|
||||
|
|
@ -366,8 +379,11 @@ extern SC_Lib * Abc_SclRead( char * pFileName );
|
|||
extern void Abc_SclWrite( char * pFileName, SC_Lib * p );
|
||||
extern void Abc_SclWriteText( char * pFileName, SC_Lib * p );
|
||||
|
||||
/*=== sclUtil.c =============================================================*/
|
||||
extern void Abc_SclHashCells( SC_Lib * p );
|
||||
extern int Abc_SclCellFind( SC_Lib * p, char * pName );
|
||||
|
||||
extern void Abc_SclLinkCells( SC_Lib * p );
|
||||
extern void Abc_SclPrintCells( SC_Lib * p );
|
||||
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
|
|
|||
|
|
@ -0,0 +1,187 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [sclUtil.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
Synopsis [Standard-cell library representation.]
|
||||
|
||||
Author [Alan Mishchenko, Niklas Een]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - August 24, 2012.]
|
||||
|
||||
Revision [$Id: sclUtil.c,v 1.0 2012/08/24 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "sclInt.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Reading library from file.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static unsigned Abc_SclHashString( char * pName, int TableSize )
|
||||
{
|
||||
static int s_Primes[10] = { 1291, 1699, 2357, 4177, 5147, 5647, 6343, 7103, 7873, 8147 };
|
||||
unsigned i, Key = 0;
|
||||
for ( i = 0; pName[i] != '\0'; i++ )
|
||||
Key += s_Primes[i%10]*pName[i]*pName[i];
|
||||
return Key % TableSize;
|
||||
}
|
||||
int * Abc_SclHashLookup( SC_Lib * p, char * pName )
|
||||
{
|
||||
int i;
|
||||
for ( i = Abc_SclHashString(pName, p->nBins); i < p->nBins; i = (i + 1) % p->nBins )
|
||||
if ( p->pBins[i] == -1 || !strcmp(pName, SC_LibCell(p, p->pBins[i])->name) )
|
||||
return p->pBins + i;
|
||||
assert( 0 );
|
||||
return NULL;
|
||||
}
|
||||
void Abc_SclHashCells( SC_Lib * p )
|
||||
{
|
||||
SC_Cell * pCell;
|
||||
int i, * pPlace;
|
||||
assert( p->nBins == 0 );
|
||||
p->nBins = Abc_PrimeCudd( 5 * Vec_PtrSize(p->vCells) );
|
||||
p->pBins = ABC_FALLOC( int, p->nBins );
|
||||
SC_LitForEachCell( p, pCell, i )
|
||||
{
|
||||
pPlace = Abc_SclHashLookup( p, pCell->name );
|
||||
assert( *pPlace == -1 );
|
||||
*pPlace = i;
|
||||
}
|
||||
}
|
||||
int Abc_SclCellFind( SC_Lib * p, char * pName )
|
||||
{
|
||||
return *Abc_SclHashLookup( p, pName );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Links equal gates into rings while sorting them by area.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static int Abc_SclCompareCells( SC_Cell ** pp1, SC_Cell ** pp2 )
|
||||
{
|
||||
if ( (*pp1)->n_inputs < (*pp2)->n_inputs )
|
||||
return -1;
|
||||
if ( (*pp1)->n_inputs > (*pp2)->n_inputs )
|
||||
return 1;
|
||||
if ( (*pp1)->area < (*pp2)->area )
|
||||
return -1;
|
||||
if ( (*pp1)->area > (*pp2)->area )
|
||||
return 1;
|
||||
return strcmp( (*pp1)->name, (*pp2)->name );
|
||||
}
|
||||
void Abc_SclLinkCells( SC_Lib * p )
|
||||
{
|
||||
SC_Cell * pCell, * pRepr;
|
||||
int i, k;
|
||||
assert( Vec_PtrSize(p->vCellOrder) == 0 );
|
||||
SC_LitForEachCell( p, pCell, i )
|
||||
{
|
||||
// find gate with the same function
|
||||
Vec_PtrForEachEntry( SC_Cell *, p->vCellOrder, pRepr, k )
|
||||
if ( pCell->n_inputs == pRepr->n_inputs &&
|
||||
pCell->n_outputs == pRepr->n_outputs &&
|
||||
Vec_WrdEqual(SC_CellFunc(pCell), SC_CellFunc(pRepr)) )
|
||||
break;
|
||||
if ( k == Vec_PtrSize(p->vCellOrder) )
|
||||
{
|
||||
Vec_PtrPush( p->vCellOrder, pCell );
|
||||
pCell->pNext = pCell->pPrev = pCell;
|
||||
continue;
|
||||
}
|
||||
// add it to the list before the cell
|
||||
pRepr->pPrev->pNext = pCell; pCell->pNext = pRepr;
|
||||
pCell->pPrev = pRepr->pPrev; pRepr->pPrev = pCell;
|
||||
}
|
||||
// sort cells by size the then by name
|
||||
qsort( (void *)Vec_PtrArray(p->vCellOrder), Vec_PtrSize(p->vCellOrder), sizeof(void *), (int(*)(const void *,const void *))Abc_SclCompareCells );
|
||||
// sort cell lists
|
||||
Vec_PtrForEachEntry( SC_Cell *, p->vCellOrder, pRepr, k )
|
||||
{
|
||||
Vec_Ptr_t * vList = Vec_PtrAlloc( 100 );
|
||||
SC_RingForEachCell( pRepr, pCell, i )
|
||||
Vec_PtrPush( vList, pCell );
|
||||
qsort( (void *)Vec_PtrArray(vList), Vec_PtrSize(vList), sizeof(void *), (int(*)(const void *,const void *))Abc_SclCompareCells );
|
||||
// create new representative
|
||||
pRepr = Vec_PtrEntry( vList, 0 );
|
||||
pRepr->pNext = pRepr->pPrev = pRepr;
|
||||
// relink cells
|
||||
Vec_PtrForEachEntryStart( SC_Cell *, vList, pCell, i, 1 )
|
||||
{
|
||||
pRepr->pPrev->pNext = pCell; pCell->pNext = pRepr;
|
||||
pCell->pPrev = pRepr->pPrev; pRepr->pPrev = pCell;
|
||||
}
|
||||
// update list
|
||||
Vec_PtrWriteEntry( p->vCellOrder, k, pRepr );
|
||||
Vec_PtrFree( vList );
|
||||
}
|
||||
}
|
||||
void Abc_SclPrintCells( SC_Lib * p )
|
||||
{
|
||||
extern void Kit_DsdPrintFromTruth( unsigned * pTruth, int nVars );
|
||||
SC_Cell * pCell, * pRepr;
|
||||
int i, k;
|
||||
assert( Vec_PtrSize(p->vCellOrder) > 0 );
|
||||
printf( "Library \"%s\" ", p->lib_name );
|
||||
printf( "containing %d cells in %d classes.\n",
|
||||
Vec_PtrSize(p->vCells), Vec_PtrSize(p->vCellOrder) );
|
||||
Vec_PtrForEachEntry( SC_Cell *, p->vCellOrder, pRepr, k )
|
||||
{
|
||||
printf( "Class%3d : ", k );
|
||||
printf( "Ins = %d ", pRepr->n_inputs );
|
||||
printf( "Outs = %d", pRepr->n_outputs );
|
||||
for ( i = 0; i < pRepr->n_outputs; i++ )
|
||||
{
|
||||
printf( " " );
|
||||
Kit_DsdPrintFromTruth( (unsigned *)Vec_WrdArray(SC_CellPin(pRepr, pRepr->n_inputs+i)->vFunc), pRepr->n_inputs );
|
||||
}
|
||||
printf( "\n" );
|
||||
SC_RingForEachCell( pRepr, pCell, i )
|
||||
{
|
||||
printf( " %3d : ", i+1 );
|
||||
printf( "%-12s ", pCell->name );
|
||||
printf( "%2d ", pCell->drive_strength );
|
||||
printf( "A =%8.3f", pCell->area );
|
||||
printf( "\n" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
@ -945,6 +945,28 @@ static inline word Vec_WrdSum( Vec_Wrd_t * p )
|
|||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks if two vectors are equal.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Vec_WrdEqual( Vec_Wrd_t * p1, Vec_Wrd_t * p2 )
|
||||
{
|
||||
int i;
|
||||
if ( p1->nSize != p2->nSize )
|
||||
return 0;
|
||||
for ( i = 0; i < p1->nSize; i++ )
|
||||
if ( p1->pArray[i] != p2->pArray[i] )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Counts the number of common entries.]
|
||||
|
|
|
|||
Loading…
Reference in New Issue