mirror of https://github.com/YosysHQ/abc.git
Esperiments with MO PLA optimization.
This commit is contained in:
parent
d7d1978e42
commit
eb270018b9
|
|
@ -258,6 +258,7 @@ static inline int Abc_NtkHasBlifMv( Abc_Ntk_t * pNtk ) { return pN
|
|||
static inline int Abc_NtkHasBlackbox( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_BLACKBOX; }
|
||||
|
||||
static inline int Abc_NtkIsSopNetlist( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_SOP && pNtk->ntkType == ABC_NTK_NETLIST; }
|
||||
static inline int Abc_NtkIsBddNetlist( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_BDD && pNtk->ntkType == ABC_NTK_NETLIST; }
|
||||
static inline int Abc_NtkIsAigNetlist( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_AIG && pNtk->ntkType == ABC_NTK_NETLIST; }
|
||||
static inline int Abc_NtkIsMappedNetlist( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_MAP && pNtk->ntkType == ABC_NTK_NETLIST; }
|
||||
static inline int Abc_NtkIsBlifMvNetlist( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_BLIFMV && pNtk->ntkType == ABC_NTK_NETLIST; }
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define ABC_MUX_CUBES 100000
|
||||
#define ABC_MAX_CUBES 100000
|
||||
|
||||
int Abc_ConvertZddToSop( DdManager * dd, DdNode * zCover, char * pSop, int nFanins, Vec_Str_t * vCube, int fPhase );
|
||||
static DdNode * Abc_ConvertAigToBdd( DdManager * dd, Hop_Obj_t * pRoot);
|
||||
|
|
@ -307,10 +307,10 @@ char * Abc_ConvertBddToSop( Mem_Flex_t * pMan, DdManager * dd, DdNode * bFuncOn,
|
|||
assert( 0 );
|
||||
}
|
||||
|
||||
if ( nCubes > ABC_MUX_CUBES )
|
||||
if ( nCubes > ABC_MAX_CUBES )
|
||||
{
|
||||
Cudd_RecursiveDerefZdd( dd, zCover );
|
||||
printf( "The number of cubes exceeded the predefined limit (%d).\n", ABC_MUX_CUBES );
|
||||
printf( "The number of cubes exceeded the predefined limit (%d).\n", ABC_MAX_CUBES );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -571,7 +571,7 @@ void Abc_CountZddCubes_rec( DdManager * dd, DdNode * zCover, int * pnCubes )
|
|||
(*pnCubes)++;
|
||||
return;
|
||||
}
|
||||
if ( (*pnCubes) > ABC_MUX_CUBES )
|
||||
if ( (*pnCubes) > ABC_MAX_CUBES )
|
||||
return;
|
||||
extraDecomposeCover( dd, zCover, &zC0, &zC1, &zC2 );
|
||||
Abc_CountZddCubes_rec( dd, zC0, pnCubes );
|
||||
|
|
|
|||
|
|
@ -2479,13 +2479,16 @@ usage:
|
|||
int IoCommandWritePla( Abc_Frame_t * pAbc, int argc, char **argv )
|
||||
{
|
||||
char * pFileName;
|
||||
int c;
|
||||
int c, fUseMoPla = 0;
|
||||
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "mh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'm':
|
||||
fUseMoPla ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
|
|
@ -2502,12 +2505,13 @@ int IoCommandWritePla( Abc_Frame_t * pAbc, int argc, char **argv )
|
|||
// get the output file name
|
||||
pFileName = argv[globalUtilOptind];
|
||||
// call the corresponding file writer
|
||||
Io_Write( pAbc->pNtkCur, pFileName, IO_FILE_PLA );
|
||||
Io_Write( pAbc->pNtkCur, pFileName, fUseMoPla ? IO_FILE_MOPLA : IO_FILE_PLA );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pAbc->Err, "usage: write_pla [-h] <file>\n" );
|
||||
fprintf( pAbc->Err, "usage: write_pla [-mh] <file>\n" );
|
||||
fprintf( pAbc->Err, "\t writes the collapsed network into a PLA file\n" );
|
||||
fprintf( pAbc->Err, "\t-m : toggle writing multi-output PLA [default = %s]\n", fUseMoPla? "yes":"no" );
|
||||
fprintf( pAbc->Err, "\t-h : print the help massage\n" );
|
||||
fprintf( pAbc->Err, "\tfile : the name of the file to write\n" );
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ typedef enum {
|
|||
IO_FILE_GML,
|
||||
IO_FILE_LIST,
|
||||
IO_FILE_PLA,
|
||||
IO_FILE_MOPLA,
|
||||
IO_FILE_SMV,
|
||||
IO_FILE_VERILOG,
|
||||
IO_FILE_UNKNOWN
|
||||
|
|
@ -128,6 +129,7 @@ extern void Io_WriteGml( Abc_Ntk_t * pNtk, char * pFileName );
|
|||
extern void Io_WriteList( Abc_Ntk_t * pNtk, char * pFileName, int fUseHost );
|
||||
/*=== abcWritePla.c ===========================================================*/
|
||||
extern int Io_WritePla( Abc_Ntk_t * pNtk, char * FileName );
|
||||
extern int Io_WriteMoPla( Abc_Ntk_t * pNtk, char * FileName );
|
||||
/*=== abcWriteSmv.c ===========================================================*/
|
||||
extern int Io_WriteSmv( Abc_Ntk_t * pNtk, char * FileName );
|
||||
/*=== abcWriteVerilog.c =======================================================*/
|
||||
|
|
|
|||
|
|
@ -399,6 +399,10 @@ void Io_Write( Abc_Ntk_t * pNtk, char * pFileName, Io_FileType_t FileType )
|
|||
if ( !Abc_NtkToSop( pNtkTemp, 1 ) )
|
||||
return;
|
||||
}
|
||||
else if ( FileType == IO_FILE_MOPLA )
|
||||
{
|
||||
pNtkTemp = Abc_NtkStrash( pNtk, 0, 0, 0 );
|
||||
}
|
||||
else if ( FileType == IO_FILE_BENCH )
|
||||
{
|
||||
if ( !Abc_NtkIsStrash(pNtk) )
|
||||
|
|
@ -444,6 +448,8 @@ void Io_Write( Abc_Ntk_t * pNtk, char * pFileName, Io_FileType_t FileType )
|
|||
Io_WriteBook( pNtkTemp, pFileName );
|
||||
else if ( FileType == IO_FILE_PLA )
|
||||
Io_WritePla( pNtkTemp, pFileName );
|
||||
else if ( FileType == IO_FILE_MOPLA )
|
||||
Io_WriteMoPla( pNtkTemp, pFileName );
|
||||
else if ( FileType == IO_FILE_EQN )
|
||||
{
|
||||
if ( !Abc_NtkHasAig(pNtkTemp) )
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
***********************************************************************/
|
||||
|
||||
#include "ioAbc.h"
|
||||
#include "misc/extra/extraBdd.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -27,49 +28,10 @@ ABC_NAMESPACE_IMPL_START
|
|||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int Io_WritePlaOne( FILE * pFile, Abc_Ntk_t * pNtk );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Writes the network in PLA format.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Io_WritePla( Abc_Ntk_t * pNtk, char * pFileName )
|
||||
{
|
||||
Abc_Ntk_t * pExdc;
|
||||
FILE * pFile;
|
||||
|
||||
assert( Abc_NtkIsSopNetlist(pNtk) );
|
||||
assert( Abc_NtkLevel(pNtk) == 1 );
|
||||
|
||||
pFile = fopen( pFileName, "w" );
|
||||
if ( pFile == NULL )
|
||||
{
|
||||
fprintf( stdout, "Io_WritePla(): Cannot open the output file.\n" );
|
||||
return 0;
|
||||
}
|
||||
fprintf( pFile, "# Benchmark \"%s\" written by ABC on %s\n", pNtk->pName, Extra_TimeStamp() );
|
||||
// write the network
|
||||
Io_WritePlaOne( pFile, pNtk );
|
||||
// write EXDC network if it exists
|
||||
pExdc = Abc_NtkExdc( pNtk );
|
||||
if ( pExdc )
|
||||
printf( "Io_WritePla: EXDC is not written (warning).\n" );
|
||||
// finalize the file
|
||||
fclose( pFile );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Writes the network in PLA format.]
|
||||
|
|
@ -192,6 +154,292 @@ int Io_WritePlaOne( FILE * pFile, Abc_Ntk_t * pNtk )
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Writes the network in PLA format.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Io_WritePla( Abc_Ntk_t * pNtk, char * pFileName )
|
||||
{
|
||||
Abc_Ntk_t * pExdc;
|
||||
FILE * pFile;
|
||||
|
||||
assert( Abc_NtkIsSopNetlist(pNtk) );
|
||||
assert( Abc_NtkLevel(pNtk) == 1 );
|
||||
|
||||
pFile = fopen( pFileName, "w" );
|
||||
if ( pFile == NULL )
|
||||
{
|
||||
fprintf( stdout, "Io_WritePla(): Cannot open the output file.\n" );
|
||||
return 0;
|
||||
}
|
||||
fprintf( pFile, "# Benchmark \"%s\" written by ABC on %s\n", pNtk->pName, Extra_TimeStamp() );
|
||||
// write the network
|
||||
Io_WritePlaOne( pFile, pNtk );
|
||||
// write EXDC network if it exists
|
||||
pExdc = Abc_NtkExdc( pNtk );
|
||||
if ( pExdc )
|
||||
printf( "Io_WritePla: EXDC is not written (warning).\n" );
|
||||
// finalize the file
|
||||
fclose( pFile );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Writes the network in PLA format.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Io_WriteMoPlaOneInt( FILE * pFile, Abc_Ntk_t * pNtk, DdManager * dd, Vec_Ptr_t * vFuncs )
|
||||
{
|
||||
Abc_Obj_t * pNode;
|
||||
DdNode * bOnset, * bOffset, * bCube, * bFunc, * bTemp, * zCover;
|
||||
int i, k, nInputs, nOutputs;
|
||||
int nCubes, fPhase;
|
||||
|
||||
assert( Vec_PtrSize(vFuncs) == Abc_NtkCoNum(pNtk) );
|
||||
assert( dd->size == Abc_NtkCiNum(pNtk) );
|
||||
assert( dd->size <= 1000 );
|
||||
|
||||
// collect the parameters
|
||||
nInputs = Abc_NtkCiNum(pNtk);
|
||||
nOutputs = Abc_NtkCoNum(pNtk);
|
||||
assert( nOutputs > 1 );
|
||||
|
||||
// create extra variables
|
||||
for ( i = 0; i < nOutputs; i++ )
|
||||
Cudd_bddNewVarAtLevel( dd, i );
|
||||
assert( dd->size == nInputs + nOutputs );
|
||||
|
||||
// create ON and OFF sets
|
||||
bOnset = Cudd_ReadLogicZero( dd ); Cudd_Ref(bOnset);
|
||||
bOffset = Cudd_ReadLogicZero( dd ); Cudd_Ref(bOffset);
|
||||
for ( i = 0; i < nOutputs; i++ )
|
||||
{
|
||||
bFunc = (DdNode *)Vec_PtrEntry(vFuncs, i);
|
||||
// create onset
|
||||
bCube = Cudd_bddAnd( dd, Cudd_bddIthVar(dd, nInputs+i), bFunc ); Cudd_Ref(bCube);
|
||||
for ( k = 0; k < nOutputs; k++ )
|
||||
if ( k != i )
|
||||
{
|
||||
bCube = Cudd_bddAnd( dd, bTemp = bCube, Cudd_Not(Cudd_bddIthVar(dd, nInputs+k)) ); Cudd_Ref(bCube);
|
||||
Cudd_RecursiveDeref( dd, bTemp );
|
||||
}
|
||||
bOnset = Cudd_bddOr( dd, bTemp = bOnset, bCube ); Cudd_Ref(bOnset);
|
||||
Cudd_RecursiveDeref( dd, bTemp );
|
||||
Cudd_RecursiveDeref( dd, bCube );
|
||||
// create offset
|
||||
bCube = Cudd_bddAnd( dd, Cudd_bddIthVar(dd, nInputs+i), Cudd_Not(bFunc) ); Cudd_Ref(bCube);
|
||||
bOffset = Cudd_bddOr( dd, bTemp = bOffset, bCube ); Cudd_Ref(bOffset);
|
||||
Cudd_RecursiveDeref( dd, bTemp );
|
||||
Cudd_RecursiveDeref( dd, bCube );
|
||||
|
||||
printf( "Trying %d output.\n", i );
|
||||
printf( "Onset = %d nodes.\n", Cudd_DagSize(bOnset) );
|
||||
printf( "Offset = %d nodes.\n", Cudd_DagSize(bOffset) );
|
||||
}
|
||||
|
||||
Cudd_zddVarsFromBddVars( dd, 2 );
|
||||
|
||||
// derive ISOP
|
||||
{
|
||||
extern int Abc_CountZddCubes( DdManager * dd, DdNode * zCover );
|
||||
DdNode * bCover, * zCover0, * zCover1;
|
||||
int nCubes0, nCubes1;
|
||||
// get the ZDD of the negative polarity
|
||||
bCover = Cudd_zddIsop( dd, bOffset, Cudd_Not(bOnset), &zCover0 );
|
||||
Cudd_Ref( zCover0 );
|
||||
Cudd_Ref( bCover );
|
||||
Cudd_RecursiveDeref( dd, bCover );
|
||||
nCubes0 = Abc_CountZddCubes( dd, zCover0 );
|
||||
|
||||
// get the ZDD of the positive polarity
|
||||
bCover = Cudd_zddIsop( dd, bOnset, Cudd_Not(bOffset), &zCover1 );
|
||||
Cudd_Ref( zCover1 );
|
||||
Cudd_Ref( bCover );
|
||||
Cudd_RecursiveDeref( dd, bCover );
|
||||
nCubes1 = Abc_CountZddCubes( dd, zCover1 );
|
||||
|
||||
// compare the number of cubes
|
||||
if ( nCubes1 <= nCubes0 )
|
||||
{ // use positive polarity
|
||||
nCubes = nCubes1;
|
||||
zCover = zCover1;
|
||||
Cudd_RecursiveDerefZdd( dd, zCover0 );
|
||||
fPhase = 1;
|
||||
}
|
||||
else
|
||||
{ // use negative polarity
|
||||
nCubes = nCubes0;
|
||||
zCover = zCover0;
|
||||
Cudd_RecursiveDerefZdd( dd, zCover1 );
|
||||
fPhase = 0;
|
||||
}
|
||||
}
|
||||
Cudd_RecursiveDeref( dd, bOnset );
|
||||
Cudd_RecursiveDeref( dd, bOffset );
|
||||
Cudd_RecursiveDerefZdd( dd, zCover );
|
||||
printf( "Cover = %d nodes.\n", Cudd_DagSize(zCover) );
|
||||
printf( "ISOP = %d\n", nCubes );
|
||||
|
||||
// write the header
|
||||
fprintf( pFile, ".i %d\n", nInputs );
|
||||
fprintf( pFile, ".o %d\n", nOutputs );
|
||||
fprintf( pFile, ".ilb" );
|
||||
Abc_NtkForEachCi( pNtk, pNode, i )
|
||||
fprintf( pFile, " %s", Abc_ObjName(pNode) );
|
||||
fprintf( pFile, "\n" );
|
||||
fprintf( pFile, ".ob" );
|
||||
Abc_NtkForEachCo( pNtk, pNode, i )
|
||||
fprintf( pFile, " %s", Abc_ObjName(pNode) );
|
||||
fprintf( pFile, "\n" );
|
||||
fprintf( pFile, ".p %d\n", nCubes );
|
||||
|
||||
|
||||
fprintf( pFile, ".e\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Writes the network in PLA format.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Io_WriteMoPlaOneIntMinterms( FILE * pFile, Abc_Ntk_t * pNtk, DdManager * dd, Vec_Ptr_t * vFuncs )
|
||||
{
|
||||
int pValues[1000];
|
||||
Abc_Obj_t * pNode;
|
||||
int i, k, nProducts, nInputs, nOutputs;
|
||||
assert( Vec_PtrSize(vFuncs) == Abc_NtkCoNum(pNtk) );
|
||||
assert( dd->size == Abc_NtkCiNum(pNtk) );
|
||||
assert( dd->size <= 1000 );
|
||||
|
||||
// collect the parameters
|
||||
nInputs = Abc_NtkCiNum(pNtk);
|
||||
nOutputs = Abc_NtkCoNum(pNtk);
|
||||
nProducts = (1 << nInputs);
|
||||
|
||||
// write the header
|
||||
fprintf( pFile, ".i %d\n", nInputs );
|
||||
fprintf( pFile, ".o %d\n", nOutputs );
|
||||
fprintf( pFile, ".ilb" );
|
||||
Abc_NtkForEachCi( pNtk, pNode, i )
|
||||
fprintf( pFile, " %s", Abc_ObjName(pNode) );
|
||||
fprintf( pFile, "\n" );
|
||||
fprintf( pFile, ".ob" );
|
||||
Abc_NtkForEachCo( pNtk, pNode, i )
|
||||
fprintf( pFile, " %s", Abc_ObjName(pNode) );
|
||||
fprintf( pFile, "\n" );
|
||||
fprintf( pFile, ".p %d\n", nProducts );
|
||||
|
||||
// iterate through minterms
|
||||
for ( k = 0; k < nProducts; k++ )
|
||||
{
|
||||
for ( i = 0; i < nInputs; i++ )
|
||||
fprintf( pFile, "%c", '0' + (pValues[i] = ((k >> i) & 1)) );
|
||||
fprintf( pFile, " " );
|
||||
for ( i = 0; i < nOutputs; i++ )
|
||||
fprintf( pFile, "%c", '0' + (Cudd_ReadOne(dd) == Cudd_Eval(dd, (DdNode *)Vec_PtrEntry(vFuncs, i), pValues)) );
|
||||
fprintf( pFile, "\n" );
|
||||
}
|
||||
|
||||
fprintf( pFile, ".e\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Writes the network in PLA format.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Io_WriteMoPlaOne( FILE * pFile, Abc_Ntk_t * pNtk )
|
||||
{
|
||||
int fVerbose = 1;
|
||||
DdManager * dd;
|
||||
DdNode * bFunc;
|
||||
Vec_Ptr_t * vFuncsGlob;
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
assert( Abc_NtkIsStrash(pNtk) );
|
||||
dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, 1, fVerbose );
|
||||
if ( dd == NULL )
|
||||
return 0;
|
||||
if ( fVerbose )
|
||||
printf( "Shared BDD size = %6d nodes.\n", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) );
|
||||
|
||||
// complement the global functions
|
||||
vFuncsGlob = Vec_PtrAlloc( Abc_NtkCoNum(pNtk) );
|
||||
Abc_NtkForEachCo( pNtk, pObj, i )
|
||||
Vec_PtrPush( vFuncsGlob, Abc_ObjGlobalBdd(pObj) );
|
||||
|
||||
// consider minterms
|
||||
Io_WriteMoPlaOneIntMinterms( pFile, pNtk, dd, vFuncsGlob );
|
||||
Abc_NtkFreeGlobalBdds( pNtk, 0 );
|
||||
|
||||
// cleanup
|
||||
Vec_PtrForEachEntry( DdNode *, vFuncsGlob, bFunc, i )
|
||||
Cudd_RecursiveDeref( dd, bFunc );
|
||||
Vec_PtrFree( vFuncsGlob );
|
||||
Extra_StopManager( dd );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Writes the network in PLA format.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Io_WriteMoPla( Abc_Ntk_t * pNtk, char * pFileName )
|
||||
{
|
||||
FILE * pFile;
|
||||
assert( Abc_NtkIsStrash(pNtk) );
|
||||
if ( Abc_NtkCiNum(pNtk) > 16 )
|
||||
{
|
||||
printf( "Cannot write multi-output PLA for more than 16 inputs.\n" );
|
||||
return 0;
|
||||
}
|
||||
pFile = fopen( pFileName, "w" );
|
||||
if ( pFile == NULL )
|
||||
{
|
||||
fprintf( stdout, "Io_WritePla(): Cannot open the output file.\n" );
|
||||
return 0;
|
||||
}
|
||||
fprintf( pFile, "# Benchmark \"%s\" written by ABC on %s\n", pNtk->pName, Extra_TimeStamp() );
|
||||
Io_WriteMoPlaOne( pFile, pNtk );
|
||||
fclose( pFile );
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
|
|
|
|||
Loading…
Reference in New Issue