mirror of https://github.com/YosysHQ/abc.git
Merged alanmi/abc into default
This commit is contained in:
commit
5af44731bf
2
Makefile
2
Makefile
|
|
@ -22,7 +22,7 @@ MODULES := \
|
|||
src/misc/mem src/misc/bar src/misc/bbl src/misc/parse \
|
||||
src/opt/cut src/opt/fxu src/opt/fxch src/opt/rwr src/opt/mfs src/opt/sim \
|
||||
src/opt/ret src/opt/fret src/opt/res src/opt/lpk src/opt/nwk src/opt/rwt \
|
||||
src/opt/cgt src/opt/csw src/opt/dar src/opt/dau src/opt/sfm \
|
||||
src/opt/cgt src/opt/csw src/opt/dar src/opt/dau src/opt/dsc src/opt/sfm src/opt/sbd \
|
||||
src/sat/bsat src/sat/csat src/sat/msat src/sat/psat src/sat/cnf src/sat/bmc \
|
||||
src/bool/bdc src/bool/deco src/bool/dec src/bool/kit src/bool/lucky \
|
||||
src/bool/rsb src/bool/rpo \
|
||||
|
|
|
|||
68
abclib.dsp
68
abclib.dsp
|
|
@ -807,6 +807,10 @@ SOURCE=.\src\base\wlc\wlcStdin.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\base\wlc\wlcWin.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\base\wlc\wlcWriteVer.c
|
||||
# End Source File
|
||||
# End Group
|
||||
|
|
@ -967,6 +971,10 @@ SOURCE=.\src\base\cba\cbaReadVer.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\base\cba\cbaTypes.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\base\cba\cbaWriteBlif.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
@ -2670,6 +2678,50 @@ SOURCE=.\src\opt\fxch\FxchMan.c
|
|||
SOURCE=.\src\opt\fxch\FxchSCHashTable.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "dsc"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\dsc\dsc.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\dsc\dsc.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "sbd"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\sbd\sbd.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\sbd\sbd.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\sbd\sbdCnf.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\sbd\sbdCore.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\sbd\sbdInt.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\sbd\sbdSat.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\sbd\sbdWin.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Group
|
||||
# Begin Group "map"
|
||||
|
||||
|
|
@ -4525,6 +4577,10 @@ SOURCE=.\src\aig\gia\giaUtil.c
|
|||
|
||||
SOURCE=.\src\aig\miniaig\miniaig.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\miniaig\minilut.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Group
|
||||
# Begin Group "bool"
|
||||
|
|
@ -5359,6 +5415,10 @@ SOURCE=.\src\proof\acec\acec.h
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\proof\acec\acecCl.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\proof\acec\acecCo.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
@ -5383,6 +5443,10 @@ SOURCE=.\src\proof\acec\acecOrder.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\proof\acec\acecPa.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\proof\acec\acecPo.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
@ -5391,6 +5455,10 @@ SOURCE=.\src\proof\acec\acecPolyn.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\proof\acec\acecPool.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\proof\acec\acecRe.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
|
|||
|
|
@ -1382,6 +1382,8 @@ extern Gia_Man_t * Mf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pP
|
|||
/*=== giaMini.c ===========================================================*/
|
||||
extern Gia_Man_t * Gia_ManReadMiniAig( char * pFileName );
|
||||
extern void Gia_ManWriteMiniAig( Gia_Man_t * pGia, char * pFileName );
|
||||
extern Gia_Man_t * Gia_ManReadMiniLut( char * pFileName );
|
||||
extern void Gia_ManWriteMiniLut( Gia_Man_t * pGia, char * pFileName );
|
||||
/*=== giaMuxes.c ===========================================================*/
|
||||
extern void Gia_ManCountMuxXor( Gia_Man_t * p, int * pnMuxes, int * pnXors );
|
||||
extern void Gia_ManPrintMuxStats( Gia_Man_t * p );
|
||||
|
|
|
|||
|
|
@ -19,8 +19,10 @@
|
|||
***********************************************************************/
|
||||
|
||||
#include "gia.h"
|
||||
#include "opt/dau/dau.h"
|
||||
#include "base/main/main.h"
|
||||
#include "aig/miniaig/miniaig.h"
|
||||
#include "aig/miniaig/minilut.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -180,6 +182,186 @@ void Gia_ManWriteMiniAig( Gia_Man_t * pGia, char * pFileName )
|
|||
Mini_AigStop( p );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Converts MiniLUT into GIA.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Gia_Man_t * Gia_ManFromMiniLut( Mini_Lut_t * p )
|
||||
{
|
||||
Gia_Man_t * pGia, * pTemp;
|
||||
Vec_Int_t * vCopies;
|
||||
Vec_Int_t * vCover = Vec_IntAlloc( 1000 );
|
||||
Vec_Int_t * vLits = Vec_IntAlloc( 100 );
|
||||
int i, k, Fan, iGiaLit, nNodes;
|
||||
int LutSize = Abc_MaxInt( 2, Mini_LutSize(p) );
|
||||
assert( LutSize <= 6 );
|
||||
// get the number of nodes
|
||||
nNodes = Mini_LutNodeNum(p);
|
||||
// create ABC network
|
||||
pGia = Gia_ManStart( 3 * nNodes );
|
||||
pGia->pName = Abc_UtilStrsav( "MiniLut" );
|
||||
// create mapping from MiniLUT objects into ABC objects
|
||||
vCopies = Vec_IntAlloc( nNodes );
|
||||
Vec_IntPush( vCopies, 0 );
|
||||
Vec_IntPush( vCopies, 1 );
|
||||
// iterate through the objects
|
||||
Gia_ManHashAlloc( pGia );
|
||||
for ( i = 2; i < nNodes; i++ )
|
||||
{
|
||||
if ( Mini_LutNodeIsPi( p, i ) )
|
||||
iGiaLit = Gia_ManAppendCi(pGia);
|
||||
else if ( Mini_LutNodeIsPo( p, i ) )
|
||||
iGiaLit = Gia_ManAppendCo(pGia, Vec_IntEntry(vCopies, Mini_LutNodeFanin(p, i, 0)));
|
||||
else if ( Mini_LutNodeIsNode( p, i ) )
|
||||
{
|
||||
unsigned * puTruth = Mini_LutNodeTruth( p, i );
|
||||
word Truth = LutSize == 6 ? *(word *)puTruth : ((word)*puTruth << 32) | (word)*puTruth;
|
||||
Vec_IntClear( vLits );
|
||||
Mini_LutForEachFanin( p, i, Fan, k )
|
||||
Vec_IntPush( vLits, Vec_IntEntry(vCopies, Fan) );
|
||||
iGiaLit = Dsm_ManTruthToGia( pGia, &Truth, vLits, vCover );
|
||||
}
|
||||
else assert( 0 );
|
||||
Vec_IntPush( vCopies, iGiaLit );
|
||||
}
|
||||
Vec_IntFree( vCover );
|
||||
Vec_IntFree( vLits );
|
||||
Gia_ManHashStop( pGia );
|
||||
assert( Vec_IntSize(vCopies) == nNodes );
|
||||
Vec_IntFree( vCopies );
|
||||
Gia_ManSetRegNum( pGia, Mini_LutRegNum(p) );
|
||||
pGia = Gia_ManCleanup( pTemp = pGia );
|
||||
Gia_ManStop( pTemp );
|
||||
return pGia;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Converts GIA into MiniLUT.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Mini_Lut_t * Gia_ManToMiniLut( Gia_Man_t * pGia )
|
||||
{
|
||||
Mini_Lut_t * p;
|
||||
Vec_Wrd_t * vTruths;
|
||||
Gia_Obj_t * pObj, * pFanin;
|
||||
int i, k, LutSize, pVars[16];
|
||||
word Truth;
|
||||
assert( Gia_ManHasMapping(pGia) );
|
||||
LutSize = Gia_ManLutSizeMax( pGia );
|
||||
assert( LutSize >= 2 );
|
||||
// create the manager
|
||||
p = Mini_LutStart( LutSize );
|
||||
// create primary inputs
|
||||
Gia_ManFillValue( pGia );
|
||||
Gia_ManForEachCi( pGia, pObj, i )
|
||||
pObj->Value = Mini_LutCreatePi(p);
|
||||
// create internal nodes
|
||||
vTruths = Vec_WrdStart( Gia_ManObjNum(pGia) );
|
||||
Gia_ManForEachLut( pGia, i )
|
||||
{
|
||||
pObj = Gia_ManObj( pGia, i );
|
||||
Gia_LutForEachFaninObj( pGia, i, pFanin, k )
|
||||
pVars[k] = pFanin->Value;
|
||||
Truth = Gia_LutComputeTruth6( pGia, i, vTruths );
|
||||
pObj->Value = Mini_LutCreateNode( p, Gia_ObjLutSize(pGia, i), pVars, (unsigned *)&Truth );
|
||||
}
|
||||
Vec_WrdFree( vTruths );
|
||||
// create primary outputs
|
||||
Gia_ManForEachCo( pGia, pObj, i )
|
||||
{
|
||||
if ( Gia_ObjFanin0(pObj) == Gia_ManConst0(pGia) )
|
||||
pObj->Value = Mini_LutCreatePo( p, Gia_ObjFaninC0(pObj) );
|
||||
else if ( !Gia_ObjFaninC0(pObj) )
|
||||
pObj->Value = Mini_LutCreatePo( p, Gia_ObjFanin0(pObj)->Value );
|
||||
else // add inverter LUT
|
||||
{
|
||||
word TruthInv = ABC_CONST(0x5555555555555555);
|
||||
int Fanin = Gia_ObjFanin0(pObj)->Value;
|
||||
int LutInv = Mini_LutCreateNode( p, 1, &Fanin, (unsigned *)&TruthInv );
|
||||
pObj->Value = Mini_LutCreatePo( p, LutInv );
|
||||
}
|
||||
}
|
||||
// set registers
|
||||
Mini_LutSetRegNum( p, Gia_ManRegNum(pGia) );
|
||||
//Mini_LutPrintStats( p );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Procedures to input/output MiniAIG into/from internal GIA.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_FrameGiaInputMiniLut( Abc_Frame_t * pAbc, void * p )
|
||||
{
|
||||
Gia_Man_t * pGia;
|
||||
if ( pAbc == NULL )
|
||||
printf( "ABC framework is not initialized by calling Abc_Start()\n" );
|
||||
pGia = Gia_ManFromMiniLut( (Mini_Lut_t *)p );
|
||||
Abc_FrameUpdateGia( pAbc, pGia );
|
||||
// Gia_ManDelete( pGia );
|
||||
}
|
||||
void * Abc_FrameGiaOutputMiniLut( Abc_Frame_t * pAbc )
|
||||
{
|
||||
Gia_Man_t * pGia;
|
||||
if ( pAbc == NULL )
|
||||
printf( "ABC framework is not initialized by calling Abc_Start()\n" );
|
||||
pGia = Abc_FrameReadGia( pAbc );
|
||||
if ( pGia == NULL )
|
||||
printf( "Current network in ABC framework is not defined.\n" );
|
||||
return Gia_ManToMiniLut( pGia );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Procedures to read/write GIA to/from MiniAIG file.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Gia_Man_t * Gia_ManReadMiniLut( char * pFileName )
|
||||
{
|
||||
Mini_Lut_t * p = Mini_LutLoad( pFileName );
|
||||
Gia_Man_t * pGia = Gia_ManFromMiniLut( p );
|
||||
ABC_FREE( pGia->pName );
|
||||
pGia->pName = Extra_FileNameGeneric( pFileName );
|
||||
Mini_LutStop( p );
|
||||
return pGia;
|
||||
}
|
||||
void Gia_ManWriteMiniLut( Gia_Man_t * pGia, char * pFileName )
|
||||
{
|
||||
Mini_Lut_t * p = Gia_ManToMiniLut( pGia );
|
||||
Mini_LutDump( p, pFileName );
|
||||
Mini_LutStop( p );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ Gia_Man_t * Gia_ManDupMuxes( Gia_Man_t * p, int Limit )
|
|||
Gia_Obj_t * pObj, * pFan0, * pFan1, * pFanC, * pSiblNew, * pObjNew;
|
||||
int i;
|
||||
assert( p->pMuxes == NULL );
|
||||
assert( Limit >= 1 ); // allows to create AIG with XORs without MUXes
|
||||
assert( Limit >= 0 ); // allows to create AIG with XORs without MUXes
|
||||
ABC_FREE( p->pRefs );
|
||||
Gia_ManCreateRefs( p );
|
||||
// start the new manager
|
||||
|
|
|
|||
|
|
@ -489,7 +489,7 @@ int Sbm_ManTestSat( void * pMan )
|
|||
|
||||
StartSol = Vec_IntSize(p->vSolCuts);
|
||||
// StartSol = 30;
|
||||
while ( fKeepTrying )
|
||||
while ( fKeepTrying && StartSol-fKeepTrying > 0 )
|
||||
{
|
||||
printf( "Trying to find mapping with %d gates.\n", StartSol-fKeepTrying );
|
||||
// for ( i = Vec_IntSize(p->vSolCuts)-5; i < nVars; i++ )
|
||||
|
|
|
|||
|
|
@ -54,6 +54,10 @@ extern void Abc_NtkInputMiniAig( void * pAbc, void * pMiniAig );
|
|||
extern void * Abc_NtkOutputMiniAig( void * pAbc );
|
||||
extern void Abc_NtkSetFlopNum( void * pAbc, int nFlops );
|
||||
|
||||
// procedures to input/output 'mini AIG'
|
||||
extern void Abc_NtkInputMiniLut( void * pAbc, void * pMiniLut );
|
||||
extern void * Abc_NtkOutputMiniLut( void * pAbc );
|
||||
|
||||
// procedures to set CI/CO arrival/required times
|
||||
extern void Abc_NtkSetCiArrivalTime( void * pAbc, int iCi, float Rise, float Fall );
|
||||
extern void Abc_NtkSetCoRequiredTime( void * pAbc, int iCo, float Rise, float Fall );
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ static void Mini_AigPush( Mini_Aig_t * p, int Lit0, int Lit1 )
|
|||
{
|
||||
if ( p->nSize + 2 > p->nCap )
|
||||
{
|
||||
assert( p->nSize < MINI_AIG_NULL/4 );
|
||||
if ( p->nCap < MINI_AIG_START_SIZE )
|
||||
Mini_AigGrow( p, MINI_AIG_START_SIZE );
|
||||
else
|
||||
|
|
|
|||
|
|
@ -0,0 +1,288 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [minilut.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Minimalistic representation of LUT mapped network.]
|
||||
|
||||
Synopsis [External declarations.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - September 29, 2012.]
|
||||
|
||||
Revision [$Id: minilut.h,v 1.00 2012/09/29 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef MINI_LUT__mini_lut_h
|
||||
#define MINI_LUT__mini_lut_h
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
ABC_NAMESPACE_HEADER_START
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define MINI_LUT_NULL (0x7FFFFFFF)
|
||||
#define MINI_LUT_NULL2 (0x7FFFFFFE)
|
||||
#define MINI_LUT_START_SIZE (0x000000FF)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Mini_Lut_t_ Mini_Lut_t;
|
||||
struct Mini_Lut_t_
|
||||
{
|
||||
int nCap;
|
||||
int nSize;
|
||||
int nRegs;
|
||||
int LutSize;
|
||||
int * pArray;
|
||||
unsigned * pTruths;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// memory management
|
||||
#define MINI_LUT_ALLOC(type, num) ((type *) malloc(sizeof(type) * (num)))
|
||||
#define MINI_LUT_CALLOC(type, num) ((type *) calloc((num), sizeof(type)))
|
||||
#define MINI_LUT_FALLOC(type, num) ((type *) memset(malloc(sizeof(type) * (num)), 0xff, sizeof(type) * (num)))
|
||||
#define MINI_LUT_FREE(obj) ((obj) ? (free((char *) (obj)), (obj) = 0) : 0)
|
||||
#define MINI_LUT_REALLOC(type, obj, num) \
|
||||
((obj) ? ((type *) realloc((char *)(obj), sizeof(type) * (num))) : \
|
||||
((type *) malloc(sizeof(type) * (num))))
|
||||
|
||||
// compute truth table size measured in unsigned's
|
||||
static int Mini_LutWordNum( int LutSize )
|
||||
{
|
||||
return LutSize > 5 ? 1 << (LutSize-5) : 1;
|
||||
}
|
||||
|
||||
// internal procedures
|
||||
static void Mini_LutGrow( Mini_Lut_t * p, int nCapMin )
|
||||
{
|
||||
if ( p->nCap >= nCapMin )
|
||||
return;
|
||||
p->pArray = MINI_LUT_REALLOC( int, p->pArray, nCapMin * p->LutSize );
|
||||
p->pTruths = MINI_LUT_REALLOC( unsigned, p->pTruths, nCapMin * Mini_LutWordNum(p->LutSize) );
|
||||
p->nCap = nCapMin;
|
||||
assert( p->pArray );
|
||||
assert( p->pTruths );
|
||||
}
|
||||
static void Mini_LutPush( Mini_Lut_t * p, int nVars, int * pVars, unsigned * pTruth )
|
||||
{
|
||||
int i, nWords = Mini_LutWordNum(p->LutSize);
|
||||
if ( p->nSize == p->nCap )
|
||||
{
|
||||
assert( p->LutSize*p->nSize < MINI_LUT_NULL/2 );
|
||||
if ( p->nCap < MINI_LUT_START_SIZE )
|
||||
Mini_LutGrow( p, MINI_LUT_START_SIZE );
|
||||
else
|
||||
Mini_LutGrow( p, 2 * p->nCap );
|
||||
}
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
p->pArray[p->LutSize * p->nSize + i] = pVars[i];
|
||||
for ( ; i < p->LutSize; i++ )
|
||||
p->pArray[p->LutSize * p->nSize + i] = MINI_LUT_NULL;
|
||||
for ( i = 0; i < nWords; i++ )
|
||||
p->pTruths[nWords * p->nSize + i] = pTruth? pTruth[i] : 0;
|
||||
p->nSize++;
|
||||
}
|
||||
|
||||
// accessing fanins
|
||||
static int Mini_LutNodeFanin( Mini_Lut_t * p, int Id, int k )
|
||||
{
|
||||
assert( Id >= 0 && Id < p->nSize );
|
||||
return p->pArray[p->LutSize*Id+k];
|
||||
}
|
||||
static unsigned * Mini_LutNodeTruth( Mini_Lut_t * p, int Id )
|
||||
{
|
||||
assert( Id >= 0 && Id < p->nSize );
|
||||
return p->pTruths + Id * Mini_LutWordNum(p->LutSize);
|
||||
}
|
||||
|
||||
// working with LUTs
|
||||
static int Mini_LutNodeConst0() { return 0; }
|
||||
static int Mini_LutNodeConst1() { return 1; }
|
||||
|
||||
static int Mini_LutNodeNum( Mini_Lut_t * p ) { return p->nSize; }
|
||||
static int Mini_LutNodeIsConst( Mini_Lut_t * p, int Id ) { assert( Id >= 0 ); return Id == 0 || Id == 1; }
|
||||
static int Mini_LutNodeIsPi( Mini_Lut_t * p, int Id ) { assert( Id >= 0 ); return Id > 0 && Mini_LutNodeFanin( p, Id, 0 ) == MINI_LUT_NULL; }
|
||||
static int Mini_LutNodeIsPo( Mini_Lut_t * p, int Id ) { assert( Id >= 0 ); return Id > 0 && Mini_LutNodeFanin( p, Id, 0 ) != MINI_LUT_NULL && Mini_LutNodeFanin( p, Id, 1 ) == MINI_LUT_NULL2; }
|
||||
static int Mini_LutNodeIsNode( Mini_Lut_t * p, int Id ) { assert( Id >= 0 ); return Id > 0 && Mini_LutNodeFanin( p, Id, 0 ) != MINI_LUT_NULL && Mini_LutNodeFanin( p, Id, 1 ) != MINI_LUT_NULL2; }
|
||||
|
||||
static int Mini_LutSize( Mini_Lut_t * p ) { return p->LutSize; }
|
||||
|
||||
// working with sequential AIGs
|
||||
static int Mini_LutRegNum( Mini_Lut_t * p ) { return p->nRegs; }
|
||||
static void Mini_LutSetRegNum( Mini_Lut_t * p, int n ) { p->nRegs = n; }
|
||||
|
||||
// iterators through objects
|
||||
#define Mini_LutForEachPi( p, i ) for (i = 2; i < Mini_LutNodeNum(p); i++) if ( !Mini_LutNodeIsPi(p, i) ) {} else
|
||||
#define Mini_LutForEachPo( p, i ) for (i = 2; i < Mini_LutNodeNum(p); i++) if ( !Mini_LutNodeIsPo(p, i) ) {} else
|
||||
#define Mini_LutForEachNode( p, i ) for (i = 2; i < Mini_LutNodeNum(p); i++) if ( !Mini_LutNodeIsNode(p, i) ) {} else
|
||||
|
||||
// iterator through fanins
|
||||
#define Mini_LutForEachFanin( p, i, Fan, k ) for (k = 0; (k < p->LutSize) && (Fan = Mini_LutNodeFanin(p, i, k)) < MINI_LUT_NULL2; k++)
|
||||
|
||||
// constructor/destructor
|
||||
static Mini_Lut_t * Mini_LutStart( int LutSize )
|
||||
{
|
||||
Mini_Lut_t * p; int i;
|
||||
assert( LutSize >= 2 && LutSize <= 16 );
|
||||
p = MINI_LUT_CALLOC( Mini_Lut_t, 1 );
|
||||
p->LutSize = LutSize;
|
||||
p->nCap = MINI_LUT_START_SIZE;
|
||||
p->pArray = MINI_LUT_ALLOC( int, p->nCap * p->LutSize );
|
||||
p->pTruths = MINI_LUT_ALLOC( unsigned, p->nCap * Mini_LutWordNum(p->LutSize) );
|
||||
Mini_LutPush( p, 0, NULL, NULL ); // const0
|
||||
Mini_LutPush( p, 0, NULL, NULL ); // const1
|
||||
for ( i = 0; i < Mini_LutWordNum(p->LutSize); i++ )
|
||||
p->pTruths[i] = 0;
|
||||
for ( i = 0; i < Mini_LutWordNum(p->LutSize); i++ )
|
||||
p->pTruths[Mini_LutWordNum(p->LutSize) + i] = ~0;
|
||||
return p;
|
||||
}
|
||||
static void Mini_LutStop( Mini_Lut_t * p )
|
||||
{
|
||||
MINI_LUT_FREE( p->pArray );
|
||||
MINI_LUT_FREE( p->pTruths );
|
||||
MINI_LUT_FREE( p );
|
||||
}
|
||||
static void Mini_LutPrintStats( Mini_Lut_t * p )
|
||||
{
|
||||
int i, nPis, nPos, nNodes;
|
||||
nPis = 0;
|
||||
Mini_LutForEachPi( p, i )
|
||||
nPis++;
|
||||
nPos = 0;
|
||||
Mini_LutForEachPo( p, i )
|
||||
nPos++;
|
||||
nNodes = 0;
|
||||
Mini_LutForEachNode( p, i )
|
||||
nNodes++;
|
||||
printf( "PI = %d. PO = %d. LUT = %d.\n", nPis, nPos, nNodes );
|
||||
}
|
||||
|
||||
// serialization
|
||||
static void Mini_LutDump( Mini_Lut_t * p, char * pFileName )
|
||||
{
|
||||
FILE * pFile;
|
||||
int RetValue;
|
||||
pFile = fopen( pFileName, "wb" );
|
||||
if ( pFile == NULL )
|
||||
{
|
||||
printf( "Cannot open file for writing \"%s\".\n", pFileName );
|
||||
return;
|
||||
}
|
||||
RetValue = fwrite( &p->nSize, sizeof(int), 1, pFile );
|
||||
RetValue = fwrite( &p->nRegs, sizeof(int), 1, pFile );
|
||||
RetValue = fwrite( &p->LutSize, sizeof(int), 1, pFile );
|
||||
RetValue = fwrite( p->pArray, sizeof(int), p->nSize * p->LutSize, pFile );
|
||||
RetValue = fwrite( p->pTruths, sizeof(int), p->nSize * Mini_LutWordNum(p->LutSize), pFile );
|
||||
fclose( pFile );
|
||||
}
|
||||
static Mini_Lut_t * Mini_LutLoad( char * pFileName )
|
||||
{
|
||||
Mini_Lut_t * p;
|
||||
FILE * pFile;
|
||||
int RetValue, nSize;
|
||||
pFile = fopen( pFileName, "rb" );
|
||||
if ( pFile == NULL )
|
||||
{
|
||||
printf( "Cannot open file for reading \"%s\".\n", pFileName );
|
||||
return NULL;
|
||||
}
|
||||
RetValue = fread( &nSize, sizeof(int), 1, pFile );
|
||||
p = MINI_LUT_CALLOC( Mini_Lut_t, 1 );
|
||||
p->nSize = p->nCap = nSize;
|
||||
RetValue = fread( &p->nRegs, sizeof(int), 1, pFile );
|
||||
RetValue = fread( &p->LutSize, sizeof(int), 1, pFile );
|
||||
p->pArray = MINI_LUT_ALLOC( int, p->nCap * p->LutSize );
|
||||
p->pTruths = MINI_LUT_ALLOC( unsigned, p->nCap * Mini_LutWordNum(p->LutSize) );
|
||||
RetValue = fread( p->pArray, sizeof(int), p->nCap * p->LutSize, pFile );
|
||||
RetValue = fread( p->pTruths, sizeof(int), p->nCap * Mini_LutWordNum(p->LutSize), pFile );
|
||||
fclose( pFile );
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
// creating nodes
|
||||
// (constant nodes are created when LUT manager is created)
|
||||
static int Mini_LutCreatePi( Mini_Lut_t * p )
|
||||
{
|
||||
Mini_LutPush( p, 0, NULL, NULL );
|
||||
return p->nSize - 1;
|
||||
}
|
||||
static int Mini_LutCreatePo( Mini_Lut_t * p, int Var0 )
|
||||
{
|
||||
assert( Var0 >= 0 && Var0 < p->nSize );
|
||||
Mini_LutPush( p, 1, &Var0, NULL );
|
||||
// mark PO by setting its 2nd fanin to the special number
|
||||
p->pArray[p->LutSize*(p->nSize - 1)+1] = MINI_LUT_NULL2;
|
||||
return p->nSize - 1;
|
||||
}
|
||||
|
||||
// create LUT
|
||||
static int Mini_LutCreateNode( Mini_Lut_t * p, int nVars, int * pVars, unsigned * pTruth )
|
||||
{
|
||||
assert( nVars >= 0 && nVars <= p->LutSize );
|
||||
Mini_LutPush( p, nVars, pVars, pTruth );
|
||||
return p->nSize - 1;
|
||||
}
|
||||
|
||||
// procedure to check the topological order during AIG construction
|
||||
static int Mini_LutCheck( Mini_Lut_t * p )
|
||||
{
|
||||
int status = 1;
|
||||
int i, k, iFaninVar;
|
||||
Mini_LutForEachNode( p, i )
|
||||
{
|
||||
for ( k = 0; k < p->LutSize; k++ )
|
||||
{
|
||||
iFaninVar = Mini_LutNodeFanin( p, i, k );
|
||||
if ( iFaninVar == MINI_LUT_NULL )
|
||||
continue;
|
||||
if ( iFaninVar >= p->LutSize * i )
|
||||
printf( "Fanin %d of LUT node %d is not in a topological order.\n", k, i ), status = 0;
|
||||
}
|
||||
}
|
||||
Mini_LutForEachPo( p, i )
|
||||
{
|
||||
iFaninVar = Mini_LutNodeFanin( p, i, 0 );
|
||||
if ( iFaninVar >= p->LutSize * i )
|
||||
printf( "Fanin %d of PO node %d is not in a topological order.\n", k, i ), status = 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -55,6 +55,7 @@
|
|||
#include "sat/bmc/bmc.h"
|
||||
#include "proof/ssc/ssc.h"
|
||||
#include "opt/sfm/sfm.h"
|
||||
#include "opt/sbd/sbd.h"
|
||||
#include "bool/rpo/rpo.h"
|
||||
#include "map/mpm/mpm.h"
|
||||
#include "opt/fret/fretime.h"
|
||||
|
|
@ -134,7 +135,7 @@ static int Abc_CommandRr ( Abc_Frame_t * pAbc, int argc, cha
|
|||
static int Abc_CommandCascade ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandExtract ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandVarMin ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandDetect ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandFaultClasses ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandExact ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandBmsStart ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandBmsStop ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
|
|
@ -481,6 +482,7 @@ static int Abc_CommandAbc9Acec ( Abc_Frame_t * pAbc, int argc, cha
|
|||
static int Abc_CommandAbc9Esop ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandAbc9Exorcism ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandAbc9Mfs ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandAbc9Mfsd ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
//static int Abc_CommandAbc9PoPart2 ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
//static int Abc_CommandAbc9CexCut ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
//static int Abc_CommandAbc9CexMerge ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
|
|
@ -778,7 +780,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
|
|||
Cmd_CommandAdd( pAbc, "Synthesis", "cascade", Abc_CommandCascade, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Synthesis", "extract", Abc_CommandExtract, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Synthesis", "varmin", Abc_CommandVarMin, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Synthesis", "detect", Abc_CommandDetect, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Synthesis", "faultclasses", Abc_CommandFaultClasses, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Synthesis", "exact", Abc_CommandExact, 1 );
|
||||
|
||||
Cmd_CommandAdd( pAbc, "Exact synthesis", "bms_start", Abc_CommandBmsStart, 0 );
|
||||
|
|
@ -1122,6 +1124,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
|
|||
Cmd_CommandAdd( pAbc, "ABC9", "&esop", Abc_CommandAbc9Esop, 0 );
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&exorcism", Abc_CommandAbc9Exorcism, 0 );
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&mfs", Abc_CommandAbc9Mfs, 0 );
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&mfsd", Abc_CommandAbc9Mfsd, 0 );
|
||||
// Cmd_CommandAdd( pAbc, "ABC9", "&popart2", Abc_CommandAbc9PoPart2, 0 );
|
||||
// Cmd_CommandAdd( pAbc, "ABC9", "&cexcut", Abc_CommandAbc9CexCut, 0 );
|
||||
// Cmd_CommandAdd( pAbc, "ABC9", "&cexmerge", Abc_CommandAbc9CexMerge, 0 );
|
||||
|
|
@ -6212,6 +6215,9 @@ usage:
|
|||
Abc_Print( -2, "\t 3: disjoint-support decomposition with cofactoring\n" );
|
||||
Abc_Print( -2, "\t 4: updated disjoint-support decomposition with cofactoring\n" );
|
||||
Abc_Print( -2, "\t 5: enumerating decomposable variable sets\n" );
|
||||
Abc_Print( -2, "\t 6: disjoint-support decomposition with cofactoring and boolean difference analysis\n" );
|
||||
Abc_Print( -2, "\t from V. Callegaro, F. S. Marranghello, M. G. A. Martins, R. P. Ribas and A. I. Reis,\n");
|
||||
Abc_Print( -2, "\t \"Bottom-up disjoint-support decomposition based on cofactor and boolean difference analysis,\" ICCD'15.\n" );
|
||||
Abc_Print( -2, "\t-N <num> : the number of support variables (binary files only) [default = unused]\n" );
|
||||
Abc_Print( -2, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" );
|
||||
Abc_Print( -2, "\t-h : print the command usage\n");
|
||||
|
|
@ -7235,23 +7241,33 @@ usage:
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_CommandDetect( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
int Abc_CommandFaultClasses( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
extern void Abc_NtkDetectClassesTest( Abc_Ntk_t * pNtk, int fSeq, int fVerbose );
|
||||
extern void Abc_NtkDetectClassesTest( Abc_Ntk_t * pNtk, int fSeq, int fVerbose, int fVeryVerbose );
|
||||
extern void Abc_NtkGenFaultList( Abc_Ntk_t * pNtk, char * pFileName, int fStuckAt );
|
||||
Abc_Ntk_t * pNtk;
|
||||
int c, fSeq = 0, fVerbose = 0;
|
||||
int c, fGen = 0, fStuckAt = 0, fSeq = 0, fVerbose = 0, fVeryVerbose = 0;
|
||||
pNtk = Abc_FrameReadNtk(pAbc);
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "svh" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "gcsvwh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'g':
|
||||
fGen ^= 1;
|
||||
break;
|
||||
case 'c':
|
||||
fStuckAt ^= 1;
|
||||
break;
|
||||
case 's':
|
||||
fSeq ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
case 'w':
|
||||
fVeryVerbose ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
|
|
@ -7268,14 +7284,25 @@ int Abc_CommandDetect( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
Abc_Print( -1, "Only applicable to a logic network.\n" );
|
||||
return 1;
|
||||
}
|
||||
Abc_NtkDetectClassesTest( pNtk, fSeq, fVerbose );
|
||||
if ( fGen )
|
||||
{
|
||||
char * pFileName = Extra_FileNameGenericAppend(Abc_NtkSpec(pNtk), "_faults.txt");
|
||||
Abc_NtkGenFaultList( pNtk, pFileName, fStuckAt );
|
||||
}
|
||||
else
|
||||
Abc_NtkDetectClassesTest( pNtk, fSeq, fVerbose, fVeryVerbose );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
Abc_Print( -2, "usage: detect [-svh]\n" );
|
||||
Abc_Print( -2, "\t detects properties of internal nodes\n" );
|
||||
Abc_Print( -2, "\t-s : toggle using sequential circuit information [default = %s]\n", fSeq? "yes": "no" );
|
||||
Abc_Print( -2, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" );
|
||||
Abc_Print( -2, "usage: faultclasses [-gcsvwh]\n" );
|
||||
Abc_Print( -2, "\t computes equivalence classes of faults in the given mapped netlist;\n" );
|
||||
Abc_Print( -2, "\t the fault list with faults in the format: <fault_id> <node_name> <fault_name>\n" );
|
||||
Abc_Print( -2, "\t should be read by command \"read_fins\" before calling this command\n" );
|
||||
Abc_Print( -2, "\t-g : toggle generating a fault list for the current mapped network [default = %s]\n", fGen? "yes": "no" );
|
||||
Abc_Print( -2, "\t-c : toggle using only stuck-at faults in the generated fault list [default = %s]\n", fStuckAt? "yes": "no" );
|
||||
Abc_Print( -2, "\t-s : toggle detecting sequential equivalence classes [default = %s]\n", fSeq? "yes": "no" );
|
||||
Abc_Print( -2, "\t-v : toggle verbose printout during computation [default = %s]\n", fVerbose? "yes": "no" );
|
||||
Abc_Print( -2, "\t-w : toggle printing of resulting fault equivalence classes [default = %s]\n", fVeryVerbose? "yes": "no" );
|
||||
Abc_Print( -2, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -7443,7 +7470,7 @@ usage:
|
|||
Abc_Print( -2, "\t finds optimum networks using SAT-based exact synthesis for hex truth tables <truth1> <truth2> ...\n" );
|
||||
Abc_Print( -2, "\t-D <num> : constrain maximum depth (if too low, algorithm may not terminate)\n" );
|
||||
Abc_Print( -2, "\t-A <list> : input arrival times (comma separated list)\n" );
|
||||
Abc_Print( -2, "\t-S <num> : number of start gates in search [default = %s]\n", nStartGates );
|
||||
Abc_Print( -2, "\t-S <num> : number of start gates in search [default = %d]\n", nStartGates );
|
||||
Abc_Print( -2, "\t-C <num> : the limit on the number of conflicts; turn off with 0 [default = %d]\n", nBTLimit );
|
||||
Abc_Print( -2, "\t-a : toggle create AIG [default = %s]\n", fMakeAIG ? "yes" : "no" );
|
||||
Abc_Print( -2, "\t-t : run test suite\n" );
|
||||
|
|
@ -11840,7 +11867,7 @@ int Abc_CommandTestColor( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
***********************************************************************/
|
||||
int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
|
||||
//Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
|
||||
int nCutMax = 1;
|
||||
int nLeafMax = 4;
|
||||
int nDivMax = 2;
|
||||
|
|
@ -12047,8 +12074,6 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
{
|
||||
// extern void Cba_PrsReadBlifTest();
|
||||
// Cba_PrsReadBlifTest();
|
||||
extern void Sfm_TimTest( Abc_Ntk_t * pNtk );
|
||||
Sfm_TimTest( pNtk );
|
||||
}
|
||||
return 0;
|
||||
usage:
|
||||
|
|
@ -26971,12 +26996,13 @@ int Abc_CommandAbc9Read( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
char ** pArgvNew;
|
||||
char * FileName, * pTemp;
|
||||
int c, nArgcNew;
|
||||
int fUseMini = 0;
|
||||
int fMiniAig = 0;
|
||||
int fMiniLut = 0;
|
||||
int fVerbose = 0;
|
||||
int fGiaSimple = 0;
|
||||
int fSkipStrash = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "csmvh" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "csmlvh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
|
|
@ -26987,7 +27013,10 @@ int Abc_CommandAbc9Read( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
fSkipStrash ^= 1;
|
||||
break;
|
||||
case 'm':
|
||||
fUseMini ^= 1;
|
||||
fMiniAig ^= 1;
|
||||
break;
|
||||
case 'l':
|
||||
fMiniLut ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
|
|
@ -27020,8 +27049,10 @@ int Abc_CommandAbc9Read( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
}
|
||||
fclose( pFile );
|
||||
|
||||
if ( fUseMini )
|
||||
if ( fMiniAig )
|
||||
pAig = Gia_ManReadMiniAig( FileName );
|
||||
else if ( fMiniLut )
|
||||
pAig = Gia_ManReadMiniLut( FileName );
|
||||
// else if ( Extra_FileIsType( FileName, ".v", NULL, NULL ) )
|
||||
// Abc3_ReadShowHie( FileName, fSkipStrash );
|
||||
else
|
||||
|
|
@ -27031,11 +27062,12 @@ int Abc_CommandAbc9Read( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
return 0;
|
||||
|
||||
usage:
|
||||
Abc_Print( -2, "usage: &r [-csmvh] <file>\n" );
|
||||
Abc_Print( -2, "usage: &r [-csmlvh] <file>\n" );
|
||||
Abc_Print( -2, "\t reads the current AIG from the AIGER file\n" );
|
||||
Abc_Print( -2, "\t-c : toggles reading simple AIG [default = %s]\n", fGiaSimple? "yes": "no" );
|
||||
Abc_Print( -2, "\t-s : toggles structural hashing while reading [default = %s]\n", !fSkipStrash? "yes": "no" );
|
||||
Abc_Print( -2, "\t-m : toggles reading MiniAIG rather than AIGER file [default = %s]\n", fUseMini? "yes": "no" );
|
||||
Abc_Print( -2, "\t-m : toggles reading MiniAIG rather than AIGER file [default = %s]\n", fMiniAig? "yes": "no" );
|
||||
Abc_Print( -2, "\t-l : toggles reading MiniLUT rather than AIGER file [default = %s]\n", fMiniLut? "yes": "no" );
|
||||
Abc_Print( -2, "\t-v : toggles additional verbose output [default = %s]\n", fVerbose? "yes": "no" );
|
||||
Abc_Print( -2, "\t-h : print the command usage\n");
|
||||
Abc_Print( -2, "\t<file> : the file name\n");
|
||||
|
|
@ -27616,6 +27648,7 @@ static inline int Gia_ManCompareWithBest( Gia_Man_t * pBest, Gia_Man_t * p, int
|
|||
*pnBestLuts = nCurLuts;
|
||||
*pnBestEdges = nCurEdges;
|
||||
*pnBestLevels = nCurLevels;
|
||||
//printf( "\nUpdating best (%d %d %d).\n\n", nCurLuts, nCurEdges, nCurLevels );
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -27815,9 +27848,10 @@ int Abc_CommandAbc9Write( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
int c, nArgcNew;
|
||||
int fUnique = 0;
|
||||
int fMiniAig = 0;
|
||||
int fMiniLut = 0;
|
||||
int fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "umvh" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "umlvh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
|
|
@ -27827,6 +27861,9 @@ int Abc_CommandAbc9Write( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
case 'm':
|
||||
fMiniAig ^= 1;
|
||||
break;
|
||||
case 'l':
|
||||
fMiniLut ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
|
|
@ -27857,15 +27894,18 @@ int Abc_CommandAbc9Write( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
}
|
||||
else if ( fMiniAig )
|
||||
Gia_ManWriteMiniAig( pAbc->pGia, pFileName );
|
||||
else if ( fMiniLut )
|
||||
Gia_ManWriteMiniLut( pAbc->pGia, pFileName );
|
||||
else
|
||||
Gia_AigerWrite( pAbc->pGia, pFileName, 0, 0 );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
Abc_Print( -2, "usage: &w [-umvh] <file>\n" );
|
||||
Abc_Print( -2, "usage: &w [-umlvh] <file>\n" );
|
||||
Abc_Print( -2, "\t writes the current AIG into the AIGER file\n" );
|
||||
Abc_Print( -2, "\t-u : toggle writing canonical AIG structure [default = %s]\n", fUnique? "yes" : "no" );
|
||||
Abc_Print( -2, "\t-m : toggle writing MiniAIG rather than AIGER [default = %s]\n", fMiniAig? "yes" : "no" );
|
||||
Abc_Print( -2, "\t-l : toggle writing MiniLUT rather than AIGER [default = %s]\n", fMiniLut? "yes" : "no" );
|
||||
Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" );
|
||||
Abc_Print( -2, "\t-h : print the command usage\n");
|
||||
Abc_Print( -2, "\t<file> : the file name\n");
|
||||
|
|
@ -28193,9 +28233,10 @@ int Abc_CommandAbc9MuxProfile( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
extern void Gia_ManMuxProfiling( Gia_Man_t * p );
|
||||
extern void Gia_ManProfileStructures( Gia_Man_t * p, int nLimit, int fVerbose );
|
||||
extern void Acec_StatsCollect( Gia_Man_t * p, int fVerbose );
|
||||
int c, fNpn = 0, fMuxes = 0, nLimit = 0, fVerbose = 0;
|
||||
extern void Acec_ManProfile( Gia_Man_t * p, int fVerbose );
|
||||
int c, fNpn = 0, fMuxes = 0, fAdders = 0, nLimit = 0, fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "Nnmvh" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "Nnmavh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
|
|
@ -28216,6 +28257,9 @@ int Abc_CommandAbc9MuxProfile( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
case 'm':
|
||||
fMuxes ^= 1;
|
||||
break;
|
||||
case 'a':
|
||||
fAdders ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
|
|
@ -28241,16 +28285,19 @@ int Abc_CommandAbc9MuxProfile( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
}
|
||||
else if ( fMuxes )
|
||||
Gia_ManMuxProfiling( pAbc->pGia );
|
||||
else if ( fAdders )
|
||||
Acec_ManProfile( pAbc->pGia, fVerbose );
|
||||
else
|
||||
Gia_ManProfileStructures( pAbc->pGia, nLimit, fVerbose );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
Abc_Print( -2, "usage: &profile [-N num] [-nmvh]\n" );
|
||||
Abc_Print( -2, "usage: &profile [-N num] [-nmavh]\n" );
|
||||
Abc_Print( -2, "\t profile gate structures appearing in the AIG\n" );
|
||||
Abc_Print( -2, "\t-N num : limit on class size to show [default = %d]\n", nLimit );
|
||||
Abc_Print( -2, "\t-n : toggle profiling NPN-classes (for 3-LUT mapped AIGs) [default = %s]\n", fNpn? "yes": "no" );
|
||||
Abc_Print( -2, "\t-m : toggle profiling MUX structures [default = %s]\n", fMuxes? "yes": "no" );
|
||||
Abc_Print( -2, "\t-a : toggle profiling adder structures [default = %s]\n", fAdders? "yes": "no" );
|
||||
Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" );
|
||||
Abc_Print( -2, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
|
|
@ -30989,7 +31036,7 @@ usage:
|
|||
Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit );
|
||||
Abc_Print( -2, "\t-S num : the max number of SAT variables [default = %d]\n", pPars->nSatVarMax );
|
||||
Abc_Print( -2, "\t-K num : the target LUT size for downstream mapping [default = %d]\n", nLutSize );
|
||||
Abc_Print( -2, "\t-R num : the delay relaxation ratio (num >= 0) [default = %d]\n", nRelaxRatio );
|
||||
Abc_Print( -2, "\t-R num : the delay relaxation ratio (num >= 0) [default = %d]\n", nRelaxRatio );
|
||||
Abc_Print( -2, "\t-f : toggle using lighter logic synthesis [default = %s]\n", pPars->fLightSynth? "yes": "no" );
|
||||
Abc_Print( -2, "\t-v : toggle verbose printout [default = %s]\n", pPars->fVerbose? "yes": "no" );
|
||||
Abc_Print( -2, "\t-h : print the command usage\n");
|
||||
|
|
@ -40800,6 +40847,136 @@ usage:
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_CommandAbc9Mfsd( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
extern Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * pGia, Sbd_Par_t * pPars );
|
||||
Gia_Man_t * pTemp; int c;
|
||||
Sbd_Par_t Pars, * pPars = &Pars;
|
||||
Sbd_ParSetDefault( pPars );
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "KWFMCacvwh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'K':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-K\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
pPars->nLutSize = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( pPars->nLutSize < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'W':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-W\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
pPars->nTfoLevels = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( pPars->nTfoLevels < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'F':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
pPars->nTfoFanMax = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( pPars->nTfoFanMax < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'M':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
pPars->nWinSizeMax = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( pPars->nWinSizeMax < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'C':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
pPars->nBTLimit = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( pPars->nBTLimit < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'a':
|
||||
pPars->fArea ^= 1;
|
||||
break;
|
||||
case 'c':
|
||||
pPars->fCover ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
pPars->fVerbose ^= 1;
|
||||
break;
|
||||
case 'w':
|
||||
pPars->fVeryVerbose ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
if ( pAbc->pGia == NULL )
|
||||
{
|
||||
Abc_Print( -1, "Abc_CommandAbc9Mfs(): There is no AIG.\n" );
|
||||
return 0;
|
||||
}
|
||||
if ( Gia_ManBufNum(pAbc->pGia) )
|
||||
{
|
||||
Abc_Print( -1, "Abc_CommandAbc9Mfs(): This command does not work with barrier buffers.\n" );
|
||||
return 1;
|
||||
}
|
||||
if ( Gia_ManHasMapping(pAbc->pGia) )
|
||||
{
|
||||
Abc_Print( -1, "Abc_CommandAbc9Mfs(): The current AIG has mapping (run &st to unmap).\n" );
|
||||
return 0;
|
||||
}
|
||||
pTemp = Sbd_NtkPerform( pAbc->pGia, pPars );
|
||||
Abc_FrameUpdateGia( pAbc, pTemp );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
Abc_Print( -2, "usage: &mfsd [-KWFMC <num>] [-acvwh]\n" );
|
||||
Abc_Print( -2, "\t performs SAT-based delay-oriented AIG optimization\n" );
|
||||
Abc_Print( -2, "\t-K <num> : the LUT size for delay minimization (2 <= num <= 6) [default = %d]\n", pPars->nLutSize );
|
||||
Abc_Print( -2, "\t-W <num> : the number of levels in the TFO cone (0 <= num) [default = %d]\n", pPars->nTfoLevels );
|
||||
Abc_Print( -2, "\t-F <num> : the max number of fanouts to skip (1 <= num) [default = %d]\n", pPars->nTfoFanMax );
|
||||
Abc_Print( -2, "\t-M <num> : the max node count of windows to consider (0 = no limit) [default = %d]\n", pPars->nWinSizeMax );
|
||||
Abc_Print( -2, "\t-C <num> : the max number of conflicts in one SAT run (0 = no limit) [default = %d]\n", pPars->nBTLimit );
|
||||
Abc_Print( -2, "\t-a : toggle minimizing area or area+edges [default = %s]\n", pPars->fArea? "area": "area+edges" );
|
||||
Abc_Print( -2, "\t-c : toggle using complete slow covering procedure [default = %s]\n", pPars->fCover? "yes": "no" );
|
||||
Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", pPars->fVerbose? "yes": "no" );
|
||||
Abc_Print( -2, "\t-w : toggle printing detailed stats for each node [default = %s]\n", pPars->fVeryVerbose? "yes": "no" );
|
||||
Abc_Print( -2, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include "bool/kit/kit.h"
|
||||
#include "opt/dau/dau.h"
|
||||
#include "misc/util/utilTruth.h"
|
||||
#include "opt/dsc/dsc.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -484,6 +485,8 @@ void Abc_TruthDecPerform( Abc_TtStore_t * p, int DecType, int fVerbose )
|
|||
pAlgoName = "fast DSD";
|
||||
else if ( DecType == 5 )
|
||||
pAlgoName = "analysis";
|
||||
else if ( DecType == 6 )
|
||||
pAlgoName = "DSD ICCD'15";
|
||||
|
||||
if ( pAlgoName )
|
||||
printf( "Applying %-10s to %8d func%s of %2d vars... ",
|
||||
|
|
@ -577,6 +580,23 @@ void Abc_TruthDecPerform( Abc_TtStore_t * p, int DecType, int fVerbose )
|
|||
if ( fVerbose )
|
||||
printf( "\n" );
|
||||
}
|
||||
} else if ( DecType == 6 )
|
||||
{
|
||||
char pDsd[DSC_MAX_STR];
|
||||
/* memory pool with a capacity of storing 3*nVars
|
||||
truth-tables for negative and positive cofactors and
|
||||
the boolean difference for each input variable */
|
||||
word *mem_pool = Dsc_alloc_pool(p->nVars);
|
||||
for ( i = 0; i < p->nFuncs; i++ )
|
||||
{
|
||||
if ( fVerbose )
|
||||
printf( "%7d : ", i );
|
||||
Dsc_Decompose(p->pFuncs[i], p->nVars, pDsd, mem_pool);
|
||||
if ( fVerbose )
|
||||
printf( "%s\n", pDsd[0] ? pDsd : "NULL");
|
||||
nNodes += Dsc_CountAnds( pDsd );
|
||||
}
|
||||
Dsc_free_pool(mem_pool);
|
||||
}
|
||||
else assert( 0 );
|
||||
|
||||
|
|
@ -629,7 +649,7 @@ int Abc_DecTest( char * pFileName, int DecType, int nVarNum, int fVerbose )
|
|||
printf( "Using truth tables from file \"%s\"...\n", pFileName );
|
||||
if ( DecType == 0 )
|
||||
{ if ( nVarNum < 0 ) Abc_TtStoreTest( pFileName ); }
|
||||
else if ( DecType >= 1 && DecType <= 5 )
|
||||
else if ( DecType >= 1 && DecType <= 6 )
|
||||
Abc_TruthDecTest( pFileName, DecType, nVarNum, fVerbose );
|
||||
else
|
||||
printf( "Unknown decomposition type value (%d).\n", DecType );
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -29,6 +29,7 @@
|
|||
#include "misc/extra/extra.h"
|
||||
#include "misc/util/utilNam.h"
|
||||
#include "misc/vec/vecHash.h"
|
||||
#include "cbaTypes.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
|
|
@ -40,116 +41,6 @@ ABC_NAMESPACE_HEADER_START
|
|||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// network objects
|
||||
typedef enum {
|
||||
CBA_OBJ_NONE = 0, // 00: unused
|
||||
CBA_OBJ_PI, // 01: input
|
||||
CBA_OBJ_PO, // 02: output
|
||||
CBA_OBJ_BOX, // 03: box
|
||||
|
||||
CBA_BOX_CF, // 04:
|
||||
CBA_BOX_CT, // 05:
|
||||
CBA_BOX_CX, // 06:
|
||||
CBA_BOX_CZ, // 07:
|
||||
|
||||
CBA_BOX_BUF, // 08:
|
||||
CBA_BOX_INV, // 09:
|
||||
CBA_BOX_AND, // 10:
|
||||
CBA_BOX_NAND, // 11:
|
||||
CBA_BOX_OR, // 12:
|
||||
CBA_BOX_NOR, // 13:
|
||||
CBA_BOX_XOR, // 14:
|
||||
CBA_BOX_XNOR, // 15:
|
||||
CBA_BOX_SHARP, // 16:
|
||||
CBA_BOX_SHARPL, // 17:
|
||||
CBA_BOX_MUX, // 18:
|
||||
CBA_BOX_MAJ, // 19:
|
||||
|
||||
CBA_BOX_ABC, // 20:
|
||||
CBA_BOX_BA, // 21:
|
||||
CBA_BOX_BO, // 22:
|
||||
CBA_BOX_BX, // 23:
|
||||
CBA_BOX_BN, // 24:
|
||||
CBA_BOX_BAO, // 25:
|
||||
CBA_BOX_BOA, // 26:
|
||||
|
||||
CBA_BOX_RAND, // 27:
|
||||
CBA_BOX_RNAND, // 28:
|
||||
CBA_BOX_ROR, // 29:
|
||||
CBA_BOX_RNOR, // 30:
|
||||
CBA_BOX_RXOR, // 31:
|
||||
CBA_BOX_RXNOR, // 32:
|
||||
|
||||
CBA_BOX_LNOT, // 33
|
||||
CBA_BOX_LAND, // 34:
|
||||
CBA_BOX_LNAND, // 35:
|
||||
CBA_BOX_LOR, // 36:
|
||||
CBA_BOX_LNOR, // 37:
|
||||
CBA_BOX_LXOR, // 38:
|
||||
CBA_BOX_LXNOR, // 39:
|
||||
|
||||
CBA_BOX_NMUX, // 40:
|
||||
CBA_BOX_SEL, // 41:
|
||||
CBA_BOX_PSEL, // 42:
|
||||
CBA_BOX_ENC, // 43:
|
||||
CBA_BOX_PENC, // 44:
|
||||
CBA_BOX_DEC, // 45:
|
||||
CBA_BOX_EDEC, // 46:
|
||||
|
||||
CBA_BOX_ADD, // 47:
|
||||
CBA_BOX_SUB, // 48:
|
||||
CBA_BOX_MUL, // 49:
|
||||
CBA_BOX_SMUL, // 50:
|
||||
CBA_BOX_DIV, // 51:
|
||||
CBA_BOX_MOD, // 52:
|
||||
CBA_BOX_REM, // 53:
|
||||
CBA_BOX_POW, // 54:
|
||||
CBA_BOX_MIN, // 55:
|
||||
CBA_BOX_SQRT, // 56:
|
||||
CBA_BOX_ABS, // 57:
|
||||
|
||||
CBA_BOX_SLTHAN, // 58:
|
||||
CBA_BOX_LTHAN, // 59:
|
||||
CBA_BOX_LETHAN, // 60:
|
||||
CBA_BOX_METHAN, // 61:
|
||||
CBA_BOX_MTHAN, // 62:
|
||||
CBA_BOX_EQU, // 63:
|
||||
CBA_BOX_NEQU, // 64:
|
||||
|
||||
CBA_BOX_SHIL, // 65:
|
||||
CBA_BOX_SHIR, // 66:
|
||||
CBA_BOX_SHILA, // 67:
|
||||
CBA_BOX_SHIRA, // 68:
|
||||
CBA_BOX_ROTL, // 69:
|
||||
CBA_BOX_ROTR, // 70:
|
||||
|
||||
CBA_BOX_NODE, // 71:
|
||||
CBA_BOX_LUT, // 72:
|
||||
CBA_BOX_GATE, // 73:
|
||||
CBA_BOX_TABLE, // 74:
|
||||
|
||||
CBA_BOX_TRI, // 75:
|
||||
CBA_BOX_RAM, // 76:
|
||||
CBA_BOX_RAMR, // 77:
|
||||
CBA_BOX_RAMW, // 78:
|
||||
CBA_BOX_RAMWC, // 79:
|
||||
CBA_BOX_RAML, // 80:
|
||||
CBA_BOX_RAMS, // 81:
|
||||
CBA_BOX_RAMBOX, // 82:
|
||||
|
||||
CBA_BOX_LATCH, // 83:
|
||||
CBA_BOX_LATCHRS, // 84:
|
||||
CBA_BOX_DFF, // 85:
|
||||
CBA_BOX_DFFCPL, // 86:
|
||||
CBA_BOX_DFFRS, // 87:
|
||||
|
||||
CBA_BOX_SLICE, // 88:
|
||||
CBA_BOX_CONCAT, // 89:
|
||||
|
||||
CBA_BOX_LAST // 90
|
||||
} Cba_ObjType_t;
|
||||
|
||||
|
||||
|
||||
typedef struct Cba_Ntk_t_ Cba_Ntk_t;
|
||||
typedef struct Cba_Man_t_ Cba_Man_t;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,169 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [cbaTypes.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Hierarchical word-level netlist.]
|
||||
|
||||
Synopsis [External declarations.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - July 21, 2015.]
|
||||
|
||||
Revision [$Id: cbaTypes.h,v 1.00 2014/11/29 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef ABC__base__cba__cba__types_h
|
||||
#define ABC__base__cba__cba__types_h
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ABC_NAMESPACE_HEADER_START
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// network objects
|
||||
typedef enum {
|
||||
CBA_OBJ_NONE = 0, // 00: unused
|
||||
CBA_OBJ_PI, // 01: input
|
||||
CBA_OBJ_PO, // 02: output
|
||||
CBA_OBJ_BOX, // 03: box
|
||||
|
||||
CBA_BOX_CF, // 04:
|
||||
CBA_BOX_CT, // 05:
|
||||
CBA_BOX_CX, // 06:
|
||||
CBA_BOX_CZ, // 07:
|
||||
|
||||
CBA_BOX_BUF, // 08:
|
||||
CBA_BOX_INV, // 09:
|
||||
CBA_BOX_AND, // 10:
|
||||
CBA_BOX_NAND, // 11:
|
||||
CBA_BOX_OR, // 12:
|
||||
CBA_BOX_NOR, // 13:
|
||||
CBA_BOX_XOR, // 14:
|
||||
CBA_BOX_XNOR, // 15:
|
||||
CBA_BOX_SHARP, // 16:
|
||||
CBA_BOX_SHARPL, // 17:
|
||||
CBA_BOX_MUX, // 18:
|
||||
CBA_BOX_MAJ, // 19:
|
||||
|
||||
CBA_BOX_ABC, // 20:
|
||||
CBA_BOX_BA, // 21:
|
||||
CBA_BOX_BO, // 22:
|
||||
CBA_BOX_BX, // 23:
|
||||
CBA_BOX_BN, // 24:
|
||||
CBA_BOX_BAO, // 25:
|
||||
CBA_BOX_BOA, // 26:
|
||||
|
||||
CBA_BOX_RAND, // 27:
|
||||
CBA_BOX_RNAND, // 28:
|
||||
CBA_BOX_ROR, // 29:
|
||||
CBA_BOX_RNOR, // 30:
|
||||
CBA_BOX_RXOR, // 31:
|
||||
CBA_BOX_RXNOR, // 32:
|
||||
|
||||
CBA_BOX_LNOT, // 33
|
||||
CBA_BOX_LAND, // 34:
|
||||
CBA_BOX_LNAND, // 35:
|
||||
CBA_BOX_LOR, // 36:
|
||||
CBA_BOX_LNOR, // 37:
|
||||
CBA_BOX_LXOR, // 38:
|
||||
CBA_BOX_LXNOR, // 39:
|
||||
|
||||
CBA_BOX_NMUX, // 40:
|
||||
CBA_BOX_SEL, // 41:
|
||||
CBA_BOX_PSEL, // 42:
|
||||
CBA_BOX_ENC, // 43:
|
||||
CBA_BOX_PENC, // 44:
|
||||
CBA_BOX_DEC, // 45:
|
||||
CBA_BOX_EDEC, // 46:
|
||||
|
||||
CBA_BOX_ADD, // 47:
|
||||
CBA_BOX_SUB, // 48:
|
||||
CBA_BOX_MUL, // 49:
|
||||
CBA_BOX_SMUL, // 50:
|
||||
CBA_BOX_DIV, // 51:
|
||||
CBA_BOX_MOD, // 52:
|
||||
CBA_BOX_REM, // 53:
|
||||
CBA_BOX_POW, // 54:
|
||||
CBA_BOX_MIN, // 55:
|
||||
CBA_BOX_SQRT, // 56:
|
||||
CBA_BOX_ABS, // 57:
|
||||
|
||||
CBA_BOX_SLTHAN, // 58:
|
||||
CBA_BOX_LTHAN, // 59:
|
||||
CBA_BOX_LETHAN, // 60:
|
||||
CBA_BOX_METHAN, // 61:
|
||||
CBA_BOX_MTHAN, // 62:
|
||||
CBA_BOX_EQU, // 63:
|
||||
CBA_BOX_NEQU, // 64:
|
||||
|
||||
CBA_BOX_SHIL, // 65:
|
||||
CBA_BOX_SHIR, // 66:
|
||||
CBA_BOX_SHILA, // 67:
|
||||
CBA_BOX_SHIRA, // 68:
|
||||
CBA_BOX_ROTL, // 69:
|
||||
CBA_BOX_ROTR, // 70:
|
||||
|
||||
CBA_BOX_NODE, // 71:
|
||||
CBA_BOX_LUT, // 72:
|
||||
CBA_BOX_GATE, // 73:
|
||||
CBA_BOX_TABLE, // 74:
|
||||
|
||||
CBA_BOX_TRI, // 75:
|
||||
CBA_BOX_RAM, // 76:
|
||||
CBA_BOX_RAMR, // 77:
|
||||
CBA_BOX_RAMW, // 78:
|
||||
CBA_BOX_RAMWC, // 79:
|
||||
CBA_BOX_RAML, // 80:
|
||||
CBA_BOX_RAMS, // 81:
|
||||
CBA_BOX_RAMBOX, // 82:
|
||||
|
||||
CBA_BOX_LATCH, // 83:
|
||||
CBA_BOX_LATCHRS, // 84:
|
||||
CBA_BOX_DFF, // 85:
|
||||
CBA_BOX_DFFCPL, // 86:
|
||||
CBA_BOX_DFFRS, // 87:
|
||||
|
||||
CBA_BOX_SLICE, // 88:
|
||||
CBA_BOX_CONCAT, // 89:
|
||||
|
||||
CBA_BOX_LAST // 90
|
||||
} Cba_ObjType_t;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// ITERATORS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -2378,6 +2378,7 @@ int IoCommandWriteCex( Abc_Frame_t * pAbc, int argc, char **argv )
|
|||
Abc_Obj_t * pObj;
|
||||
FILE * pFile;
|
||||
int i, f;
|
||||
/*
|
||||
Abc_NtkForEachLatch( pNtk, pObj, i )
|
||||
if ( !Abc_LatchIsInit0(pObj) )
|
||||
{
|
||||
|
|
@ -2385,7 +2386,7 @@ int IoCommandWriteCex( Abc_Frame_t * pAbc, int argc, char **argv )
|
|||
fprintf( stdout, "Run commands \"undc\" and \"zero\" and then rerun the equivalence check.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
*/
|
||||
pFile = fopen( pFileName, "w" );
|
||||
if ( pFile == NULL )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ void Io_WriteDotNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho
|
|||
Abc_Obj_t * pNode, * pFanin;
|
||||
char * pSopString;
|
||||
int LevelMin, LevelMax, fHasCos, Level, i, k, fHasBdds, fCompl, Prev;
|
||||
int Limit = 300;
|
||||
int Limit = 500;
|
||||
|
||||
assert( Abc_NtkIsStrash(pNtk) || Abc_NtkIsLogic(pNtk) );
|
||||
|
||||
|
|
|
|||
|
|
@ -8,4 +8,5 @@ SRC += src/base/wlc/wlcAbs.c \
|
|||
src/base/wlc/wlcReadVer.c \
|
||||
src/base/wlc/wlcSim.c \
|
||||
src/base/wlc/wlcStdin.c \
|
||||
src/base/wlc/wlcWin.c \
|
||||
src/base/wlc/wlcWriteVer.c
|
||||
|
|
|
|||
|
|
@ -244,6 +244,8 @@ static inline Wlc_Obj_t * Wlc_ObjFoToFi( Wlc_Ntk_t * p, Wlc_Obj_t * pObj )
|
|||
|
||||
#define Wlc_ObjForEachFanin( pObj, iFanin, i ) \
|
||||
for ( i = 0; (i < Wlc_ObjFaninNum(pObj)) && (((iFanin) = Wlc_ObjFaninId(pObj, i)), 1); i++ )
|
||||
#define Wlc_ObjForEachFaninObj( p, pObj, pFanin, i ) \
|
||||
for ( i = 0; (i < Wlc_ObjFaninNum(pObj)) && (((pFanin) = Wlc_NtkObj(p, Wlc_ObjFaninId(pObj, i))), 1); i++ )
|
||||
#define Wlc_ObjForEachFaninReverse( pObj, iFanin, i ) \
|
||||
for ( i = Wlc_ObjFaninNum(pObj) - 1; (i >= 0) && (((iFanin) = Wlc_ObjFaninId(pObj, i)), 1); i-- )
|
||||
|
||||
|
|
@ -272,6 +274,8 @@ extern char * Wlc_ObjName( Wlc_Ntk_t * p, int iObj );
|
|||
extern void Wlc_ObjUpdateType( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, int Type );
|
||||
extern void Wlc_ObjAddFanins( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFanins );
|
||||
extern void Wlc_NtkFree( Wlc_Ntk_t * p );
|
||||
extern void Wlc_NtkPrintNode( Wlc_Ntk_t * p, Wlc_Obj_t * pObj );
|
||||
extern void Wlc_NtkPrintNodeArray( Wlc_Ntk_t * p, Vec_Int_t * vArray );
|
||||
extern void Wlc_NtkPrintNodes( Wlc_Ntk_t * p, int Type );
|
||||
extern void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fVerbose );
|
||||
extern Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p );
|
||||
|
|
@ -287,6 +291,8 @@ extern void Wlc_NtkDeleteSim( Vec_Ptr_t * p );
|
|||
extern int Wlc_StdinProcessSmt( Abc_Frame_t * pAbc, char * pCmd );
|
||||
/*=== wlcReadVer.c ========================================================*/
|
||||
extern Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr );
|
||||
/*=== wlcWin.c =============================================================*/
|
||||
extern void Wlc_WinProfileArith( Wlc_Ntk_t * p );
|
||||
/*=== wlcWriteVer.c ========================================================*/
|
||||
extern void Wlc_WriteVer( Wlc_Ntk_t * p, char * pFileName, int fAddCos, int fNoFlops );
|
||||
|
||||
|
|
|
|||
|
|
@ -292,6 +292,10 @@ int Wlc_BlastLessSigned( Gia_Man_t * pNew, int * pArg0, int * pArg1, int nBits )
|
|||
void Wlc_BlastFullAdder( Gia_Man_t * pNew, int a, int b, int c, int * pc, int * ps )
|
||||
{
|
||||
int fUseXor = 0;
|
||||
int fCompl = (a == 1 || b == 1 || c == 1);
|
||||
// propagate complement through the FA - helps generate less redundant logic
|
||||
if ( fCompl )
|
||||
a = Abc_LitNot(a), b = Abc_LitNot(b), c = Abc_LitNot(c);
|
||||
if ( fUseXor )
|
||||
{
|
||||
int Xor = Gia_ManHashXor(pNew, a, b);
|
||||
|
|
@ -310,6 +314,8 @@ void Wlc_BlastFullAdder( Gia_Man_t * pNew, int a, int b, int c, int * pc, int *
|
|||
*ps = Gia_ManHashAnd(pNew, Abc_LitNot(And2), Abc_LitNot(And2_));
|
||||
*pc = Gia_ManHashOr (pNew, And1, And2);
|
||||
}
|
||||
if ( fCompl )
|
||||
*ps = Abc_LitNot(*ps), *pc = Abc_LitNot(*pc);
|
||||
}
|
||||
void Wlc_BlastAdder( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits ) // result is in pAdd0
|
||||
{
|
||||
|
|
@ -412,6 +418,7 @@ void Wlc_BlastMultiplier( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA,
|
|||
assert( fSigned == 0 || fSigned == 1 );
|
||||
// prepare result
|
||||
Vec_IntFill( vRes, nArgA + nArgB, 0 );
|
||||
//Vec_IntFill( vRes, nArgA + nArgB + 1, 0 );
|
||||
pRes = Vec_IntArray( vRes );
|
||||
// prepare intermediate storage
|
||||
Vec_IntFill( vTemp, 2 * nArgA, 0 );
|
||||
|
|
@ -426,6 +433,7 @@ void Wlc_BlastMultiplier( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA,
|
|||
pArgS[nArgA-1] = fSigned;
|
||||
for ( a = 0; a < nArgA; a++ )
|
||||
Wlc_BlastFullAdderCtrl( pNew, 1, pArgC[a], pArgS[a], Carry, &Carry, &pRes[nArgB+a], 0 );
|
||||
//Vec_IntWriteEntry( vRes, nArgA + nArgB, Carry );
|
||||
}
|
||||
void Wlc_BlastDivider( Gia_Man_t * pNew, int * pNum, int nNum, int * pDiv, int nDiv, int fQuo, Vec_Int_t * vRes )
|
||||
{
|
||||
|
|
@ -804,7 +812,7 @@ void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int
|
|||
Vec_WecPush( vLevels, k, 0 );
|
||||
}
|
||||
//Vec_WecPrint( vProds, 0 );
|
||||
|
||||
//printf( "Cutoff ID for partial products = %d.\n", Gia_ManObjNum(pNew) );
|
||||
Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes );
|
||||
|
||||
Vec_WecFree( vProds );
|
||||
|
|
@ -1360,6 +1368,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds, int iOutput, in
|
|||
{
|
||||
pNew = Gia_ManCleanup( pTemp = pNew );
|
||||
Gia_ManDupRemapLiterals( vBits, pTemp );
|
||||
//printf( "Cutoff ID %d became %d.\n", 75, Abc_Lit2Var(Gia_ManObj(pTemp, 73)->Value) );
|
||||
Gia_ManStop( pTemp );
|
||||
}
|
||||
// transform AIG with init state
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ static int Abc_CommandPs ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
|||
static int Abc_CommandBlast ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandPsInv ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandGetInv ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandProfile ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
|
||||
static inline Wlc_Ntk_t * Wlc_AbcGetNtk( Abc_Frame_t * pAbc ) { return (Wlc_Ntk_t *)pAbc->pAbcWlc; }
|
||||
|
|
@ -67,6 +68,7 @@ void Wlc_Init( Abc_Frame_t * pAbc )
|
|||
Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Word level", "%psinv", Abc_CommandPsInv, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Word level", "%getinv", Abc_CommandGetInv, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Word level", "%test", Abc_CommandTest, 0 );
|
||||
}
|
||||
|
||||
|
|
@ -543,6 +545,50 @@ int Abc_CommandGetInv( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**Function********************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
******************************************************************************/
|
||||
int Abc_CommandProfile( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
|
||||
int c, fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
if ( pNtk == NULL )
|
||||
{
|
||||
Abc_Print( 1, "Abc_CommandProfile(): There is no current design.\n" );
|
||||
return 0;
|
||||
}
|
||||
Wlc_WinProfileArith( pNtk );
|
||||
return 0;
|
||||
usage:
|
||||
Abc_Print( -2, "usage: %%profile [-vh]\n" );
|
||||
Abc_Print( -2, "\t profiles arithmetic components in the word-level networks\n" );
|
||||
Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
|
||||
Abc_Print( -2, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function********************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -575,7 +621,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
}
|
||||
if ( pNtk == NULL )
|
||||
{
|
||||
Abc_Print( 1, "Abc_CommandBlast(): There is no current design.\n" );
|
||||
Abc_Print( 1, "Abc_CommandTest(): There is no current design.\n" );
|
||||
return 0;
|
||||
}
|
||||
// transform
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@ static char * Wlc_Names[WLC_OBJ_NUMBER+1] = {
|
|||
">>>", // 10: shift right (arithmetic)
|
||||
"<<", // 11: shift left
|
||||
"<<<", // 12: shift left (arithmetic)
|
||||
"rotateR", // 13: rotate right
|
||||
"rotateL", // 14: rotate left
|
||||
"rotR", // 13: rotate right
|
||||
"rotL", // 14: rotate left
|
||||
"~", // 15: bitwise NOT
|
||||
"&", // 16: bitwise AND
|
||||
"|", // 17: bitwise OR
|
||||
|
|
@ -55,8 +55,8 @@ static char * Wlc_Names[WLC_OBJ_NUMBER+1] = {
|
|||
"~^", // 21: bitwise NXOR
|
||||
"[:]", // 22: bit selection
|
||||
"{,}", // 23: bit concatenation
|
||||
"zeroPad", // 24: zero padding
|
||||
"signExt", // 25: sign extension
|
||||
"zPad", // 24: zero padding
|
||||
"sExt", // 25: sign extension
|
||||
"!", // 26: logic NOT
|
||||
"=>", // 27: logic implication
|
||||
"&&", // 28: logic AND
|
||||
|
|
@ -83,7 +83,7 @@ static char * Wlc_Names[WLC_OBJ_NUMBER+1] = {
|
|||
"**", // 49: arithmetic power
|
||||
"-", // 50: arithmetic minus
|
||||
"sqrt", // 51: integer square root
|
||||
"square", // 52: integer square
|
||||
"squar", // 52: integer square
|
||||
"table", // 53: bit table
|
||||
NULL // 54: unused
|
||||
};
|
||||
|
|
@ -471,6 +471,57 @@ void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fVerbose )
|
|||
Vec_VecFree( (Vec_Vec_t *)vOccurs );
|
||||
Vec_IntFree( vAnds );
|
||||
}
|
||||
void Wlc_NtkPrintNode( Wlc_Ntk_t * p, Wlc_Obj_t * pObj )
|
||||
{
|
||||
printf( "%8d : ", Wlc_ObjId(p, pObj) );
|
||||
printf( "%3d%s", Wlc_ObjRange(pObj), Wlc_ObjIsSigned(pObj) ? "s" : " " );
|
||||
if ( pObj->Type == WLC_OBJ_CONST )
|
||||
printf( " " );
|
||||
else
|
||||
{
|
||||
printf( " = %3d%s %5s ", Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)), Wlc_ObjIsSigned(Wlc_ObjFanin0(p, pObj)) ? "s" : " ", Wlc_Names[(int)pObj->Type] );
|
||||
if ( Wlc_ObjFaninNum(pObj) > 1 )
|
||||
printf( "%3d%s ", Wlc_ObjRange(Wlc_ObjFanin1(p, pObj)), Wlc_ObjIsSigned(Wlc_ObjFanin1(p, pObj)) ? "s" : " " );
|
||||
else
|
||||
printf( " " );
|
||||
if ( Wlc_ObjFaninNum(pObj) > 2 )
|
||||
printf( "%3d%s ", Wlc_ObjRange(Wlc_ObjFanin2(p, pObj)), Wlc_ObjIsSigned(Wlc_ObjFanin2(p, pObj)) ? "s" : " " );
|
||||
else
|
||||
printf( " " );
|
||||
}
|
||||
printf( " : " );
|
||||
printf( "%-12s", Wlc_ObjName(p, Wlc_ObjId(p, pObj)) );
|
||||
if ( pObj->Type == WLC_OBJ_CONST )
|
||||
{
|
||||
printf( " = %d\'%sh", Wlc_ObjRange(pObj), Wlc_ObjIsSigned(pObj) ? "s":"" );
|
||||
if ( pObj->fXConst )
|
||||
{
|
||||
int k;
|
||||
for ( k = 0; k < (Wlc_ObjRange(pObj) + 3) / 4; k++ )
|
||||
printf( "x" );
|
||||
}
|
||||
else
|
||||
Abc_TtPrintHexArrayRev( stdout, (word *)Wlc_ObjConstValue(pObj), (Wlc_ObjRange(pObj) + 3) / 4 );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( " = %-12s %5s ", Wlc_ObjName(p, Wlc_ObjFaninId0(pObj)), Wlc_Names[(int)pObj->Type] );
|
||||
if ( Wlc_ObjFaninNum(pObj) > 1 )
|
||||
printf( "%-12s ", Wlc_ObjName(p, Wlc_ObjFaninId1(pObj)) );
|
||||
else
|
||||
printf( " " );
|
||||
if ( Wlc_ObjFaninNum(pObj) > 2 )
|
||||
printf( "%-12s ", Wlc_ObjName(p, Wlc_ObjFaninId2(pObj)) );
|
||||
}
|
||||
printf( "\n" );
|
||||
}
|
||||
void Wlc_NtkPrintNodeArray( Wlc_Ntk_t * p, Vec_Int_t * vArray )
|
||||
{
|
||||
Wlc_Obj_t * pObj;
|
||||
int i;
|
||||
Wlc_NtkForEachObjVec( vArray, p, pObj, i )
|
||||
Wlc_NtkPrintNode( p, pObj );
|
||||
}
|
||||
void Wlc_NtkPrintNodes( Wlc_Ntk_t * p, int Type )
|
||||
{
|
||||
Wlc_Obj_t * pObj;
|
||||
|
|
@ -480,16 +531,8 @@ void Wlc_NtkPrintNodes( Wlc_Ntk_t * p, int Type )
|
|||
{
|
||||
if ( (int)pObj->Type != Type )
|
||||
continue;
|
||||
printf( "%8d :", Counter++ );
|
||||
printf( "%8d : ", i );
|
||||
printf( "%3d%s = ", Wlc_ObjRange(pObj), Wlc_ObjIsSigned(pObj) ? "s" : " " );
|
||||
printf( "%3d%s %s ", Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)), Wlc_ObjIsSigned(Wlc_ObjFanin0(p, pObj)) ? "s" : " ", Wlc_Names[Type] );
|
||||
printf( "%3d%s ", Wlc_ObjRange(Wlc_ObjFanin1(p, pObj)), Wlc_ObjIsSigned(Wlc_ObjFanin1(p, pObj)) ? "s" : " " );
|
||||
printf( " : " );
|
||||
printf( "%-12s = ", Wlc_ObjName(p, i) );
|
||||
printf( "%-12s %s ", Wlc_ObjName(p, Wlc_ObjFaninId0(pObj)), Wlc_Names[Type] );
|
||||
printf( "%-12s ", Wlc_ObjName(p, Wlc_ObjFaninId1(pObj)) );
|
||||
printf( "\n" );
|
||||
printf( "%8d :", Counter++ );
|
||||
Wlc_NtkPrintNode( p, pObj );
|
||||
}
|
||||
}
|
||||
void Wlc_NtkPrintStats( Wlc_Ntk_t * p, int fDistrib, int fVerbose )
|
||||
|
|
|
|||
|
|
@ -0,0 +1,166 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [wlcWin.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Verilog parser.]
|
||||
|
||||
Synopsis [Parses several flavors of word-level Verilog.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - August 22, 2014.]
|
||||
|
||||
Revision [$Id: wlcWin.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "wlc.h"
|
||||
#include "base/abc/abc.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collect arithmetic nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Wlc_ObjIsArithm( Wlc_Obj_t * pObj )
|
||||
{
|
||||
return pObj->Type == WLC_OBJ_CONST ||
|
||||
pObj->Type == WLC_OBJ_BUF || pObj->Type == WLC_OBJ_BIT_NOT ||
|
||||
pObj->Type == WLC_OBJ_BIT_ZEROPAD || pObj->Type == WLC_OBJ_BIT_SIGNEXT ||
|
||||
// pObj->Type == WLC_OBJ_BIT_SELECT || pObj->Type == WLC_OBJ_BIT_CONCAT ||
|
||||
pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB ||
|
||||
pObj->Type == WLC_OBJ_ARI_MULTI || pObj->Type == WLC_OBJ_ARI_MINUS;
|
||||
}
|
||||
int Wlc_ObjIsArithmReal( Wlc_Obj_t * pObj )
|
||||
{
|
||||
return pObj->Type == WLC_OBJ_BIT_NOT ||
|
||||
pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB ||
|
||||
pObj->Type == WLC_OBJ_ARI_MULTI || pObj->Type == WLC_OBJ_ARI_MINUS;
|
||||
}
|
||||
int Wlc_ManCountArithmReal( Wlc_Ntk_t * p, Vec_Int_t * vNodes )
|
||||
{
|
||||
Wlc_Obj_t * pObj;
|
||||
int i, Counter = 0;
|
||||
Wlc_NtkForEachObjVec( vNodes, p, pObj, i )
|
||||
Counter += Wlc_ObjIsArithmReal( pObj );
|
||||
return Counter;
|
||||
}
|
||||
int Wlc_ObjHasArithm_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj )
|
||||
{
|
||||
if ( pObj->Type == WLC_OBJ_CONST )
|
||||
return 0;
|
||||
if ( pObj->Type == WLC_OBJ_BUF || pObj->Type == WLC_OBJ_BIT_NOT ||
|
||||
pObj->Type == WLC_OBJ_BIT_ZEROPAD || pObj->Type == WLC_OBJ_BIT_SIGNEXT )
|
||||
return Wlc_ObjHasArithm_rec( p, Wlc_ObjFanin0(p, pObj) );
|
||||
return pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB ||
|
||||
pObj->Type == WLC_OBJ_ARI_MULTI || pObj->Type == WLC_OBJ_ARI_MINUS;
|
||||
}
|
||||
int Wlc_ObjHasArithmFanins( Wlc_Ntk_t * p, Wlc_Obj_t * pObj )
|
||||
{
|
||||
Wlc_Obj_t * pFanin; int i;
|
||||
assert( !Wlc_ObjHasArithm_rec(p, pObj) );
|
||||
Wlc_ObjForEachFaninObj( p, pObj, pFanin, i )
|
||||
if ( Wlc_ObjHasArithm_rec(p, pFanin) )
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
void Wlc_WinCompute_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vLeaves, Vec_Int_t * vNodes )
|
||||
{
|
||||
Wlc_Obj_t * pFanin; int i;
|
||||
if ( pObj->Mark )
|
||||
return;
|
||||
pObj->Mark = 1;
|
||||
if ( !Wlc_ObjIsArithm(pObj) )
|
||||
{
|
||||
Vec_IntPush( vLeaves, Wlc_ObjId(p, pObj) );
|
||||
return;
|
||||
}
|
||||
Wlc_ObjForEachFaninObj( p, pObj, pFanin, i )
|
||||
Wlc_WinCompute_rec( p, pFanin, vLeaves, vNodes );
|
||||
Vec_IntPush( vNodes, Wlc_ObjId(p, pObj) );
|
||||
}
|
||||
void Wlc_WinCleanMark_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj )
|
||||
{
|
||||
Wlc_Obj_t * pFanin; int i;
|
||||
if ( !pObj->Mark )
|
||||
return;
|
||||
pObj->Mark = 0;
|
||||
Wlc_ObjForEachFaninObj( p, pObj, pFanin, i )
|
||||
Wlc_WinCleanMark_rec( p, pFanin );
|
||||
}
|
||||
void Wlc_WinCompute( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vLeaves, Vec_Int_t * vNodes )
|
||||
{
|
||||
Vec_IntClear( vLeaves );
|
||||
Vec_IntClear( vNodes );
|
||||
if ( Wlc_ObjHasArithm_rec(p, pObj) )
|
||||
{
|
||||
Wlc_WinCompute_rec( p, pObj, vLeaves, vNodes );
|
||||
Wlc_WinCleanMark_rec( p, pObj );
|
||||
}
|
||||
else if ( Wlc_ObjHasArithmFanins(p, pObj) )
|
||||
{
|
||||
Wlc_Obj_t * pFanin; int i;
|
||||
Wlc_ObjForEachFaninObj( p, pObj, pFanin, i )
|
||||
if ( Wlc_ObjHasArithm_rec(p, pFanin) )
|
||||
Wlc_WinCompute_rec( p, pFanin, vLeaves, vNodes );
|
||||
Wlc_ObjForEachFaninObj( p, pObj, pFanin, i )
|
||||
if ( Wlc_ObjHasArithm_rec(p, pFanin) )
|
||||
Wlc_WinCleanMark_rec( p, pFanin );
|
||||
}
|
||||
else assert( 0 );
|
||||
}
|
||||
void Wlc_WinProfileArith( Wlc_Ntk_t * p )
|
||||
{
|
||||
Vec_Int_t * vLeaves = Vec_IntAlloc( 1000 );
|
||||
Vec_Int_t * vNodes = Vec_IntAlloc( 1000 );
|
||||
Wlc_Obj_t * pObj; int i, Count = 0;
|
||||
Wlc_NtkForEachObj( p, pObj, i )
|
||||
pObj->Mark = 0;
|
||||
Wlc_NtkForEachObj( p, pObj, i )
|
||||
if ( Wlc_ObjHasArithm_rec(p, pObj) ? Wlc_ObjIsCo(pObj) : Wlc_ObjHasArithmFanins(p, pObj) )
|
||||
{
|
||||
Wlc_WinCompute( p, pObj, vLeaves, vNodes );
|
||||
if ( Wlc_ManCountArithmReal(p, vNodes) < 2 )
|
||||
continue;
|
||||
|
||||
printf( "Arithmetic cone of node %d (%s):\n", Wlc_ObjId(p, pObj), Wlc_ObjName(p, Wlc_ObjId(p, pObj)) );
|
||||
Wlc_NtkPrintNode( p, pObj );
|
||||
Vec_IntReverseOrder( vNodes );
|
||||
Wlc_NtkPrintNodeArray( p, vNodes );
|
||||
printf( "\n" );
|
||||
Count++;
|
||||
}
|
||||
Wlc_NtkForEachObj( p, pObj, i )
|
||||
assert( pObj->Mark == 0 );
|
||||
printf( "Finished printing %d arithmetic cones.\n", Count );
|
||||
Vec_IntFree( vLeaves );
|
||||
Vec_IntFree( vNodes );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
@ -112,6 +112,7 @@ extern char * Mio_LibraryReadName ( Mio_Library_t * pLib );
|
|||
extern int Mio_LibraryReadGateNum ( Mio_Library_t * pLib );
|
||||
extern Mio_Gate_t * Mio_LibraryReadGates ( Mio_Library_t * pLib );
|
||||
extern Mio_Gate_t ** Mio_LibraryReadGateArray ( Mio_Library_t * pLib );
|
||||
extern Mio_Gate_t * Mio_LibraryReadGateById ( Mio_Library_t * pLib, int iD );
|
||||
extern Mio_Gate_t * Mio_LibraryReadGateByName ( Mio_Library_t * pLib, char * pName, char * pOutName );
|
||||
extern char * Mio_LibraryReadSopByName ( Mio_Library_t * pLib, char * pName );
|
||||
extern Mio_Gate_t * Mio_LibraryReadGateByTruth( Mio_Library_t * pLib, word t );
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ char * Mio_LibraryReadName ( Mio_Library_t * pLib ) { retur
|
|||
int Mio_LibraryReadGateNum ( Mio_Library_t * pLib ) { return pLib->nGates; }
|
||||
Mio_Gate_t * Mio_LibraryReadGates ( Mio_Library_t * pLib ) { return pLib->pGates; }
|
||||
Mio_Gate_t ** Mio_LibraryReadGateArray ( Mio_Library_t * pLib ) { return pLib->ppGatesName;}
|
||||
Mio_Gate_t * Mio_LibraryReadGateById ( Mio_Library_t * pLib, int Id ) { assert( pLib->ppGates0[Id]->Cell == Id ); return pLib->ppGates0[Id];}
|
||||
Mio_Gate_t * Mio_LibraryReadBuf ( Mio_Library_t * pLib ) { return pLib->pGateBuf; }
|
||||
Mio_Gate_t * Mio_LibraryReadInv ( Mio_Library_t * pLib ) { return pLib->pGateInv; }
|
||||
Mio_Gate_t * Mio_LibraryReadConst0 ( Mio_Library_t * pLib ) { return pLib->pGate0; }
|
||||
|
|
|
|||
|
|
@ -586,7 +586,10 @@ void Mio_LibrarySortGates( Mio_Library_t * pLib )
|
|||
int i = 0;
|
||||
ppGates = ABC_ALLOC( Mio_Gate_t *, pLib->nGates );
|
||||
Mio_LibraryForEachGate( pLib, pGate )
|
||||
{
|
||||
pGate->Cell = i;
|
||||
ppGates[i++] = pGate;
|
||||
}
|
||||
assert( i == pLib->nGates );
|
||||
// sort gates by name
|
||||
pLib->ppGates0 = ABC_ALLOC( Mio_Gate_t *, pLib->nGates );
|
||||
|
|
|
|||
|
|
@ -1614,10 +1614,14 @@ Vec_Str_t * Scl_LibertyReadSclStr( Scl_Tree_t * p, int fVerbose, int fVeryVerbos
|
|||
Vec_Flt_t * vArray;
|
||||
assert( Vec_PtrSize(vTemples) % 4 == 0 );
|
||||
Vec_PtrForEachEntry( Vec_Flt_t *, vTemples, vArray, i )
|
||||
{
|
||||
if ( vArray == NULL )
|
||||
continue;
|
||||
if ( i % 4 == 0 )
|
||||
ABC_FREE( vArray );
|
||||
else if ( i % 4 == 2 || i % 4 == 3 )
|
||||
Vec_FltFree( vArray );
|
||||
}
|
||||
Vec_PtrFree( vTemples );
|
||||
}
|
||||
if ( fVerbose )
|
||||
|
|
|
|||
|
|
@ -266,6 +266,28 @@ static inline void Abc_TtAnd( word * pOut, word * pIn1, word * pIn2, int nWords,
|
|||
for ( w = 0; w < nWords; w++ )
|
||||
pOut[w] = pIn1[w] & pIn2[w];
|
||||
}
|
||||
static inline void Abc_TtAndCompl( word * pOut, word * pIn1, int fCompl1, word * pIn2, int fCompl2, int nWords )
|
||||
{
|
||||
int w;
|
||||
if ( fCompl1 )
|
||||
{
|
||||
if ( fCompl2 )
|
||||
for ( w = 0; w < nWords; w++ )
|
||||
pOut[w] = ~pIn1[w] & ~pIn2[w];
|
||||
else
|
||||
for ( w = 0; w < nWords; w++ )
|
||||
pOut[w] = ~pIn1[w] & pIn2[w];
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( fCompl2 )
|
||||
for ( w = 0; w < nWords; w++ )
|
||||
pOut[w] = pIn1[w] & ~pIn2[w];
|
||||
else
|
||||
for ( w = 0; w < nWords; w++ )
|
||||
pOut[w] = pIn1[w] & pIn2[w];
|
||||
}
|
||||
}
|
||||
static inline void Abc_TtAndSharp( word * pOut, word * pIn1, word * pIn2, int nWords, int fCompl )
|
||||
{
|
||||
int w;
|
||||
|
|
@ -288,6 +310,12 @@ static inline void Abc_TtOr( word * pOut, word * pIn1, word * pIn2, int nWords )
|
|||
for ( w = 0; w < nWords; w++ )
|
||||
pOut[w] = pIn1[w] | pIn2[w];
|
||||
}
|
||||
static inline void Abc_TtOrXor( word * pOut, word * pIn1, word * pIn2, int nWords )
|
||||
{
|
||||
int w;
|
||||
for ( w = 0; w < nWords; w++ )
|
||||
pOut[w] |= pIn1[w] ^ pIn2[w];
|
||||
}
|
||||
static inline void Abc_TtXor( word * pOut, word * pIn1, word * pIn2, int nWords, int fCompl )
|
||||
{
|
||||
int w;
|
||||
|
|
@ -1603,6 +1631,14 @@ static inline int Abc_TtFindFirstBit( word * pIn, int nVars )
|
|||
return 64*w + Abc_Tt6FirstBit(pIn[w]);
|
||||
return -1;
|
||||
}
|
||||
static inline int Abc_TtFindFirstDiffBit( word * pIn1, word * pIn2, int nVars )
|
||||
{
|
||||
int w, nWords = Abc_TtWordNum(nVars);
|
||||
for ( w = 0; w < nWords; w++ )
|
||||
if ( pIn1[w] ^ pIn2[w] )
|
||||
return 64*w + Abc_Tt6FirstBit(pIn1[w] ^ pIn2[w]);
|
||||
return -1;
|
||||
}
|
||||
static inline int Abc_TtFindFirstZero( word * pIn, int nVars )
|
||||
{
|
||||
int w, nWords = Abc_TtWordNum(nVars);
|
||||
|
|
|
|||
|
|
@ -238,12 +238,28 @@ int Dau_DsdBalance( Gia_Man_t * pGia, int * pFans, int nFans, int fAnd )
|
|||
assert( nFans > 1 );
|
||||
iFan0 = pFans[--nFans];
|
||||
iFan1 = pFans[--nFans];
|
||||
if ( fAnd )
|
||||
iFan = Gia_ManHashAnd( pGia, iFan0, iFan1 );
|
||||
else if ( pGia->pMuxes )
|
||||
iFan = Gia_ManHashXorReal( pGia, iFan0, iFan1 );
|
||||
else
|
||||
iFan = Gia_ManHashXor( pGia, iFan0, iFan1 );
|
||||
if ( pGia->pHTable == NULL )
|
||||
{
|
||||
if ( fAnd )
|
||||
iFan = Gia_ManAppendAnd( pGia, iFan0, iFan1 );
|
||||
else if ( pGia->pMuxes )
|
||||
{
|
||||
int fCompl = Abc_LitIsCompl(iFan0) ^ Abc_LitIsCompl(iFan1);
|
||||
iFan = Gia_ManAppendXorReal( pGia, Abc_LitRegular(iFan0), Abc_LitRegular(iFan1) );
|
||||
iFan = Abc_LitNotCond( iFan, fCompl );
|
||||
}
|
||||
else
|
||||
iFan = Gia_ManAppendXor( pGia, iFan0, iFan1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( fAnd )
|
||||
iFan = Gia_ManHashAnd( pGia, iFan0, iFan1 );
|
||||
else if ( pGia->pMuxes )
|
||||
iFan = Gia_ManHashXorReal( pGia, iFan0, iFan1 );
|
||||
else
|
||||
iFan = Gia_ManHashXor( pGia, iFan0, iFan1 );
|
||||
}
|
||||
pObj = Gia_ManObj(pGia, Abc_Lit2Var(iFan));
|
||||
if ( Gia_ObjIsAnd(pObj) )
|
||||
{
|
||||
|
|
@ -340,14 +356,24 @@ int Dau_DsdToGia_rec( Gia_Man_t * pGia, char * pStr, char ** p, int * pMatches,
|
|||
assert( **p == '{' && *q == '}' );
|
||||
*p = q;
|
||||
}
|
||||
if ( pGia->pMuxes )
|
||||
Res = Gia_ManHashMuxReal( pGia, Temp[0], Temp[1], Temp[2] );
|
||||
if ( pGia->pHTable == NULL )
|
||||
{
|
||||
if ( pGia->pMuxes )
|
||||
Res = Gia_ManAppendMux( pGia, Temp[0], Temp[1], Temp[2] );
|
||||
else
|
||||
Res = Gia_ManAppendMux( pGia, Temp[0], Temp[1], Temp[2] );
|
||||
}
|
||||
else
|
||||
Res = Gia_ManHashMux( pGia, Temp[0], Temp[1], Temp[2] );
|
||||
{
|
||||
if ( pGia->pMuxes )
|
||||
Res = Gia_ManHashMuxReal( pGia, Temp[0], Temp[1], Temp[2] );
|
||||
else
|
||||
Res = Gia_ManHashMux( pGia, Temp[0], Temp[1], Temp[2] );
|
||||
}
|
||||
pObj = Gia_ManObj(pGia, Abc_Lit2Var(Res));
|
||||
if ( Gia_ObjIsAnd(pObj) )
|
||||
{
|
||||
if ( pGia->pMuxes )
|
||||
if ( pGia->pMuxes && pGia->pHTable != NULL )
|
||||
Gia_ObjSetMuxLevel( pGia, pObj );
|
||||
else
|
||||
{
|
||||
|
|
@ -377,7 +403,7 @@ int Dau_DsdToGia_rec( Gia_Man_t * pGia, char * pStr, char ** p, int * pMatches,
|
|||
vLeaves.nSize = nVars;
|
||||
vLeaves.pArray = Fanins;
|
||||
nObjOld = Gia_ManObjNum(pGia);
|
||||
Res = Kit_TruthToGia( pGia, (unsigned *)pFunc, nVars, vCover, &vLeaves, 1 );
|
||||
Res = Kit_TruthToGia( pGia, (unsigned *)pFunc, nVars, vCover, &vLeaves, pGia->pHTable != NULL );
|
||||
// assert( nVars <= 6 );
|
||||
// Res = Dau_DsdToGiaCompose_rec( pGia, pFunc[0], Fanins, nVars );
|
||||
for ( i = nObjOld; i < Gia_ManObjNum(pGia); i++ )
|
||||
|
|
@ -434,7 +460,7 @@ int Dsm_ManTruthToGia( void * p, word * pTruth, Vec_Int_t * vLeaves, Vec_Int_t *
|
|||
if ( nSizeNonDec )
|
||||
m_NonDsd++;
|
||||
// printf( "%s\n", pDsd );
|
||||
if ( fDelayBalance )
|
||||
if ( fDelayBalance && pGia->vLevels )
|
||||
return Dau_DsdToGia( pGia, pDsd, Vec_IntArray(vLeaves), vCover );
|
||||
else
|
||||
return Dau_DsdToGia2( pGia, pDsd, Vec_IntArray(vLeaves), vCover );
|
||||
|
|
|
|||
|
|
@ -0,0 +1,525 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [dsc.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Disjoint support decomposition - ICCD'15]
|
||||
|
||||
Synopsis [Disjoint-support decomposition with cofactoring and boolean difference analysis
|
||||
from V. Callegaro, F. S. Marranghello, M. G. A. Martins, R. P. Ribas and A. I. Reis,
|
||||
"Bottom-up disjoint-support decomposition based on cofactor and boolean difference analysis," ICCD'15]
|
||||
|
||||
Author [Vinicius Callegaro, Mayler G. A. Martins, Felipe S. Marranghello, Renato P. Ribas and Andre I. Reis]
|
||||
|
||||
Affiliation [UFRGS - Federal University of Rio Grande do Sul - Brazil]
|
||||
|
||||
Date [Ver. 1.0. Started - October 24, 2014.]
|
||||
|
||||
Revision [$Id: dsc.h,v 1.00 2014/10/24 00:00:00 vcallegaro Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "dsc.h"
|
||||
#include <assert.h>
|
||||
#include "misc/util/utilTruth.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
This code performs truth-table-based decomposition for 6-variable functions.
|
||||
Representation of operations:
|
||||
! = not;
|
||||
(ab) = a and b;
|
||||
[ab] = a xor b;
|
||||
*/
|
||||
typedef struct Dsc_node_t_ Dsc_node_t;
|
||||
struct Dsc_node_t_
|
||||
{
|
||||
word *pNegCof;
|
||||
word *pPosCof;
|
||||
word *pBoolDiff;
|
||||
unsigned int on[DSC_MAX_VAR+1]; // pos cofactor spec - first element denotes the size of the array
|
||||
unsigned int off[DSC_MAX_VAR+1]; // neg cofactor spec - first element denotes the size of the array
|
||||
char exp[DSC_MAX_STR];
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void xorInPlace( word * pOut, word * pIn2, int nWords)
|
||||
{
|
||||
int w;
|
||||
for ( w = 0; w < nWords; w++ )
|
||||
pOut[w] ^= pIn2[w];
|
||||
}
|
||||
|
||||
void dsc_debug_node(Dsc_node_t * pNode, int nVars, const int TRUTH_WORDS) {
|
||||
int i;
|
||||
printf("Node:\t%s\n",pNode->exp);
|
||||
printf("\tneg cof:\t");Abc_TtPrintHexRev(stdout, pNode->pNegCof, nVars);
|
||||
printf("\tpos cof:\t");Abc_TtPrintHexRev(stdout, pNode->pPosCof, nVars);
|
||||
printf("\tbool diff:\t");Abc_TtPrintHexRev(stdout, pNode->pBoolDiff, nVars);
|
||||
printf("\toff:\t");
|
||||
for (i=1;i<=(int)pNode->off[0];i++) {
|
||||
printf("%c%c", (pNode->off[i] & 1U) ? ' ' : '!', 'a'+(pNode->off[i] >> 1));
|
||||
}
|
||||
printf("\ton:\t");
|
||||
for (i=1;i<=(int)pNode->on[0];i++) {
|
||||
printf("%c%c", (pNode->on[i] & 1U) ? ' ' : '!', 'a'+(pNode->on[i] >> 1));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
inline int dsc_and_test(Dsc_node_t *ni, Dsc_node_t *nj, const int TRUTH_WORDS, int* ci, int* cj) {
|
||||
if (Abc_TtEqual(ni->pNegCof, nj->pNegCof, TRUTH_WORDS)) {*ci=1; *cj=1; return 1;}
|
||||
else if (Abc_TtEqual(ni->pNegCof, nj->pPosCof, TRUTH_WORDS)) {*ci=1; *cj=0; return 1;}
|
||||
else if (Abc_TtEqual(ni->pPosCof, nj->pNegCof, TRUTH_WORDS)) {*ci=0; *cj=1; return 1;}
|
||||
else if (Abc_TtEqual(ni->pPosCof, nj->pPosCof, TRUTH_WORDS)) {*ci=0; *cj=0; return 1;}
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int dsc_xor_test(Dsc_node_t *ni, Dsc_node_t *nj, const int TRUTH_WORDS) {
|
||||
return Abc_TtEqual(ni->pBoolDiff, nj->pBoolDiff, TRUTH_WORDS);
|
||||
}
|
||||
|
||||
void concat(char* target, char begin, char end, char* s1, int s1Polarity, char* s2, int s2Polarity) {
|
||||
*target++ = begin;
|
||||
//s1
|
||||
if (!s1Polarity)
|
||||
*target++ = '!';
|
||||
while (*s1 != '\0')
|
||||
*target++ = *s1++;
|
||||
// s2
|
||||
if (!s2Polarity)
|
||||
*target++ = '!';
|
||||
while (*s2 != '\0')
|
||||
*target++ = *s2++;
|
||||
// end
|
||||
*target++ = end;
|
||||
*target = '\0';
|
||||
}
|
||||
|
||||
void cubeCofactor(word * const pTruth, const unsigned int * const cubeCof, const int TRUTH_WORDS) {
|
||||
int size = cubeCof[0];
|
||||
int i;
|
||||
for (i = 1; i <= size; i++) {
|
||||
unsigned int c = cubeCof[i];
|
||||
if (c & 1U) {
|
||||
Abc_TtCofactor1(pTruth, TRUTH_WORDS, c >> 1);
|
||||
} else {
|
||||
Abc_TtCofactor0(pTruth, TRUTH_WORDS, c >> 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void merge(unsigned int * const pOut, const unsigned int * const pIn) {
|
||||
const int elementsToCopy = pIn[0];
|
||||
int i, j;
|
||||
for (i = pOut[0]+1, j = 1; j <= elementsToCopy; i++, j++) {
|
||||
pOut[i] = pIn[j];
|
||||
}
|
||||
pOut[0] += elementsToCopy;
|
||||
}
|
||||
|
||||
void dsc_and_group(Dsc_node_t * pOut, Dsc_node_t * ni, int niPolarity, Dsc_node_t * nj, int njPolarity, int nVars, const int TRUTH_WORDS) {
|
||||
unsigned int* xiOFF, * xiON, * xjOFF, * xjON;
|
||||
// expression
|
||||
concat(pOut->exp, '(', ')', ni->exp, niPolarity, nj->exp, njPolarity);
|
||||
// ON-OFF
|
||||
if (niPolarity) {
|
||||
xiOFF = ni->off;
|
||||
xiON = ni->on;
|
||||
} else {
|
||||
xiOFF = ni->on;
|
||||
xiON = ni->off;
|
||||
}
|
||||
if (njPolarity) {
|
||||
xjOFF = nj->off;
|
||||
xjON = nj->on;
|
||||
} else {
|
||||
xjOFF = nj->on;
|
||||
xjON = nj->off;
|
||||
}
|
||||
// creating both the new OFF specification and negative cofactor of the new group
|
||||
{
|
||||
// first element of the array represents the size of the cube-cofactor
|
||||
int xiOFFSize = xiOFF[0];
|
||||
int xjOFFSize = xjOFF[0];
|
||||
if (xiOFFSize <= xjOFFSize) {
|
||||
int i;
|
||||
pOut->off[0] = xiOFFSize; // set the number of elements
|
||||
for (i = 1; i <= xiOFFSize; i++) {
|
||||
pOut->off[i] = xiOFF[i];
|
||||
}
|
||||
} else {
|
||||
int i;
|
||||
pOut->off[0] = xjOFFSize; // set the number of elements
|
||||
for (i = 1; i <= xjOFFSize; i++) {
|
||||
pOut->off[i] = xjOFF[i];
|
||||
}
|
||||
}
|
||||
// set the negative cofactor of the new group
|
||||
pOut->pNegCof = niPolarity ? ni->pNegCof : ni->pPosCof;
|
||||
}
|
||||
// creating both new ON specification and positive cofactor of the new group
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
unsigned int xiONSize = xiON[0];
|
||||
unsigned int xjONSize = xjON[0];
|
||||
pOut->on[0] = xiONSize + xjONSize;
|
||||
for (i = 1; i <= (int)xiONSize; i++) {
|
||||
pOut->on[i] = xiON[i];
|
||||
}
|
||||
for (j = 1; j <= (int)xjONSize; j++) {
|
||||
pOut->on[i++] = xjON[j];
|
||||
}
|
||||
// set the positive cofactor of the new group
|
||||
if (xiONSize >= xjONSize) {
|
||||
pOut->pPosCof = niPolarity ? ni->pPosCof : ni->pNegCof;
|
||||
cubeCofactor(pOut->pPosCof, xjON, TRUTH_WORDS);
|
||||
} else {
|
||||
pOut->pPosCof = njPolarity ? nj->pPosCof : nj->pNegCof;
|
||||
cubeCofactor(pOut->pPosCof, xiON, TRUTH_WORDS);
|
||||
}
|
||||
}
|
||||
// set the boolean difference of the new group
|
||||
pOut->pBoolDiff = njPolarity ? nj->pNegCof : nj->pPosCof;
|
||||
xorInPlace(pOut->pBoolDiff, pOut->pPosCof, TRUTH_WORDS);
|
||||
}
|
||||
|
||||
void dsc_xor_group(Dsc_node_t * pOut, Dsc_node_t * ni, Dsc_node_t * nj, int nVars, const int TRUTH_WORDS) {
|
||||
//
|
||||
const unsigned int * xiOFF = ni->off;
|
||||
const unsigned int * xiON = ni->on;
|
||||
const unsigned int * xjOFF = nj->off;
|
||||
const unsigned int * xjON = nj->on;
|
||||
//
|
||||
const int xiOFFSize = xiOFF[0];
|
||||
const int xiONSize = xiON[0];
|
||||
const int xjOFFSize = xjOFF[0];
|
||||
const int xjONSize = xjON[0];
|
||||
// minCubeCofs
|
||||
int minCCSize = xiOFFSize;
|
||||
int minCCPolarity = 0;
|
||||
Dsc_node_t * minCCNode = ni;
|
||||
// expression
|
||||
concat(pOut->exp, '[', ']', ni->exp, 1, nj->exp, 1);
|
||||
if (minCCSize > xiONSize) {
|
||||
minCCSize = xiONSize;
|
||||
minCCPolarity = 1;
|
||||
//minCCNode = ni;
|
||||
}
|
||||
if (minCCSize > xjOFFSize) {
|
||||
minCCSize = xjOFFSize;
|
||||
minCCPolarity = 0;
|
||||
minCCNode = nj;
|
||||
}
|
||||
if (minCCSize > xjONSize) {
|
||||
minCCSize = xjONSize;
|
||||
minCCPolarity = 1;
|
||||
minCCNode = nj;
|
||||
}
|
||||
//
|
||||
if (minCCNode == ni) {
|
||||
if (minCCPolarity) {
|
||||
// gOFF = xiON, xjON
|
||||
pOut->pNegCof = nj->pPosCof;
|
||||
cubeCofactor(pOut->pNegCof, xiON, TRUTH_WORDS);
|
||||
// gON = xiON, xjOFF
|
||||
pOut->pPosCof = nj->pNegCof;
|
||||
cubeCofactor(pOut->pPosCof, xiON, TRUTH_WORDS);
|
||||
} else {
|
||||
// gOFF = xiOFF, xjOFF
|
||||
pOut->pNegCof = nj->pNegCof;
|
||||
cubeCofactor(pOut->pNegCof, xiOFF, TRUTH_WORDS);
|
||||
// gON = xiOFF, xjON
|
||||
pOut->pPosCof = nj->pPosCof;
|
||||
cubeCofactor(pOut->pPosCof, xiOFF, TRUTH_WORDS);
|
||||
}
|
||||
}else {
|
||||
if (minCCPolarity) {
|
||||
// gOFF = xjON, xiON
|
||||
pOut->pNegCof = ni->pPosCof;
|
||||
cubeCofactor(pOut->pNegCof, xjON, TRUTH_WORDS);
|
||||
// gON = xjON, xiOFF
|
||||
pOut->pPosCof = ni->pNegCof;
|
||||
cubeCofactor(pOut->pPosCof, xjON, TRUTH_WORDS);
|
||||
} else {
|
||||
// gOFF = xjOFF, xiOFF
|
||||
pOut->pNegCof = ni->pNegCof;
|
||||
cubeCofactor(pOut->pNegCof, xjOFF, TRUTH_WORDS);
|
||||
// gON = xjOFF, xiON
|
||||
pOut->pPosCof = ni->pPosCof;
|
||||
cubeCofactor(pOut->pPosCof, xjOFF, TRUTH_WORDS);
|
||||
}
|
||||
}
|
||||
// bool diff
|
||||
pOut->pBoolDiff = ni->pBoolDiff;
|
||||
// evaluating specs
|
||||
// off spec
|
||||
pOut->off[0] = 0;
|
||||
if ((xiOFFSize+xjOFFSize) <= (xiONSize+xjONSize)) {
|
||||
merge(pOut->off, xiOFF);
|
||||
merge(pOut->off, xjOFF);
|
||||
} else {
|
||||
merge(pOut->off, xiON);
|
||||
merge(pOut->off, xjON);
|
||||
}
|
||||
// on spec
|
||||
pOut->on[0] = 0;
|
||||
if ((xiOFFSize+xjONSize) <= (xiONSize+xjOFFSize)) {
|
||||
merge(pOut->on, xiOFF);
|
||||
merge(pOut->on, xjON);
|
||||
} else {
|
||||
merge(pOut->on, xiON);
|
||||
merge(pOut->on, xjOFF);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* memory allocator with a capacity of storing 3*nVars
|
||||
* truth-tables for negative and positive cofactors and
|
||||
* the boolean difference for each input variable
|
||||
*/
|
||||
extern word * Dsc_alloc_pool(int nVars) {
|
||||
return ABC_ALLOC(word, 3 * Abc_TtWordNum(nVars) * nVars);
|
||||
}
|
||||
|
||||
/**
|
||||
* just free the memory pool
|
||||
*/
|
||||
extern void Dsc_free_pool(word * pool) {
|
||||
ABC_FREE(pool);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method implements the paper proposed by V. Callegaro, F. S. Marranghello, M. G. A. Martins, R. P. Ribas and A. I. Reis,
|
||||
* entitled "Bottom-up disjoint-support decomposition based on cofactor and boolean difference analysis", presented at ICCD 2015.
|
||||
* pTruth: pointer for the truth table representing the target function.
|
||||
* nVarsInit: the number of variables of the truth table of the target function.
|
||||
* pRes: pointer for storing the resulting decomposition, whenever a decomposition can be found.
|
||||
* pool: NULL or a pointer for with a capacity of storing 3*nVars truth-tables. IF NULL, the function will allocate and free the memory of each call.
|
||||
* (the results presented on ICCD paper are running this method with NULL for the memory pool).
|
||||
* The method returns 0 if a full decomposition was found and a negative value otherwise.
|
||||
*/
|
||||
extern int Dsc_Decompose(word * pTruth, const int nVarsInit, char * const pRes, word *pool) {
|
||||
const int TRUTH_WORDS = Abc_TtWordNum(nVarsInit);
|
||||
const int NEED_POOL_ALLOC = (pool == NULL);
|
||||
|
||||
Dsc_node_t nodes[DSC_MAX_VAR];
|
||||
Dsc_node_t *newNodes[DSC_MAX_VAR];
|
||||
Dsc_node_t *oldNodes[DSC_MAX_VAR];
|
||||
|
||||
Dsc_node_t freeNodes[DSC_MAX_VAR]; // N is the maximum number of possible groups.
|
||||
int f = 0; // f represent the next free position in the freeNodes array
|
||||
int o = 0; // o stands for the number of already tested nodes
|
||||
int n = 0; // n will represent the number of current nodes (i.e. support)
|
||||
|
||||
pRes[0] = '\0';
|
||||
pRes[1] = '\0';
|
||||
|
||||
if (NEED_POOL_ALLOC)
|
||||
pool = ABC_ALLOC(word, 3 * TRUTH_WORDS * nVarsInit);
|
||||
|
||||
// block for the node data allocation
|
||||
{
|
||||
// pointer for the next free truth word
|
||||
word *pNextTruth = pool;
|
||||
int iVar;
|
||||
for (iVar = 0; iVar < nVarsInit; iVar++) {
|
||||
// negative cofactor
|
||||
Abc_TtCofactor0p(pNextTruth, pTruth, TRUTH_WORDS, iVar);
|
||||
// dont care test
|
||||
if (!Abc_TtEqual(pNextTruth, pTruth, TRUTH_WORDS)) {
|
||||
Dsc_node_t *node = &nodes[iVar];
|
||||
node->pNegCof = pNextTruth;
|
||||
// increment next truth pointer
|
||||
pNextTruth += TRUTH_WORDS;
|
||||
// positive cofactor
|
||||
node->pPosCof = pNextTruth;
|
||||
Abc_TtCofactor1p(node->pPosCof, pTruth, TRUTH_WORDS, iVar);
|
||||
// increment next truth pointer
|
||||
pNextTruth += TRUTH_WORDS;
|
||||
// boolean difference
|
||||
node->pBoolDiff = pNextTruth;
|
||||
Abc_TtXor(node->pBoolDiff, node->pNegCof, node->pPosCof, TRUTH_WORDS, 0);
|
||||
// increment next truth pointer
|
||||
pNextTruth += TRUTH_WORDS;
|
||||
// define on spec -
|
||||
node->on[0] = 1; node->on[1] = (iVar << 1) | 1u; // lit = i*2+1, when polarity=true
|
||||
// define off spec
|
||||
node->off[0] = 1; node->off[1] = iVar << 1;// lit=i*2 otherwise
|
||||
// store the node expression
|
||||
node->exp[0] = 'a'+iVar; // TODO fix the variable names
|
||||
node->exp[1] = '\0';
|
||||
// add the node to the newNodes array
|
||||
newNodes[n++] = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
//const int initialSupport = n;
|
||||
if (n == 0) {
|
||||
if (NEED_POOL_ALLOC)
|
||||
ABC_FREE(pool);
|
||||
if (Abc_TtIsConst0(pTruth, TRUTH_WORDS)) {
|
||||
{ if ( pRes ) pRes[0] = '0', pRes[1] = '\0'; }
|
||||
return 0;
|
||||
} else if (Abc_TtIsConst1(pTruth, TRUTH_WORDS)) {
|
||||
{ if ( pRes ) pRes[0] = '1', pRes[1] = '\0'; }
|
||||
return 0;
|
||||
} else {
|
||||
Abc_Print(-1, "ERROR. No variable in the support of f, but f isn't constant!\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
while (n > 0) {
|
||||
int tempN = 0;
|
||||
int i, j, iPolarity, jPolarity;
|
||||
Dsc_node_t *ni, *nj, *newNode = NULL;
|
||||
for (i = 0; i < n; i++) {
|
||||
ni = newNodes[i];
|
||||
newNode = NULL;
|
||||
j = 0;
|
||||
while (j < o) {
|
||||
nj = oldNodes[j];
|
||||
if (dsc_and_test(ni, nj, TRUTH_WORDS, &iPolarity, &jPolarity)) {
|
||||
newNode = &freeNodes[f++];
|
||||
dsc_and_group(newNode, ni, iPolarity, nj, jPolarity, nVarsInit, TRUTH_WORDS);
|
||||
}
|
||||
// XOR test
|
||||
if ((newNode == NULL) && (dsc_xor_test(ni, nj, TRUTH_WORDS))) {
|
||||
newNode = &freeNodes[f++];
|
||||
dsc_xor_group(newNode, ni, nj, nVarsInit, TRUTH_WORDS);
|
||||
}
|
||||
if (newNode != NULL) {
|
||||
oldNodes[j] = oldNodes[--o];
|
||||
break;
|
||||
} else {
|
||||
j++;
|
||||
}
|
||||
}
|
||||
if (newNode != NULL) {
|
||||
newNodes[tempN++] = newNode;
|
||||
} else {
|
||||
oldNodes[o++] = ni;
|
||||
}
|
||||
}
|
||||
n = tempN;
|
||||
}
|
||||
if (o == 1) {
|
||||
Dsc_node_t * solution = oldNodes[0];
|
||||
if (Abc_TtIsConst0(solution->pNegCof, TRUTH_WORDS) && Abc_TtIsConst1(solution->pPosCof, TRUTH_WORDS)) {
|
||||
// Direct solution found
|
||||
if ( pRes )
|
||||
strcpy( pRes, solution->exp);
|
||||
if (NEED_POOL_ALLOC)
|
||||
ABC_FREE(pool);
|
||||
return 0;
|
||||
} else if (Abc_TtIsConst1(solution->pNegCof, TRUTH_WORDS) && Abc_TtIsConst0(solution->pPosCof, TRUTH_WORDS)) {
|
||||
// Complementary solution found
|
||||
if ( pRes ) {
|
||||
pRes[0] = '!';
|
||||
strcpy( &pRes[1], solution->exp);
|
||||
}
|
||||
if (NEED_POOL_ALLOC)
|
||||
ABC_FREE(pool);
|
||||
return 0;
|
||||
} else {
|
||||
printf("DSC ERROR: Final DSC node found, but differs from target function.\n");
|
||||
if (NEED_POOL_ALLOC)
|
||||
ABC_FREE(pool);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (NEED_POOL_ALLOC)
|
||||
ABC_FREE(pool);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
Synopsis [DSD formula manipulation.]
|
||||
Description [Code copied from dauDsd.c but changed DAU_MAX_VAR to DSC_MAX_VAR]
|
||||
***********************************************************************/
|
||||
int * Dsc_ComputeMatches( char * p )
|
||||
{
|
||||
static int pMatches[DSC_MAX_VAR];
|
||||
int pNested[DSC_MAX_VAR];
|
||||
int v, nNested = 0;
|
||||
for ( v = 0; p[v]; v++ )
|
||||
{
|
||||
pMatches[v] = 0;
|
||||
if ( p[v] == '(' || p[v] == '[' || p[v] == '<' || p[v] == '{' )
|
||||
pNested[nNested++] = v;
|
||||
else if ( p[v] == ')' || p[v] == ']' || p[v] == '>' || p[v] == '}' )
|
||||
pMatches[pNested[--nNested]] = v;
|
||||
assert( nNested < DSC_MAX_VAR );
|
||||
}
|
||||
assert( nNested == 0 );
|
||||
return pMatches;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
Synopsis [DSD formula manipulation.]
|
||||
Description [Code copied from dauDsd.c but changed DAU_MAX_VAR to DSC_MAX_VAR]
|
||||
***********************************************************************/
|
||||
int Dsc_CountAnds_rec( char * pStr, char ** p, int * pMatches )
|
||||
{
|
||||
if ( **p == '!' )
|
||||
(*p)++;
|
||||
while ( (**p >= 'A' && **p <= 'F') || (**p >= '0' && **p <= '9') )
|
||||
(*p)++;
|
||||
if ( **p == '<' )
|
||||
{
|
||||
char * q = pStr + pMatches[*p - pStr];
|
||||
if ( *(q+1) == '{' )
|
||||
*p = q+1;
|
||||
}
|
||||
if ( **p >= 'a' && **p <= 'z' ) // var
|
||||
return 0;
|
||||
if ( **p == '(' || **p == '[' ) // and/or/xor
|
||||
{
|
||||
int Counter = 0, AddOn = (**p == '(')? 1 : 3;
|
||||
char * q = pStr + pMatches[ *p - pStr ];
|
||||
assert( *q == **p + 1 + (**p != '(') );
|
||||
for ( (*p)++; *p < q; (*p)++ )
|
||||
Counter += AddOn + Dsc_CountAnds_rec( pStr, p, pMatches );
|
||||
assert( *p == q );
|
||||
return Counter - AddOn;
|
||||
}
|
||||
if ( **p == '<' || **p == '{' ) // mux
|
||||
{
|
||||
int Counter = 3;
|
||||
char * q = pStr + pMatches[ *p - pStr ];
|
||||
assert( *q == **p + 1 + (**p != '(') );
|
||||
for ( (*p)++; *p < q; (*p)++ )
|
||||
Counter += Dsc_CountAnds_rec( pStr, p, pMatches );
|
||||
assert( *p == q );
|
||||
return Counter;
|
||||
}
|
||||
assert( 0 );
|
||||
return 0;
|
||||
}
|
||||
/**Function*************************************************************
|
||||
Synopsis [DSD formula manipulation.]
|
||||
Description [Code copied from dauDsd.c but changed DAU_MAX_VAR to DSC_MAX_VAR]
|
||||
***********************************************************************/
|
||||
extern int Dsc_CountAnds( char * pDsd )
|
||||
{
|
||||
if ( pDsd[1] == 0 )
|
||||
return 0;
|
||||
return Dsc_CountAnds_rec( pDsd, &pDsd, Dsc_ComputeMatches(pDsd) );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [dsc.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Disjoint support decomposition - ICCD'15]
|
||||
|
||||
Synopsis [Disjoint-support decomposition with cofactoring and boolean difference analysis
|
||||
from V. Callegaro, F. S. Marranghello, M. G. A. Martins, R. P. Ribas and A. I. Reis,
|
||||
"Bottom-up disjoint-support decomposition based on cofactor and boolean difference analysis," ICCD'15]
|
||||
|
||||
Author [Vinicius Callegaro, Mayler G. A. Martins, Felipe S. Marranghello, Renato P. Ribas and Andre I. Reis]
|
||||
|
||||
Affiliation [UFRGS - Federal University of Rio Grande do Sul - Brazil]
|
||||
|
||||
Date [Ver. 1.0. Started - October 24, 2014.]
|
||||
|
||||
Revision [$Id: dsc.h,v 1.00 2014/10/24 00:00:00 vcallegaro Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef ABC__DSC___h
|
||||
#define ABC__DSC___h
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "misc/util/abc_global.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ABC_NAMESPACE_HEADER_START
|
||||
|
||||
#define DSC_MAX_VAR 16 // should be 6 or more, i.e. DSC_MAX_VAR >= 6
|
||||
#define DSC_MAX_STR DSC_MAX_VAR << 2 // DSC_MAX_VAR * 4
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*=== dsc.c ==========================================================*/
|
||||
|
||||
/**
|
||||
* memory allocator with a capacity of storing 3*nVars
|
||||
* truth-tables for negative and positive cofactors and
|
||||
* the boolean difference for each input variable
|
||||
*/
|
||||
extern word * Dsc_alloc_pool(int nVars);
|
||||
|
||||
/**
|
||||
* This method implements the paper proposed by V. Callegaro, F. S. Marranghello, M. G. A. Martins, R. P. Ribas and A. I. Reis,
|
||||
* entitled "Bottom-up disjoint-support decomposition based on cofactor and boolean difference analysis", presented at ICCD 2015.
|
||||
* pTruth: pointer for the truth table representing the target function.
|
||||
* nVarsInit: the number of variables of the truth table of the target function.
|
||||
* pRes: pointer for storing the resulting decomposition, whenever a decomposition can be found.
|
||||
* pool: NULL or a pointer for with a capacity of storing 3*nVars truth-tables. IF NULL, the function will allocate and free the memory of each call.
|
||||
* (the results presented on ICCD paper are running this method with NULL for the memory pool).
|
||||
* The method returns 0 if a full decomposition was found and a negative value otherwise.
|
||||
*/
|
||||
extern int Dsc_Decompose(word * pTruth, const int nVarsInit, char * const pRes, word *pool);
|
||||
|
||||
/**
|
||||
* just free the memory pool
|
||||
*/
|
||||
extern void Dsc_free_pool(word * pool);
|
||||
|
||||
int * Dsc_ComputeMatches( char * p );
|
||||
int Dsc_CountAnds_rec( char * pStr, char ** p, int * pMatches );
|
||||
extern int Dsc_CountAnds( char * pDsd );
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -0,0 +1 @@
|
|||
SRC += src/opt/dsc/dsc.c
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
SRC += src/opt/sbd/sbd.c \
|
||||
src/opt/sbd/sbdCnf.c \
|
||||
src/opt/sbd/sbdCore.c \
|
||||
src/opt/sbd/sbdSat.c \
|
||||
src/opt/sbd/sbdWin.c
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [sbd.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [SAT-based optimization using internal don't-cares.]
|
||||
|
||||
Synopsis []
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: sbd.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "sbdInt.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [sbd.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [SAT-based optimization using internal don't-cares.]
|
||||
|
||||
Synopsis [External declarations.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: sbd.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef ABC__opt_sbd__h
|
||||
#define ABC__opt_sbd__h
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ABC_NAMESPACE_HEADER_START
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Sbd_Par_t_ Sbd_Par_t;
|
||||
struct Sbd_Par_t_
|
||||
{
|
||||
int nLutSize; // target LUT size
|
||||
int nTfoLevels; // the number of TFO levels (windowing)
|
||||
int nTfoFanMax; // the max number of fanouts (windowing)
|
||||
int nWinSizeMax; // maximum window size (windowing)
|
||||
int nBTLimit; // maximum number of SAT conflicts
|
||||
int nWords; // simulation word count
|
||||
int fArea; // area-oriented optimization
|
||||
int fCover; // use complete cover procedure
|
||||
int fVerbose; // verbose flag
|
||||
int fVeryVerbose; // verbose flag
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*=== sbdCnf.c ==========================================================*/
|
||||
/*=== sbdCore.c ==========================================================*/
|
||||
extern void Sbd_ParSetDefault( Sbd_Par_t * pPars );
|
||||
extern Gia_Man_t * Sbd_NtkPerform( Gia_Man_t * p, Sbd_Par_t * pPars );
|
||||
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -0,0 +1,147 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [sbdCnf.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [SAT-based optimization using internal don't-cares.]
|
||||
|
||||
Synopsis [CNF computation.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: sbdCnf.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "sbdInt.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Sbd_PrintCnf( Vec_Str_t * vCnf )
|
||||
{
|
||||
char Entry;
|
||||
int i, Lit;
|
||||
Vec_StrForEachEntry( vCnf, Entry, i )
|
||||
{
|
||||
Lit = (int)Entry;
|
||||
if ( Lit == -1 )
|
||||
printf( "\n" );
|
||||
else
|
||||
printf( "%s%d ", Abc_LitIsCompl(Lit) ? "-":"", Abc_Lit2Var(Lit) );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Sbd_TruthToCnf( word Truth, int nVars, Vec_Int_t * vCover, Vec_Str_t * vCnf )
|
||||
{
|
||||
Vec_StrClear( vCnf );
|
||||
if ( Truth == 0 || ~Truth == 0 )
|
||||
{
|
||||
// assert( nVars == 0 );
|
||||
Vec_StrPush( vCnf, (char)(Truth == 0) );
|
||||
Vec_StrPush( vCnf, (char)-1 );
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i, k, c, RetValue, Literal, Cube, nCubes = 0;
|
||||
assert( nVars > 0 );
|
||||
for ( c = 0; c < 2; c ++ )
|
||||
{
|
||||
Truth = c ? ~Truth : Truth;
|
||||
RetValue = Kit_TruthIsop( (unsigned *)&Truth, nVars, vCover, 0 );
|
||||
assert( RetValue == 0 );
|
||||
nCubes += Vec_IntSize( vCover );
|
||||
Vec_IntForEachEntry( vCover, Cube, i )
|
||||
{
|
||||
for ( k = 0; k < nVars; k++ )
|
||||
{
|
||||
Literal = 3 & (Cube >> (k << 1));
|
||||
if ( Literal == 1 ) // '0' -> pos lit
|
||||
Vec_StrPush( vCnf, (char)Abc_Var2Lit(k, 0) );
|
||||
else if ( Literal == 2 ) // '1' -> neg lit
|
||||
Vec_StrPush( vCnf, (char)Abc_Var2Lit(k, 1) );
|
||||
else if ( Literal != 0 )
|
||||
assert( 0 );
|
||||
}
|
||||
Vec_StrPush( vCnf, (char)Abc_Var2Lit(nVars, c) );
|
||||
Vec_StrPush( vCnf, (char)-1 );
|
||||
}
|
||||
}
|
||||
return nCubes;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Sbd_TranslateCnf( Vec_Wec_t * vRes, Vec_Str_t * vCnf, Vec_Int_t * vFaninMap, int iPivotVar )
|
||||
{
|
||||
Vec_Int_t * vClause;
|
||||
char Entry;
|
||||
int i, Lit;
|
||||
Vec_WecClear( vRes );
|
||||
vClause = Vec_WecPushLevel( vRes );
|
||||
Vec_StrForEachEntry( vCnf, Entry, i )
|
||||
{
|
||||
if ( (int)Entry == -1 )
|
||||
{
|
||||
vClause = Vec_WecPushLevel( vRes );
|
||||
continue;
|
||||
}
|
||||
Lit = Abc_Lit2LitV( Vec_IntArray(vFaninMap), (int)Entry );
|
||||
Lit = Abc_LitNotCond( Lit, Abc_Lit2Var(Lit) == iPivotVar );
|
||||
Vec_IntPush( vClause, Lit );
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,78 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [rsbInt.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [SAT-based optimization using internal don't-cares.]
|
||||
|
||||
Synopsis [Internal declarations.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: rsbInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef ABC__opt_sbdInt__h
|
||||
#define ABC__opt_sbdInt__h
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "misc/vec/vec.h"
|
||||
#include "sat/bsat/satSolver.h"
|
||||
#include "misc/util/utilNam.h"
|
||||
#include "misc/util/utilTruth.h"
|
||||
#include "map/scl/sclLib.h"
|
||||
#include "map/scl/sclCon.h"
|
||||
#include "bool/kit/kit.h"
|
||||
#include "misc/st/st.h"
|
||||
#include "map/mio/mio.h"
|
||||
#include "base/abc/abc.h"
|
||||
#include "sbd.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ABC_NAMESPACE_HEADER_START
|
||||
|
||||
#define SBD_SAT_UNDEC 0x1234567812345678
|
||||
#define SBD_SAT_SAT 0x8765432187654321
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*=== sbdCnf.c ==========================================================*/
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -0,0 +1,797 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [sbd.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [SAT-based optimization using internal don't-cares.]
|
||||
|
||||
Synopsis []
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: sbd.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "sbdInt.h"
|
||||
#include "misc/util/utilTruth.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define MAX_M 8 // max inputs
|
||||
#define MAX_N 30 // max nodes
|
||||
#define MAX_K 6 // max lutsize
|
||||
#define MAX_D 8 // max delays
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define SBD_LUTS_MAX 2
|
||||
#define SBD_SIZE_MAX 4
|
||||
#define SBD_DIV_MAX 16
|
||||
|
||||
// new AIG manager
|
||||
typedef struct Sbd_Pro_t_ Sbd_Pro_t;
|
||||
struct Sbd_Pro_t_
|
||||
{
|
||||
int nLuts; // LUT count
|
||||
int nSize; // LUT size
|
||||
int nDivs; // divisor count
|
||||
int nVars; // intermediate variables (nLuts * nSize)
|
||||
int nPars; // total parameter count (nLuts * (1 << nSize) + nLuts * nSize * nDivs)
|
||||
int pPars1[SBD_LUTS_MAX][1<<SBD_SIZE_MAX]; // lut parameters
|
||||
int pPars2[SBD_LUTS_MAX][SBD_SIZE_MAX][SBD_DIV_MAX]; // topo parameters
|
||||
int pVars[SBD_LUTS_MAX][SBD_SIZE_MAX+1]; // internal variables
|
||||
int pDivs[SBD_DIV_MAX]; // divisor variables (external)
|
||||
};
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Sbd_ProblemSetup( Sbd_Pro_t * p, int nLuts, int nSize, int nDivs )
|
||||
{
|
||||
Vec_Int_t * vCnf = Vec_IntAlloc( 1000 );
|
||||
int i, k, d, v, n, iVar = 0;
|
||||
assert( nLuts >= 1 && nLuts <= 2 );
|
||||
memset( p, 0, sizeof(Sbd_Pro_t) );
|
||||
p->nLuts = nLuts;
|
||||
p->nSize = nSize;
|
||||
p->nDivs = nDivs;
|
||||
p->nVars = nLuts * nSize;
|
||||
p->nPars = nLuts * (1 << nSize) + nLuts * nSize * nDivs;
|
||||
// set parameters
|
||||
for ( i = 0; i < nLuts; i++ )
|
||||
for ( k = 0; k < (1 << nSize); k++ )
|
||||
p->pPars1[i][k] = iVar++;
|
||||
for ( i = 0; i < nLuts; i++ )
|
||||
for ( k = 0; k < nSize; k++ )
|
||||
for ( d = 0; d < nDivs; d++ )
|
||||
p->pPars2[i][k][d] = iVar++;
|
||||
// set intermediate variables
|
||||
for ( i = 0; i < nLuts; i++ )
|
||||
for ( k = 0; k < nSize; k++ )
|
||||
p->pVars[i][k] = iVar++;
|
||||
// set top variables
|
||||
for ( i = 1; i < nLuts; i++ )
|
||||
p->pVars[i][nSize] = p->pVars[i-1][0];
|
||||
// set divisor variables
|
||||
for ( d = 0; d < nDivs; d++ )
|
||||
p->pDivs[d] = iVar++;
|
||||
assert( iVar == p->nPars + p->nVars + p->nDivs );
|
||||
|
||||
// input compatiblity clauses
|
||||
for ( i = 0; i < nLuts; i++ )
|
||||
for ( k = (i > 0); k < nSize; k++ )
|
||||
for ( d = 0; d < nDivs; d++ )
|
||||
for ( n = 0; n < nDivs; n++ )
|
||||
{
|
||||
if ( n < d )
|
||||
{
|
||||
Vec_IntPush( vCnf, Abc_Var2Lit(p->pPars2[i][k][d], 0) );
|
||||
Vec_IntPush( vCnf, Abc_Var2Lit(p->pPars2[i][k][n], 0) );
|
||||
Vec_IntPush( vCnf, -1 );
|
||||
}
|
||||
else if ( k < nSize-1 )
|
||||
{
|
||||
Vec_IntPush( vCnf, Abc_Var2Lit(p->pPars2[i][k][d], 0) );
|
||||
Vec_IntPush( vCnf, Abc_Var2Lit(p->pPars2[i][k+1][n], 0) );
|
||||
Vec_IntPush( vCnf, -1 );
|
||||
}
|
||||
}
|
||||
|
||||
// create LUT clauses
|
||||
for ( i = 0; i < nLuts; i++ )
|
||||
for ( k = 0; k < (1 << nSize); k++ )
|
||||
for ( n = 0; n < 2; n++ )
|
||||
{
|
||||
for ( v = 0; v < nSize; v++ )
|
||||
Vec_IntPush( vCnf, Abc_Var2Lit(p->pPars1[i][v], (k >> v) & 1) );
|
||||
Vec_IntPush( vCnf, Abc_Var2Lit(p->pVars[i][nSize], n) );
|
||||
Vec_IntPush( vCnf, Abc_Var2Lit(p->pPars1[i][k], !n) );
|
||||
Vec_IntPush( vCnf, -1 );
|
||||
}
|
||||
|
||||
// create input clauses
|
||||
for ( i = 0; i < nLuts; i++ )
|
||||
for ( k = (i > 0); k < nSize; k++ )
|
||||
for ( d = 0; d < nDivs; d++ )
|
||||
for ( n = 0; n < 2; n++ )
|
||||
{
|
||||
Vec_IntPush( vCnf, Abc_Var2Lit(p->pPars2[i][k][d], 0) );
|
||||
Vec_IntPush( vCnf, Abc_Var2Lit(p->pPars1[i][k], n) );
|
||||
Vec_IntPush( vCnf, Abc_Var2Lit(p->pDivs[d], !n) );
|
||||
Vec_IntPush( vCnf, -1 );
|
||||
}
|
||||
|
||||
return vCnf;
|
||||
}
|
||||
// add clauses to the don't-care computation solver
|
||||
void Sbd_ProblemLoad1( Sbd_Pro_t * p, Vec_Int_t * vCnf, int iStartVar, int * pDivVars, int iTopVar, sat_solver * pSat )
|
||||
{
|
||||
int pLits[8], nLits, i, k, iLit, RetValue;
|
||||
int ThisTopVar = p->pVars[0][p->nSize];
|
||||
int FirstDivVar = p->nPars + p->nVars;
|
||||
// add clauses
|
||||
for ( i = 0; i < Vec_IntSize(vCnf); i++ )
|
||||
{
|
||||
assert( Vec_IntEntry(vCnf, i) != -1 );
|
||||
for ( k = i+1; k < Vec_IntSize(vCnf); k++ )
|
||||
if ( Vec_IntEntry(vCnf, i) == -1 )
|
||||
break;
|
||||
nLits = 0;
|
||||
Vec_IntForEachEntryStartStop( vCnf, iLit, i, i, k ) {
|
||||
if ( Abc_Lit2Var(iLit) == ThisTopVar )
|
||||
pLits[nLits++] = Abc_Var2Lit( ThisTopVar, Abc_LitIsCompl(iLit) );
|
||||
else if ( Abc_Lit2Var(iLit) >= FirstDivVar )
|
||||
pLits[nLits++] = Abc_Var2Lit( pDivVars[Abc_Lit2Var(iLit)-FirstDivVar], Abc_LitIsCompl(iLit) );
|
||||
else
|
||||
pLits[nLits++] = iLit + 2 * iStartVar;
|
||||
}
|
||||
assert( nLits <= 8 );
|
||||
RetValue = sat_solver_addclause( pSat, pLits, pLits + nLits );
|
||||
assert( RetValue );
|
||||
}
|
||||
}
|
||||
// add clauses to the functionality evaluation solver
|
||||
void Sbd_ProblemLoad2( Sbd_Pro_t * p, Vec_Wec_t * vCnf, int iStartVar, int * pDivVarValues, int iTopVarValue, sat_solver * pSat )
|
||||
{
|
||||
Vec_Int_t * vLevel;
|
||||
int pLits[8], nLits, i, k, iLit, RetValue;
|
||||
int ThisTopVar = p->pVars[0][p->nSize];
|
||||
int FirstDivVar = p->nPars + p->nVars;
|
||||
int FirstIntVar = p->nPars;
|
||||
// add clauses
|
||||
Vec_WecForEachLevel( vCnf, vLevel, i )
|
||||
{
|
||||
nLits = 0;
|
||||
Vec_IntForEachEntry( vLevel, iLit, k ) {
|
||||
if ( Abc_Lit2Var(iLit) == ThisTopVar )
|
||||
{
|
||||
if ( Abc_LitIsCompl(iLit) == iTopVarValue )
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
else if ( Abc_Lit2Var(iLit) >= FirstDivVar )
|
||||
{
|
||||
if ( Abc_LitIsCompl(iLit) == pDivVarValues[Abc_Lit2Var(iLit)-FirstDivVar] )
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
else if ( Abc_Lit2Var(iLit) >= FirstIntVar )
|
||||
pLits[nLits++] = iLit + 2 * iStartVar;
|
||||
else
|
||||
pLits[nLits++] = iLit;
|
||||
}
|
||||
if ( k < Vec_IntSize(vLevel) )
|
||||
continue;
|
||||
assert( nLits <= 8 );
|
||||
RetValue = sat_solver_addclause( pSat, pLits, pLits + nLits );
|
||||
assert( RetValue );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
sat_solver * Sbd_SolverTopo( int M, int N, int K, int pVars[MAX_N][MAX_M+MAX_N][MAX_K], int pVars2[MAX_M+MAX_N][MAX_D], int pDelays[], int Req, int * pnVars ) // inputs, nodes, lutsize
|
||||
{
|
||||
sat_solver * pSat = NULL;
|
||||
Vec_Int_t * vTemp = Vec_IntAlloc(100);
|
||||
// assign vars
|
||||
int RetValue, n, i, j, j2, k, k2, d, Count, nVars = 0;
|
||||
for ( n = 0; n < N; n++ )
|
||||
for ( i = 0; i < M+N; i++ )
|
||||
for ( k = 0; k < K; k++ )
|
||||
pVars[n][i][k] = -1;
|
||||
for ( n = 0; n < N; n++ )
|
||||
for ( i = 0; i < M+n; i++ )
|
||||
for ( k = 0; k < K; k++ )
|
||||
pVars[n][i][k] = nVars++;
|
||||
printf( "Number of topo vars = %d.\n", nVars );
|
||||
*pnVars = nVars;
|
||||
// add constraints
|
||||
pSat = sat_solver_new();
|
||||
sat_solver_setnvars( pSat, nVars );
|
||||
// each node is used
|
||||
for ( i = 0; i < M+N-1; i++ )
|
||||
{
|
||||
Vec_IntClear( vTemp );
|
||||
for ( n = 0; n < N; n++ )
|
||||
for ( k = 0; k < K; k++ )
|
||||
if ( pVars[n][i][k] >= 0 )
|
||||
Vec_IntPush( vTemp, Abc_Var2Lit(pVars[n][i][k], 0) );
|
||||
RetValue = sat_solver_addclause( pSat, Vec_IntArray(vTemp), Vec_IntLimit(vTemp) );
|
||||
assert( RetValue );
|
||||
}
|
||||
printf( "Added %d node connectivity constraints.\n", i );
|
||||
// each fanin of each node is connected exactly once
|
||||
Count = 0;
|
||||
for ( n = 0; n < N; n++ )
|
||||
for ( k = 0; k < K; k++ )
|
||||
{
|
||||
// connected
|
||||
Vec_IntClear( vTemp );
|
||||
for ( i = 0; i < M+n; i++ )
|
||||
Vec_IntPush( vTemp, Abc_Var2Lit(pVars[n][i][k], 0) );
|
||||
RetValue = sat_solver_addclause( pSat, Vec_IntArray(vTemp), Vec_IntLimit(vTemp) );
|
||||
assert( RetValue );
|
||||
// exactly once
|
||||
for ( i = 0; i < M+n; i++ )
|
||||
for ( j = i+1; j < M+n; j++ )
|
||||
{
|
||||
Vec_IntFillTwo( vTemp, 2, Abc_Var2Lit(pVars[n][i][k], 1), Abc_Var2Lit(pVars[n][j][k], 1) );
|
||||
RetValue = sat_solver_addclause( pSat, Vec_IntArray(vTemp), Vec_IntLimit(vTemp) );
|
||||
assert( RetValue );
|
||||
Count++;
|
||||
}
|
||||
}
|
||||
printf( "Added %d fanin connectivity constraints.\n", Count );
|
||||
// node fanins are unique
|
||||
Count = 0;
|
||||
for ( n = 0; n < N; n++ )
|
||||
for ( i = 0; i < M+n; i++ )
|
||||
for ( k = 0; k < K; k++ )
|
||||
for ( j = i; j < M+n; j++ )
|
||||
for ( k2 = k+1; k2 < K; k2++ )
|
||||
{
|
||||
Vec_IntFillTwo( vTemp, 2, Abc_Var2Lit(pVars[n][i][k], 1), Abc_Var2Lit(pVars[n][j][k2], 1) );
|
||||
RetValue = sat_solver_addclause( pSat, Vec_IntArray(vTemp), Vec_IntLimit(vTemp) );
|
||||
assert( RetValue );
|
||||
Count++;
|
||||
}
|
||||
printf( "Added %d fanin exclusivity constraints.\n", Count );
|
||||
// nodes are ordered
|
||||
Count = 0;
|
||||
for ( n = 1; n < N; n++ )
|
||||
for ( i = 0; i < M+n-1; i++ )
|
||||
{
|
||||
// first of n cannot be smaller than first of n-1 (but can be equal)
|
||||
for ( j = i+1; j < M+n-1; j++ )
|
||||
{
|
||||
Vec_IntFillTwo( vTemp, 2, Abc_Var2Lit(pVars[n][i][0], 1), Abc_Var2Lit(pVars[n-1][j][0], 1) );
|
||||
RetValue = sat_solver_addclause( pSat, Vec_IntArray(vTemp), Vec_IntLimit(vTemp) );
|
||||
assert( RetValue );
|
||||
Count++;
|
||||
}
|
||||
// if first nodes of n and n-1 are equal, second nodes are ordered
|
||||
Vec_IntFillTwo( vTemp, 2, Abc_Var2Lit(pVars[n][i][0], 1), Abc_Var2Lit(pVars[n-1][i][0], 1) );
|
||||
for ( j = 0; j < i; j++ )
|
||||
for ( j2 = j+1; j2 < i; j2++ )
|
||||
{
|
||||
Vec_IntPushTwo( vTemp, Abc_Var2Lit(pVars[n][j][1], 1), Abc_Var2Lit(pVars[n-1][j2][1], 1) );
|
||||
RetValue = sat_solver_addclause( pSat, Vec_IntArray(vTemp), Vec_IntLimit(vTemp) );
|
||||
assert( RetValue );
|
||||
Vec_IntShrink( vTemp, 2 );
|
||||
Count++;
|
||||
}
|
||||
}
|
||||
printf( "Added %d node ordering constraints.\n", Count );
|
||||
// exclude fanins of two-input nodes
|
||||
Count = 0;
|
||||
if ( K == 2 )
|
||||
for ( n = 1; n < N; n++ )
|
||||
for ( i = M; i < M+n; i++ )
|
||||
for ( j = 0; j < i; j++ )
|
||||
for ( k = 0; k < K; k++ )
|
||||
{
|
||||
Vec_IntClear( vTemp );
|
||||
Vec_IntPush( vTemp, Abc_Var2Lit(pVars[n][i][0], 1) );
|
||||
Vec_IntPush( vTemp, Abc_Var2Lit(pVars[n][j][1], 1) );
|
||||
Vec_IntPush( vTemp, Abc_Var2Lit(pVars[i-M][j][k], 1) );
|
||||
RetValue = sat_solver_addclause( pSat, Vec_IntArray(vTemp), Vec_IntLimit(vTemp) );
|
||||
assert( RetValue );
|
||||
Count++;
|
||||
}
|
||||
printf( "Added %d two-node non-triviality constraints.\n", Count );
|
||||
|
||||
|
||||
// assign delay vars
|
||||
assert( Req < MAX_D-1 );
|
||||
for ( i = 0; i < M+N; i++ )
|
||||
for ( d = 0; d < MAX_D; d++ )
|
||||
pVars2[i][d] = nVars++;
|
||||
printf( "Number of total vars = %d.\n", nVars );
|
||||
// set input delays
|
||||
for ( i = 0; i < M; i++ )
|
||||
{
|
||||
assert( pDelays[i] < MAX_D-2 );
|
||||
Vec_IntFill( vTemp, 1, Abc_Var2Lit(pVars2[i][pDelays[i]], 0) );
|
||||
RetValue = sat_solver_addclause( pSat, Vec_IntArray(vTemp), Vec_IntLimit(vTemp) );
|
||||
assert( RetValue );
|
||||
}
|
||||
// set output delay
|
||||
for ( k = Req; k < MAX_D; k++ )
|
||||
{
|
||||
Vec_IntFill( vTemp, 1, Abc_Var2Lit(pVars2[M+N-1][Req+1], 1) );
|
||||
RetValue = sat_solver_addclause( pSat, Vec_IntArray(vTemp), Vec_IntLimit(vTemp) );
|
||||
assert( RetValue );
|
||||
}
|
||||
// set internal nodes
|
||||
for ( n = 0; n < N; n++ )
|
||||
for ( i = 0; i < M+n; i++ )
|
||||
for ( k = 0; k < K; k++ )
|
||||
for ( d = 0; d < MAX_D-1; d++ )
|
||||
{
|
||||
Vec_IntFill( vTemp, 1, Abc_Var2Lit(pVars[n][i][k], 1) );
|
||||
Vec_IntPush( vTemp, Abc_Var2Lit(pVars2[i][d], 1) );
|
||||
Vec_IntPush( vTemp, Abc_Var2Lit(pVars2[M+n][d+1], 0) );
|
||||
RetValue = sat_solver_addclause( pSat, Vec_IntArray(vTemp), Vec_IntLimit(vTemp) );
|
||||
assert( RetValue );
|
||||
}
|
||||
|
||||
|
||||
Vec_IntFree( vTemp );
|
||||
return pSat;
|
||||
}
|
||||
void Sbd_SolverTopoPrint( sat_solver * pSat, int M, int N, int K, int pVars[MAX_N][MAX_M+MAX_N][MAX_K] )
|
||||
{
|
||||
int n, i, k;
|
||||
printf( "Solution:\n" );
|
||||
printf( " | " );
|
||||
for ( n = 0; n < N; n++ )
|
||||
printf( "%2d ", M+n );
|
||||
printf( "\n" );
|
||||
for ( i = M+N-2; i >= 0; i-- )
|
||||
{
|
||||
printf( "%2d %c | ", i, i < M ? 'i' : ' ' );
|
||||
for ( n = 0; n < N; n++ )
|
||||
{
|
||||
for ( k = K-1; k >= 0; k-- )
|
||||
if ( pVars[n][i][k] == -1 )
|
||||
printf( " " );
|
||||
else
|
||||
printf( "%c", sat_solver_var_value(pSat, pVars[n][i][k]) ? '*' : '.' );
|
||||
printf( " " );
|
||||
}
|
||||
printf( "\n" );
|
||||
}
|
||||
}
|
||||
void Sbd_SolverTopoTest()
|
||||
{
|
||||
int M = 8; // 6; // inputs
|
||||
int N = 3; // 16; // nodes
|
||||
int K = 4; // 2; // lutsize
|
||||
int status, v, nVars, nIter, nSols = 0;
|
||||
int pVars[MAX_N][MAX_M+MAX_N][MAX_K]; // 20 x 32 x 6 = 3840
|
||||
int pVars2[MAX_M+MAX_N][MAX_D]; // 20 x 32 x 6 = 3840
|
||||
int pDelays[MAX_M] = {1,0,0,0,1};
|
||||
abctime clk = Abc_Clock();
|
||||
Vec_Int_t * vLits = Vec_IntAlloc(100);
|
||||
sat_solver * pSat = Sbd_SolverTopo( M, N, K, pVars, pVars2, pDelays, 2, &nVars );
|
||||
for ( nIter = 0; nIter < 1000000; nIter++ )
|
||||
{
|
||||
// find onset minterm
|
||||
status = sat_solver_solve( pSat, NULL, NULL, 0, 0, 0, 0 );
|
||||
if ( status == l_Undef )
|
||||
break;
|
||||
if ( status == l_False )
|
||||
break;
|
||||
assert( status == l_True );
|
||||
nSols++;
|
||||
// print solution
|
||||
if ( nIter < 5 )
|
||||
Sbd_SolverTopoPrint( pSat, M, N, K, pVars );
|
||||
// remember variable values
|
||||
Vec_IntClear( vLits );
|
||||
for ( v = 0; v < nVars; v++ )
|
||||
if ( sat_solver_var_value(pSat, v) )
|
||||
Vec_IntPush( vLits, Abc_Var2Lit(v, 1) );
|
||||
// add breaking clause
|
||||
status = sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits) );
|
||||
if ( status == 0 )
|
||||
break;
|
||||
//if ( nIter == 5 )
|
||||
// break;
|
||||
}
|
||||
sat_solver_delete( pSat );
|
||||
Vec_IntFree( vLits );
|
||||
printf( "Found %d solutions. ", nSols );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Synthesize random topology.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Sbd_SolverSynth( int M, int N, int K, int pLuts[MAX_N][MAX_K] )
|
||||
{
|
||||
int Used[MAX_M+MAX_N] = {0};
|
||||
int nUnused = M;
|
||||
int n, iFan0, iFan1;
|
||||
srand( time(NULL) );
|
||||
for ( n = 0; nUnused < N - n; n++ )
|
||||
{
|
||||
iFan0 = iFan1 = 0;
|
||||
while ( (iFan0 = rand() % (M + n)) == (iFan1 = rand() % (M + n)) )
|
||||
;
|
||||
pLuts[n][0] = iFan0;
|
||||
pLuts[n][1] = iFan1;
|
||||
if ( Used[iFan0] == 0 )
|
||||
{
|
||||
Used[iFan0] = 1;
|
||||
nUnused--;
|
||||
}
|
||||
if ( Used[iFan1] == 0 )
|
||||
{
|
||||
Used[iFan1] = 1;
|
||||
nUnused--;
|
||||
}
|
||||
nUnused++;
|
||||
}
|
||||
if ( nUnused == N - n )
|
||||
{
|
||||
// undo the first one
|
||||
for ( iFan0 = 0; iFan0 < M+n; iFan0++ )
|
||||
if ( Used[iFan0] )
|
||||
{
|
||||
Used[iFan0] = 0;
|
||||
nUnused++;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
assert( nUnused == N - n + 1 );
|
||||
for ( ; n < N; n++ )
|
||||
{
|
||||
for ( iFan0 = 0; iFan0 < M+n; iFan0++ )
|
||||
if ( Used[iFan0] == 0 )
|
||||
{
|
||||
Used[iFan0] = 1;
|
||||
break;
|
||||
}
|
||||
assert( iFan0 < M+n );
|
||||
for ( iFan1 = 0; iFan1 < M+n; iFan1++ )
|
||||
if ( Used[iFan1] == 0 )
|
||||
{
|
||||
Used[iFan1] = 1;
|
||||
break;
|
||||
}
|
||||
assert( iFan1 < M+n );
|
||||
pLuts[n][0] = iFan0;
|
||||
pLuts[n][1] = iFan1;
|
||||
}
|
||||
|
||||
printf( "{\n" );
|
||||
for ( n = 0; n < N; n++ )
|
||||
printf( " {%d, %d}%s // %d\n", pLuts[n][0], pLuts[n][1], n==N-1 ? "" :",", M+n );
|
||||
printf( "};\n" );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Compute truth table for the given parameter settings.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
word Sbd_SolverTruth( int M, int N, int K, int pLuts[MAX_N][MAX_K], int pValues[MAX_N*((1<<MAX_K)-1)] )
|
||||
{
|
||||
int i, k, v, nLutPars = (1 << K) - 1;
|
||||
word Truths[MAX_M+MAX_N];
|
||||
assert( M <= 6 && N <= MAX_N );
|
||||
for ( i = 0; i < M; i++ )
|
||||
Truths[i] = s_Truths6[i];
|
||||
for ( i = 0; i < N; i++ )
|
||||
{
|
||||
word Truth = 0, Mint;
|
||||
for ( k = 1; k <= nLutPars; k++ )
|
||||
{
|
||||
if ( !pValues[i*nLutPars+k-1] )
|
||||
continue;
|
||||
Mint = ~(word)0;
|
||||
for ( v = 0; v < K; v++ )
|
||||
Mint &= ((k >> v) & 1) ? Truths[pLuts[i][v]] : ~Truths[pLuts[i][v]];
|
||||
Truth |= Mint;
|
||||
}
|
||||
Truths[M+i] = Truth;
|
||||
}
|
||||
return Truths[M+N-1];
|
||||
}
|
||||
word * Sbd_SolverTruthWord( int M, int N, int K, int pLuts[MAX_N][MAX_K], int pValues[MAX_N*((1<<MAX_K)-1)], word * pTruthsElem, int fCompl )
|
||||
{
|
||||
int i, k, v, nLutPars = (1 << K) - 1;
|
||||
int nWords = Abc_TtWordNum( M );
|
||||
word * pRes = pTruthsElem + (M+N-1)*nWords;
|
||||
assert( M <= MAX_M && N <= MAX_N );
|
||||
for ( i = 0; i < N; i++ )
|
||||
{
|
||||
word * pMint, * pTruth = pTruthsElem + (M+i)*nWords;
|
||||
Abc_TtClear( pTruth, nWords );
|
||||
for ( k = 1; k <= nLutPars; k++ )
|
||||
{
|
||||
if ( !pValues[i*nLutPars+k-1] )
|
||||
continue;
|
||||
pMint = pTruthsElem + (M+N)*nWords;
|
||||
Abc_TtFill( pMint, nWords );
|
||||
for ( v = 0; v < K; v++ )
|
||||
{
|
||||
word * pFanin = pTruthsElem + pLuts[i][v]*nWords;
|
||||
Abc_TtAndSharp( pMint, pMint, pFanin, nWords, ((k >> v) & 1) == 0 );
|
||||
}
|
||||
Abc_TtOr( pTruth, pTruth, pMint, nWords );
|
||||
}
|
||||
}
|
||||
if ( fCompl )
|
||||
Abc_TtNot( pRes, nWords );
|
||||
return pRes;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Sbd_SolverFunc( int M, int N, int K, int pLuts[MAX_N][MAX_K], word * pTruthInit, int * pValues )
|
||||
{
|
||||
int fVerbose = 0;
|
||||
abctime clk = Abc_Clock();
|
||||
abctime clk2, clkOther = 0;
|
||||
sat_solver * pSat = NULL;
|
||||
int nWords = Abc_TtWordNum(M);
|
||||
int pLits[MAX_K+2], pLits2[MAX_K+2], nLits;
|
||||
int nLutPars = (1 << K) - 1, nVars = N * nLutPars;
|
||||
int i, k, m, status, iMint, Iter, fCompl = (int)(pTruthInit[0] & 1);
|
||||
// create truth tables
|
||||
word * pTruthNew, * pTruths = ABC_ALLOC( word, Abc_TtWordNum(MAX_N) * (MAX_M + MAX_N + 1) );
|
||||
Abc_TtElemInit2( pTruths, M );
|
||||
// create solver
|
||||
pSat = sat_solver_new();
|
||||
sat_solver_setnvars( pSat, nVars );
|
||||
printf( "Number of parameters %d x %d = %d.\n", N, nLutPars, nVars );
|
||||
// start with the last minterm
|
||||
// iMint = (1 << M) - 1;
|
||||
iMint = 1;
|
||||
for ( Iter = 0; Iter < (1 << M); Iter++ )
|
||||
{
|
||||
// assign the first intermediate variable
|
||||
int nVarStart = sat_solver_nvars(pSat);
|
||||
sat_solver_setnvars( pSat, nVarStart + N - 1 );
|
||||
// add clauses for nodes
|
||||
//if ( fVerbose )
|
||||
printf( "Iter %3d : Mint = %3d. Conflicts =%8d.\n", Iter, iMint, sat_solver_nconflicts(pSat) );
|
||||
for ( i = 0; i < N; i++ )
|
||||
for ( m = 0; m <= nLutPars; m++ )
|
||||
{
|
||||
if ( fVerbose )
|
||||
printf( "i = %d. m = %d.\n", i, m );
|
||||
// selector variables
|
||||
nLits = 0;
|
||||
for ( k = 0; k < K; k++ )
|
||||
{
|
||||
if ( pLuts[i][k] >= M )
|
||||
{
|
||||
assert( pLuts[i][k] - M < N - 1 );
|
||||
pLits[nLits] = pLits2[nLits] = Abc_Var2Lit( nVarStart + pLuts[i][k] - M, (m >> k) & 1 );
|
||||
nLits++;
|
||||
}
|
||||
else if ( ((iMint >> pLuts[i][k]) & 1) != ((m >> k) & 1) )
|
||||
break;
|
||||
}
|
||||
if ( k < K )
|
||||
continue;
|
||||
// add parameter
|
||||
if ( m )
|
||||
{
|
||||
pLits[nLits] = Abc_Var2Lit( i*nLutPars + m-1, 1 );
|
||||
pLits2[nLits] = Abc_Var2Lit( i*nLutPars + m-1, 0 );
|
||||
nLits++;
|
||||
}
|
||||
// node variable
|
||||
if ( i != N - 1 )
|
||||
{
|
||||
pLits[nLits] = Abc_Var2Lit( nVarStart + i, 0 );
|
||||
pLits2[nLits] = Abc_Var2Lit( nVarStart + i, 1 );
|
||||
nLits++;
|
||||
}
|
||||
// add clauses
|
||||
if ( i != N - 1 || Abc_TtGetBit(pTruthInit, iMint) != fCompl )
|
||||
{
|
||||
status = sat_solver_addclause( pSat, pLits2, pLits2 + nLits );
|
||||
if ( status == 0 )
|
||||
{
|
||||
fCompl = -1;
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
if ( (i != N - 1 || Abc_TtGetBit(pTruthInit, iMint) == fCompl) && m > 0 )
|
||||
{
|
||||
status = sat_solver_addclause( pSat, pLits, pLits + nLits );
|
||||
if ( status == 0 )
|
||||
{
|
||||
fCompl = -1;
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// run SAT solver
|
||||
status = sat_solver_solve( pSat, NULL, NULL, 0, 0, 0, 0 );
|
||||
if ( status == l_Undef )
|
||||
break;
|
||||
if ( status == l_False )
|
||||
{
|
||||
fCompl = -1;
|
||||
goto finish;
|
||||
}
|
||||
assert( status == l_True );
|
||||
|
||||
// collect values
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
pValues[i] = sat_solver_var_value(pSat, i);
|
||||
|
||||
clk2 = Abc_Clock();
|
||||
pTruthNew = Sbd_SolverTruthWord( M, N, K, pLuts, pValues, pTruths, fCompl );
|
||||
clkOther += Abc_Clock() - clk2;
|
||||
|
||||
if ( fVerbose )
|
||||
{
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
printf( "%d=%d ", i, pValues[i] );
|
||||
printf( " " );
|
||||
for ( i = nVars; i < sat_solver_nvars(pSat); i++ )
|
||||
printf( "%d=%d ", i, sat_solver_var_value(pSat, i) );
|
||||
printf( "\n" );
|
||||
Extra_PrintBinary( stdout, (unsigned *)pTruthInit, (1 << M) ); printf( "\n" );
|
||||
Extra_PrintBinary( stdout, (unsigned *)pTruthNew, (1 << M) ); printf( "\n" );
|
||||
}
|
||||
if ( Abc_TtEqual(pTruthInit, pTruthNew, nWords) )
|
||||
break;
|
||||
|
||||
// get new minterm
|
||||
iMint = Abc_TtFindFirstDiffBit( pTruthInit, pTruthNew, M );
|
||||
}
|
||||
finish:
|
||||
printf( "Finished after %d iterations and %d conflicts. ", Iter, sat_solver_nconflicts(pSat) );
|
||||
sat_solver_delete( pSat );
|
||||
ABC_FREE( pTruths );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
||||
Abc_PrintTime( 1, "Time", clkOther );
|
||||
return fCompl;
|
||||
}
|
||||
void Sbd_SolverFuncTest()
|
||||
{
|
||||
// int M = 4; // 6; // inputs
|
||||
// int N = 3; // 16; // nodes
|
||||
// int K = 2; // 2; // lutsize
|
||||
// word Truth = ~((word)3 << 8);
|
||||
// int pLuts[MAX_N][MAX_K] = { {0,1}, {2,3}, {4,5}, {6,7}, {8,9} };
|
||||
|
||||
/*
|
||||
int M = 6; // 6; // inputs
|
||||
int N = 19; // 16; // nodes
|
||||
int K = 2; // 2; // lutsize
|
||||
word pTruth[4] = { ABC_CONST(0x9ef7a8d9c7193a0f), 0, 0, 0 };
|
||||
int pLuts[MAX_N][MAX_K] = {
|
||||
{3, 5}, {1, 6}, {0, 5}, {8, 2}, {7, 9},
|
||||
{0, 1}, {2, 11}, {5, 12}, {3, 13}, {1, 14},
|
||||
{10, 15}, {11, 2}, {3, 17}, {9, 18}, {0, 13},
|
||||
{20, 7}, {19, 21}, {4, 16}, {23, 22}
|
||||
};
|
||||
*/
|
||||
|
||||
/*
|
||||
int M = 6; // 6; // inputs
|
||||
int N = 5; // 16; // nodes
|
||||
int K = 4; // 2; // lutsize
|
||||
word Truth = ABC_CONST(0x9ef7a8d9c7193a0f);
|
||||
int pLuts[MAX_N][MAX_K] = {
|
||||
{0, 1, 2, 3}, // 6
|
||||
{1, 2, 3, 4}, // 7
|
||||
{2, 3, 4, 5}, // 8
|
||||
{0, 1, 4, 5}, // 9
|
||||
{6, 7, 8, 9} // 10
|
||||
};
|
||||
*/
|
||||
|
||||
/*
|
||||
int M = 8; // 6; // inputs
|
||||
int N = 7; // 16; // nodes
|
||||
int K = 2; // 2; // lutsize
|
||||
// word pTruth[4] = { 0, 0, 0, ABC_CONST(0x8000000000000000) };
|
||||
// word pTruth[4] = { ABC_CONST(0x0000000000000001), 0, 0, 0 };
|
||||
word pTruth[4] = { 0, 0, 0, ABC_CONST(0x0000000000020000) };
|
||||
int pLuts[MAX_N][MAX_K] = { {0,1}, {2,3}, {4,5}, {6,7}, {8,9}, {10,11}, {12,13} };
|
||||
*/
|
||||
|
||||
int M = 8; // 6; // inputs
|
||||
int N = 7; // 16; // nodes
|
||||
int K = 2; // 2; // lutsize
|
||||
word pTruth[4] = { ABC_CONST(0x0000080000020000), ABC_CONST(0x0000000000020000), ABC_CONST(0x0000000000000000), ABC_CONST(0x0000000000020000) };
|
||||
int pLuts[MAX_N][MAX_K] = { {0,1}, {2,3}, {4,5}, {6,7}, {8,9}, {10,11}, {12,13} };
|
||||
|
||||
int pValues[MAX_N*((1<<MAX_K)-1)];
|
||||
int Res, i, k, nLutPars = (1 << K) - 1;
|
||||
|
||||
//Sbd_SolverSynth( M, N, K, pLuts );
|
||||
|
||||
Res = Sbd_SolverFunc( M, N, K, pLuts, pTruth, pValues );
|
||||
if ( Res == -1 )
|
||||
{
|
||||
printf( "Solution does not exist.\n" );
|
||||
return;
|
||||
}
|
||||
printf( "Result (compl = %d):\n", Res );
|
||||
for ( i = 0; i < N; i++ )
|
||||
{
|
||||
for ( k = nLutPars-1; k >= 0; k-- )
|
||||
printf( "%d", pValues[i*nLutPars+k] );
|
||||
printf( "0\n" );
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
@ -0,0 +1,310 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [sbdSim.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [SAT-based optimization using internal don't-cares.]
|
||||
|
||||
Synopsis [Simulation.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: sbdSim.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "sbdInt.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline word * Sbd_ObjSims( Gia_Man_t * p, int i ) { return Vec_WrdEntryP( p->vSims, p->iPatsPi * i ); }
|
||||
static inline word * Sbd_ObjCtrl( Gia_Man_t * p, int i ) { return Vec_WrdEntryP( p->vSimsPi, p->iPatsPi * i ); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [This does not work.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Sbd_GiaSimRoundBack2( Gia_Man_t * p )
|
||||
{
|
||||
int nWords = p->iPatsPi;
|
||||
Gia_Obj_t * pObj;
|
||||
int w, i, Id;
|
||||
// init primary outputs
|
||||
Gia_ManForEachCoId( p, Id, i )
|
||||
for ( w = 0; w < nWords; w++ )
|
||||
Sbd_ObjSims(p, Id)[w] = Gia_ManRandomW(0);
|
||||
// transfer to nodes
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
{
|
||||
word * pSims = Sbd_ObjSims(p, Gia_ObjId(p, pObj));
|
||||
Abc_TtCopy( Sbd_ObjSims(p, Gia_ObjFaninId0p(p, pObj)), pSims, nWords, Gia_ObjFaninC0(pObj) );
|
||||
}
|
||||
// simulate nodes
|
||||
Gia_ManForEachAndReverse( p, pObj, i )
|
||||
{
|
||||
word * pSims = Sbd_ObjSims(p, i);
|
||||
word * pSims0 = Sbd_ObjSims(p, Gia_ObjFaninId0(pObj, i));
|
||||
word * pSims1 = Sbd_ObjSims(p, Gia_ObjFaninId1(pObj, i));
|
||||
word Rand = Gia_ManRandomW(0);
|
||||
for ( w = 0; w < nWords; w++ )
|
||||
{
|
||||
pSims0[w] = pSims[w] | Rand;
|
||||
pSims1[w] = pSims[w] | ~Rand;
|
||||
}
|
||||
if ( Gia_ObjFaninC0(pObj) ) Abc_TtNot( pSims0, nWords );
|
||||
if ( Gia_ObjFaninC1(pObj) ) Abc_TtNot( pSims1, nWords );
|
||||
}
|
||||
// primary inputs are initialized
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Tries to falsify a sequence of two-literal SAT problems.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Sbd_GiaSatOne_rec( Gia_Man_t * p, Gia_Obj_t * pObj, int Value, int fFirst, int iPat )
|
||||
{
|
||||
if ( Gia_ObjIsTravIdCurrent(p, pObj) )
|
||||
return (int)pObj->fMark0 == Value;
|
||||
Gia_ObjSetTravIdCurrent(p, pObj);
|
||||
pObj->fMark0 = Value;
|
||||
if ( Gia_ObjIsCi(pObj) )
|
||||
{
|
||||
word * pSims = Sbd_ObjSims(p, Gia_ObjId(p, pObj));
|
||||
if ( Abc_TtGetBit( pSims, iPat ) != Value )
|
||||
Abc_TtXorBit( pSims, iPat );
|
||||
return 1;
|
||||
}
|
||||
assert( Gia_ObjIsAnd(pObj) );
|
||||
assert( !Gia_ObjIsXor(pObj) );
|
||||
if ( Value )
|
||||
return Sbd_GiaSatOne_rec( p, Gia_ObjFanin0(pObj), !Gia_ObjFaninC0(pObj), fFirst, iPat ) &&
|
||||
Sbd_GiaSatOne_rec( p, Gia_ObjFanin1(pObj), !Gia_ObjFaninC1(pObj), fFirst, iPat );
|
||||
if ( fFirst )
|
||||
return Sbd_GiaSatOne_rec( p, Gia_ObjFanin0(pObj), Gia_ObjFaninC0(pObj), fFirst, iPat );
|
||||
else
|
||||
return Sbd_GiaSatOne_rec( p, Gia_ObjFanin1(pObj), Gia_ObjFaninC1(pObj), fFirst, iPat );
|
||||
}
|
||||
int Sbd_GiaSatOne( Gia_Man_t * p, Vec_Int_t * vPairs )
|
||||
{
|
||||
int k, n, Var1, Var2, iPat = 0;
|
||||
//Gia_ManSetPhase( p );
|
||||
Vec_IntForEachEntryDouble( vPairs, Var1, Var2, k )
|
||||
{
|
||||
Gia_Obj_t * pObj1 = Gia_ManObj( p, Var1 );
|
||||
Gia_Obj_t * pObj2 = Gia_ManObj( p, Var2 );
|
||||
assert( Var2 > 0 );
|
||||
if ( Var1 == 0 )
|
||||
{
|
||||
for ( n = 0; n < 2; n++ )
|
||||
{
|
||||
Gia_ManIncrementTravId( p );
|
||||
if ( Sbd_GiaSatOne_rec(p, pObj2, !pObj2->fPhase, n, iPat) )
|
||||
{
|
||||
iPat++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf( "%c", n == 2 ? '.' : 'c' );
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( n = 0; n < 2; n++ )
|
||||
{
|
||||
Gia_ManIncrementTravId( p );
|
||||
if ( Sbd_GiaSatOne_rec(p, pObj1, !pObj1->fPhase, n, iPat) && Sbd_GiaSatOne_rec(p, pObj2, pObj2->fPhase, n, iPat) )
|
||||
{
|
||||
iPat++;
|
||||
break;
|
||||
}
|
||||
Gia_ManIncrementTravId( p );
|
||||
if ( Sbd_GiaSatOne_rec(p, pObj1, pObj1->fPhase, n, iPat) && Sbd_GiaSatOne_rec(p, pObj2, !pObj2->fPhase, n, iPat) )
|
||||
{
|
||||
iPat++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf( "%c", n == 2 ? '.' : 'e' );
|
||||
}
|
||||
if ( iPat == 64 * p->iPatsPi - 1 )
|
||||
break;
|
||||
}
|
||||
printf( "\n" );
|
||||
return iPat;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Sbd_GiaSimRoundBack( Gia_Man_t * p )
|
||||
{
|
||||
extern void Sbd_GiaSimRound( Gia_Man_t * p, int fTry, Vec_Int_t ** pvMap );
|
||||
Vec_Int_t * vReprs = Vec_IntStart( Gia_ManObjNum(p) );
|
||||
Vec_Int_t * vPairs = Vec_IntAlloc( 1000 );
|
||||
Vec_Int_t * vMap; // maps each node into its class
|
||||
int i, nConsts = 0, nClasses = 0, nPats;
|
||||
Sbd_GiaSimRound( p, 0, &vMap );
|
||||
Gia_ManForEachAndId( p, i )
|
||||
{
|
||||
if ( Vec_IntEntry(vMap, i) == 0 )
|
||||
Vec_IntPushTwo( vPairs, 0, i ), nConsts++;
|
||||
else if ( Vec_IntEntry(vReprs, Vec_IntEntry(vMap, i)) == 0 )
|
||||
Vec_IntWriteEntry( vReprs, Vec_IntEntry(vMap, i), i );
|
||||
else if ( Vec_IntEntry(vReprs, Vec_IntEntry(vMap, i)) != -1 )
|
||||
{
|
||||
Vec_IntPushTwo( vPairs, Vec_IntEntry(vReprs, Vec_IntEntry(vMap, i)), i );
|
||||
Vec_IntWriteEntry( vReprs, Vec_IntEntry(vMap, i), -1 );
|
||||
nClasses++;
|
||||
}
|
||||
}
|
||||
Vec_IntFree( vMap );
|
||||
Vec_IntFree( vReprs );
|
||||
printf( "Constants = %d. Classes = %d.\n", nConsts, nClasses );
|
||||
|
||||
nPats = Sbd_GiaSatOne( p, vPairs );
|
||||
Vec_IntFree( vPairs );
|
||||
|
||||
printf( "Generated %d patterns.\n", nPats );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Sbd_GiaSimRound( Gia_Man_t * p, int fTry, Vec_Int_t ** pvMap )
|
||||
{
|
||||
int nWords = p->iPatsPi;
|
||||
Vec_Mem_t * vStore;
|
||||
Gia_Obj_t * pObj;
|
||||
Vec_Int_t * vMap = Vec_IntStart( Gia_ManObjNum(p) );
|
||||
int w, i, Id, fCompl, RetValue;
|
||||
// init primary inputs
|
||||
if ( fTry )
|
||||
{
|
||||
Sbd_GiaSimRoundBack( p );
|
||||
Gia_ManForEachCiId( p, Id, i )
|
||||
Sbd_ObjSims(p, Id)[0] <<= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Gia_ManForEachCiId( p, Id, i )
|
||||
for ( w = 0; w < nWords; w++ )
|
||||
Sbd_ObjSims(p, Id)[w] = Gia_ManRandomW(0) << !w;
|
||||
}
|
||||
// simulate internal nodes
|
||||
vStore = Vec_MemAlloc( nWords, 16 ); // 2^12 N-word entries per page
|
||||
Vec_MemHashAlloc( vStore, 1 << 16 );
|
||||
RetValue = Vec_MemHashInsert( vStore, Sbd_ObjSims(p, 0) ); // const zero
|
||||
assert( RetValue == 0 );
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
{
|
||||
word * pSims = Sbd_ObjSims(p, i);
|
||||
if ( Gia_ObjIsXor(pObj) )
|
||||
Abc_TtXor( pSims,
|
||||
Sbd_ObjSims(p, Gia_ObjFaninId0(pObj, i)),
|
||||
Sbd_ObjSims(p, Gia_ObjFaninId1(pObj, i)),
|
||||
nWords,
|
||||
Gia_ObjFaninC0(pObj) ^ Gia_ObjFaninC1(pObj) );
|
||||
else
|
||||
Abc_TtAndCompl( pSims,
|
||||
Sbd_ObjSims(p, Gia_ObjFaninId0(pObj, i)), Gia_ObjFaninC0(pObj),
|
||||
Sbd_ObjSims(p, Gia_ObjFaninId1(pObj, i)), Gia_ObjFaninC1(pObj),
|
||||
nWords );
|
||||
// hash sim info
|
||||
fCompl = (int)(pSims[0] & 1);
|
||||
if ( fCompl ) Abc_TtNot( pSims, nWords );
|
||||
Vec_IntWriteEntry( vMap, i, Vec_MemHashInsert(vStore, pSims) );
|
||||
if ( fCompl ) Abc_TtNot( pSims, nWords );
|
||||
}
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
{
|
||||
word * pSims = Sbd_ObjSims(p, Gia_ObjId(p, pObj));
|
||||
Abc_TtCopy( pSims, Sbd_ObjSims(p, Gia_ObjFaninId0p(p, pObj)), nWords, Gia_ObjFaninC0(pObj) );
|
||||
// printf( "%d ", Abc_TtCountOnesVec(pSims, nWords) );
|
||||
assert( Gia_ObjPhase(pObj) == (int)(pSims[0] & 1) );
|
||||
}
|
||||
// printf( "\n" );
|
||||
Vec_MemHashFree( vStore );
|
||||
Vec_MemFree( vStore );
|
||||
printf( "Objects = %6d. Unique = %6d.\n", Gia_ManAndNum(p), Vec_IntCountUnique(vMap) );
|
||||
if ( pvMap )
|
||||
*pvMap = vMap;
|
||||
else
|
||||
Vec_IntFree( vMap );
|
||||
}
|
||||
void Sbd_GiaSimTest( Gia_Man_t * pGia )
|
||||
{
|
||||
Gia_ManSetPhase( pGia );
|
||||
|
||||
// allocate simulation info
|
||||
pGia->iPatsPi = 32;
|
||||
pGia->vSims = Vec_WrdStart( Gia_ManObjNum(pGia) * pGia->iPatsPi );
|
||||
pGia->vSimsPi = Vec_WrdStart( Gia_ManObjNum(pGia) * pGia->iPatsPi );
|
||||
|
||||
Gia_ManRandom( 1 );
|
||||
|
||||
Sbd_GiaSimRound( pGia, 0, NULL );
|
||||
Sbd_GiaSimRound( pGia, 0, NULL );
|
||||
Sbd_GiaSimRound( pGia, 0, NULL );
|
||||
|
||||
printf( "\n" );
|
||||
Sbd_GiaSimRound( pGia, 1, NULL );
|
||||
printf( "\n" );
|
||||
Sbd_GiaSimRound( pGia, 1, NULL );
|
||||
printf( "\n" );
|
||||
Sbd_GiaSimRound( pGia, 1, NULL );
|
||||
|
||||
Vec_WrdFreeP( &pGia->vSims );
|
||||
Vec_WrdFreeP( &pGia->vSimsPi );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
@ -0,0 +1,283 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [sbd.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [SAT-based optimization using internal don't-cares.]
|
||||
|
||||
Synopsis []
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: sbd.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "sbdInt.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Constructs SAT solver for the window.]
|
||||
|
||||
Description [The window for the pivot node (Pivot) is represented as
|
||||
a DFS ordered array of objects (vWinObjs) whose indexed in the array
|
||||
(which will be used as SAT variables) are given in array vObj2Var.
|
||||
The TFO nodes are listed as the last ones in vWinObjs. The root nodes
|
||||
are labeled with Abc_LitIsCompl() in vTfo and also given in vRoots.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, Vec_Int_t * vMirrors, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots )
|
||||
{
|
||||
Gia_Obj_t * pObj;
|
||||
int i, iLit = 1, iObj, Fan0, Fan1, Lit0m, Lit1m, Node, fCompl0, fCompl1, RetValue;
|
||||
int TfoStart = Vec_IntSize(vWinObjs) - Vec_IntSize(vTfo);
|
||||
int PivotVar = Vec_IntEntry(vObj2Var, Pivot);
|
||||
//Vec_IntPrint( vWinObjs );
|
||||
//Vec_IntPrint( vTfo );
|
||||
//Vec_IntPrint( vRoots );
|
||||
// create SAT solver
|
||||
if ( pSat == NULL )
|
||||
pSat = sat_solver_new();
|
||||
else
|
||||
sat_solver_restart( pSat );
|
||||
sat_solver_setnvars( pSat, Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots) + 32 );
|
||||
// create constant 0 clause
|
||||
sat_solver_addclause( pSat, &iLit, &iLit + 1 );
|
||||
// add clauses for all nodes
|
||||
Vec_IntForEachEntryStart( vWinObjs, iObj, i, 1 )
|
||||
{
|
||||
pObj = Gia_ManObj( p, iObj );
|
||||
if ( Gia_ObjIsCi(pObj) )
|
||||
continue;
|
||||
assert( Gia_ObjIsAnd(pObj) );
|
||||
assert( Vec_IntEntry( vMirrors, iObj ) < 0 );
|
||||
Node = Vec_IntEntry( vObj2Var, iObj );
|
||||
Lit0m = Vec_IntEntry( vMirrors, Gia_ObjFaninId0(pObj, iObj) );
|
||||
Lit1m = Vec_IntEntry( vMirrors, Gia_ObjFaninId1(pObj, iObj) );
|
||||
Fan0 = Lit0m >= 0 ? Abc_Lit2Var(Lit0m) : Gia_ObjFaninId0(pObj, iObj);
|
||||
Fan1 = Lit1m >= 0 ? Abc_Lit2Var(Lit1m) : Gia_ObjFaninId1(pObj, iObj);
|
||||
Fan0 = Vec_IntEntry( vObj2Var, Fan0 );
|
||||
Fan1 = Vec_IntEntry( vObj2Var, Fan1 );
|
||||
fCompl0 = Gia_ObjFaninC0(pObj) ^ (Lit0m >= 0 && Abc_LitIsCompl(Lit0m));
|
||||
fCompl1 = Gia_ObjFaninC1(pObj) ^ (Lit1m >= 0 && Abc_LitIsCompl(Lit1m));
|
||||
if ( Gia_ObjIsXor(pObj) )
|
||||
sat_solver_add_xor( pSat, Node, Fan0, Fan1, fCompl0 ^ fCompl1 );
|
||||
else
|
||||
sat_solver_add_and( pSat, Node, Fan0, Fan1, fCompl0, fCompl1, 0 );
|
||||
}
|
||||
// add second clauses for the TFO
|
||||
Vec_IntForEachEntryStart( vWinObjs, iObj, i, TfoStart )
|
||||
{
|
||||
pObj = Gia_ManObj( p, iObj );
|
||||
assert( Gia_ObjIsAnd(pObj) );
|
||||
assert( Vec_IntEntry( vMirrors, iObj ) < 0 );
|
||||
Node = Vec_IntEntry( vObj2Var, iObj ) + Vec_IntSize(vTfo);
|
||||
Lit0m = Vec_IntEntry( vMirrors, Gia_ObjFaninId0(pObj, iObj) );
|
||||
Lit1m = Vec_IntEntry( vMirrors, Gia_ObjFaninId1(pObj, iObj) );
|
||||
Fan0 = Lit0m >= 0 ? Abc_Lit2Var(Lit0m) : Gia_ObjFaninId0(pObj, iObj);
|
||||
Fan1 = Lit1m >= 0 ? Abc_Lit2Var(Lit1m) : Gia_ObjFaninId1(pObj, iObj);
|
||||
Fan0 = Vec_IntEntry( vObj2Var, Fan0 );
|
||||
Fan1 = Vec_IntEntry( vObj2Var, Fan1 );
|
||||
Fan0 = Fan0 < TfoStart ? Fan0 : Fan0 + Vec_IntSize(vTfo);
|
||||
Fan1 = Fan1 < TfoStart ? Fan1 : Fan1 + Vec_IntSize(vTfo);
|
||||
fCompl0 = Gia_ObjFaninC0(pObj) ^ (Fan0 == PivotVar) ^ (Lit0m >= 0 && Abc_LitIsCompl(Lit0m));
|
||||
fCompl1 = Gia_ObjFaninC1(pObj) ^ (Fan1 == PivotVar) ^ (Lit1m >= 0 && Abc_LitIsCompl(Lit1m));
|
||||
if ( Gia_ObjIsXor(pObj) )
|
||||
sat_solver_add_xor( pSat, Node, Fan0, Fan1, fCompl0 ^ fCompl1 );
|
||||
else
|
||||
sat_solver_add_and( pSat, Node, Fan0, Fan1, fCompl0, fCompl1, 0 );
|
||||
}
|
||||
if ( Vec_IntSize(vRoots) > 0 )
|
||||
{
|
||||
// create XOR clauses for the roots
|
||||
int nVars = Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo);
|
||||
Vec_Int_t * vFaninVars = Vec_IntAlloc( Vec_IntSize(vRoots) );
|
||||
Vec_IntForEachEntry( vRoots, iObj, i )
|
||||
{
|
||||
assert( Vec_IntEntry( vMirrors, iObj ) < 0 );
|
||||
Node = Vec_IntEntry( vObj2Var, iObj );
|
||||
Vec_IntPush( vFaninVars, Abc_Var2Lit(nVars, 0) );
|
||||
sat_solver_add_xor( pSat, Node, Node + Vec_IntSize(vTfo), nVars++, 0 );
|
||||
}
|
||||
// make OR clause for the last nRoots variables
|
||||
RetValue = sat_solver_addclause( pSat, Vec_IntArray(vFaninVars), Vec_IntLimit(vFaninVars) );
|
||||
Vec_IntFree( vFaninVars );
|
||||
if ( RetValue == 0 )
|
||||
{
|
||||
sat_solver_delete( pSat );
|
||||
return NULL;
|
||||
}
|
||||
assert( sat_solver_nvars(pSat) == nVars + 32 );
|
||||
}
|
||||
// finalize
|
||||
RetValue = sat_solver_simplify( pSat );
|
||||
if ( RetValue == 0 )
|
||||
{
|
||||
sat_solver_delete( pSat );
|
||||
return NULL;
|
||||
}
|
||||
return pSat;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Solves one SAT problem.]
|
||||
|
||||
Description [Computes node function for PivotVar with fanins in vDivVars
|
||||
using don't-care represented in the SAT solver. Uses array vValues to
|
||||
return the values of the first Vec_IntSize(vValues) SAT variables in case
|
||||
the implementation of the node with the given fanins does not exist.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivVars, Vec_Int_t * vValues, Vec_Int_t * vTemp )
|
||||
{
|
||||
int nBTLimit = 0;
|
||||
word uCube, uTruth = 0;
|
||||
int status, i, iVar, nFinal, * pFinal, pLits[2], nIter = 0;
|
||||
assert( FreeVar < sat_solver_nvars(pSat) );
|
||||
pLits[0] = Abc_Var2Lit( PivotVar, 0 ); // F = 1
|
||||
pLits[1] = Abc_Var2Lit( FreeVar, 0 ); // iNewLit
|
||||
while ( 1 )
|
||||
{
|
||||
// find onset minterm
|
||||
status = sat_solver_solve( pSat, pLits, pLits + 2, nBTLimit, 0, 0, 0 );
|
||||
if ( status == l_Undef )
|
||||
return SBD_SAT_UNDEC;
|
||||
if ( status == l_False )
|
||||
return uTruth;
|
||||
assert( status == l_True );
|
||||
// remember variable values
|
||||
for ( i = 0; i < Vec_IntSize(vValues); i++ )
|
||||
Vec_IntWriteEntry( vValues, i, 2*sat_solver_var_value(pSat, i) );
|
||||
// collect divisor literals
|
||||
Vec_IntClear( vTemp );
|
||||
Vec_IntPush( vTemp, Abc_LitNot(pLits[0]) ); // F = 0
|
||||
Vec_IntForEachEntry( vDivVars, iVar, i )
|
||||
Vec_IntPush( vTemp, sat_solver_var_literal(pSat, iVar) );
|
||||
// check against offset
|
||||
status = sat_solver_solve( pSat, Vec_IntArray(vTemp), Vec_IntArray(vTemp) + Vec_IntSize(vTemp), nBTLimit, 0, 0, 0 );
|
||||
if ( status == l_Undef )
|
||||
return SBD_SAT_UNDEC;
|
||||
if ( status == l_True )
|
||||
break;
|
||||
assert( status == l_False );
|
||||
// compute cube and add clause
|
||||
nFinal = sat_solver_final( pSat, &pFinal );
|
||||
uCube = ~(word)0;
|
||||
Vec_IntClear( vTemp );
|
||||
Vec_IntPush( vTemp, Abc_LitNot(pLits[1]) ); // NOT(iNewLit)
|
||||
for ( i = 0; i < nFinal; i++ )
|
||||
{
|
||||
if ( pFinal[i] == pLits[0] )
|
||||
continue;
|
||||
Vec_IntPush( vTemp, pFinal[i] );
|
||||
iVar = Vec_IntFind( vDivVars, Abc_Lit2Var(pFinal[i]) ); assert( iVar >= 0 );
|
||||
uCube &= Abc_LitIsCompl(pFinal[i]) ? s_Truths6[iVar] : ~s_Truths6[iVar];
|
||||
}
|
||||
uTruth |= uCube;
|
||||
status = sat_solver_addclause( pSat, Vec_IntArray(vTemp), Vec_IntArray(vTemp) + Vec_IntSize(vTemp) );
|
||||
assert( status );
|
||||
nIter++;
|
||||
}
|
||||
assert( status == l_True );
|
||||
// store the counter-example
|
||||
for ( i = 0; i < Vec_IntSize(vValues); i++ )
|
||||
Vec_IntAddToEntry( vValues, i, sat_solver_var_value(pSat, i) );
|
||||
|
||||
for ( i = 0; i < Vec_IntSize(vValues); i++ )
|
||||
Vec_IntAddToEntry( vValues, i, 0xC );
|
||||
/*
|
||||
// reduce the counter example
|
||||
for ( n = 0; n < 2; n++ )
|
||||
{
|
||||
Vec_IntClear( vTemp );
|
||||
Vec_IntPush( vTemp, Abc_Var2Lit(PivotVar, n) ); // n = 0 => F = 1 (expanding offset against onset)
|
||||
for ( i = 0; i < Vec_IntSize(vValues); i++ )
|
||||
Vec_IntPush( vTemp, Abc_Var2Lit(i, !((Vec_IntEntry(vValues, i) >> n) & 1)) );
|
||||
status = sat_solver_solve( pSat, Vec_IntArray(vTemp), Vec_IntArray(vTemp) + Vec_IntSize(vTemp), nBTLimit, 0, 0, 0 );
|
||||
assert( status == l_False );
|
||||
// compute cube and add clause
|
||||
nFinal = sat_solver_final( pSat, &pFinal );
|
||||
for ( i = 0; i < nFinal; i++ )
|
||||
if ( Abc_Lit2Var(pFinal[i]) != PivotVar )
|
||||
Vec_IntAddToEntry( vValues, Abc_Lit2Var(pFinal[i]), 1 << (n+2) );
|
||||
}
|
||||
*/
|
||||
return SBD_SAT_SAT;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns a bunch of positive/negative random care minterms.]
|
||||
|
||||
Description [Returns 0/1 if the functions is const 0/1.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static void sat_solver_random_polarity(sat_solver* s)
|
||||
{
|
||||
int i, k;
|
||||
for ( i = 0; i < s->size; i += 64 )
|
||||
{
|
||||
word Polar = Gia_ManRandomW(0);
|
||||
for ( k = 0; k < 64 && (i << 6) + k < s->size; k++ )
|
||||
s->polarity[(i << 6) + k] = Abc_TtGetBit(&Polar, k);
|
||||
}
|
||||
}
|
||||
int Sbd_ManCollectConstants( sat_solver * pSat, int nCareMints[2], int PivotVar, word * pVarSims[], Vec_Int_t * vInds )
|
||||
{
|
||||
int nBTLimit = 0;
|
||||
int i, Ind;
|
||||
assert( Vec_IntSize(vInds) == nCareMints[0] + nCareMints[1] );
|
||||
Vec_IntForEachEntry( vInds, Ind, i )
|
||||
{
|
||||
int fOffSet = (int)(i < nCareMints[0]);
|
||||
int status, k, iLit = Abc_Var2Lit( PivotVar, fOffSet );
|
||||
sat_solver_random_polarity( pSat );
|
||||
status = sat_solver_solve( pSat, &iLit, &iLit + 1, nBTLimit, 0, 0, 0 );
|
||||
if ( status == l_Undef )
|
||||
return -2;
|
||||
if ( status == l_False )
|
||||
return fOffSet;
|
||||
for ( k = 0; k <= PivotVar; k++ )
|
||||
if ( Abc_TtGetBit(pVarSims[k], Ind) != sat_solver_var_value(pSat, k) )
|
||||
Abc_TtXorBit(pVarSims[k], Ind);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [acecCl.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [CEC for arithmetic circuits.]
|
||||
|
||||
Synopsis [Core procedures.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: acecCl.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "acecInt.h"
|
||||
#include "misc/vec/vecWec.h"
|
||||
#include "misc/extra/extra.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
@ -44,11 +44,14 @@ ABC_NAMESPACE_IMPL_START
|
|||
***********************************************************************/
|
||||
void Gia_PolynCoreNonXors_rec( Gia_Man_t * pGia, Gia_Obj_t * pObj, Vec_Int_t * vXorPairs )
|
||||
{
|
||||
extern int Gia_ManSuppSizeOne( Gia_Man_t * p, Gia_Obj_t * pObj );
|
||||
Gia_Obj_t * pFan0, * pFan1;
|
||||
if ( !Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) )
|
||||
return;
|
||||
Gia_PolynCoreNonXors_rec( pGia, Gia_Regular(pFan0), vXorPairs );
|
||||
Gia_PolynCoreNonXors_rec( pGia, Gia_Regular(pFan1), vXorPairs );
|
||||
//if ( Gia_ManSuppSizeOne(pGia, pObj) > 4 )
|
||||
//if ( Gia_ObjId(pGia, pObj) >= 73 )
|
||||
Vec_IntPushTwo( vXorPairs, Gia_ObjId(pGia, Gia_Regular(pFan0)), Gia_ObjId(pGia, Gia_Regular(pFan1)) );
|
||||
}
|
||||
Vec_Int_t * Gia_PolynAddHaRoots( Gia_Man_t * pGia )
|
||||
|
|
@ -87,38 +90,30 @@ Vec_Int_t * Gia_PolynAddHaRoots( Gia_Man_t * pGia )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Gia_PolynCoreOrder( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vAddCos, Vec_Int_t ** pvIns, Vec_Int_t ** pvOuts )
|
||||
Vec_Wec_t * Gia_PolynComputeMap( Vec_Int_t * vAdds, int nObjs )
|
||||
{
|
||||
Vec_Int_t * vOrder = Vec_IntAlloc( 1000 );
|
||||
Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(pGia) );
|
||||
Vec_Int_t * vRoots = Vec_IntAlloc( 5 * Gia_ManCoNum(pGia) );
|
||||
Vec_Int_t * vLeaves = Vec_IntAlloc( 2 * Gia_ManCiNum(pGia) );
|
||||
Vec_Wec_t * vMap = Vec_WecStart( Gia_ManObjNum(pGia) );
|
||||
int i, k, Index, Driver, Entry1, Entry2 = -1;
|
||||
// nodes driven by adders into adder indexes
|
||||
for ( i = 0; 5*i < Vec_IntSize(vAdds); i++ )
|
||||
// map nodes driven by adders into adder indexes
|
||||
Vec_Wec_t * vMap = Vec_WecStart( nObjs ); int i;
|
||||
for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ )
|
||||
{
|
||||
Entry1 = Vec_IntEntry( vAdds, 5*i + 3 );
|
||||
Entry2 = Vec_IntEntry( vAdds, 5*i + 4 );
|
||||
int Entry1 = Vec_IntEntry( vAdds, 6*i + 3 );
|
||||
int Entry2 = Vec_IntEntry( vAdds, 6*i + 4 );
|
||||
Vec_WecPush( vMap, Entry1, i );
|
||||
Vec_WecPush( vMap, Entry1, Entry2 );
|
||||
Vec_WecPush( vMap, Entry2, i );
|
||||
Vec_WecPush( vMap, Entry2, Entry1 );
|
||||
}
|
||||
// collect roots
|
||||
Gia_ManForEachCoDriverId( pGia, Driver, i )
|
||||
{
|
||||
Vec_IntPush( vRoots, Driver );
|
||||
return vMap;
|
||||
}
|
||||
Vec_Int_t * Gia_PolynCoreOrder_int( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Wec_t * vMap, Vec_Int_t * vRoots, Vec_Int_t ** pvIns )
|
||||
{
|
||||
Vec_Int_t * vOrder = Vec_IntAlloc( 1000 );
|
||||
Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(pGia) );
|
||||
int i, k, Index, Driver, Entry1, Entry2 = -1;
|
||||
// mark roots
|
||||
Vec_IntForEachEntry( vRoots, Driver, i )
|
||||
Vec_BitWriteEntry( vIsRoot, Driver, 1 );
|
||||
}
|
||||
// collect additional outputs
|
||||
Vec_IntForEachEntry( vAddCos, Driver, i )
|
||||
{
|
||||
Vec_IntPush( vRoots, Driver );
|
||||
Vec_BitWriteEntry( vIsRoot, Driver, 1 );
|
||||
}
|
||||
// detect full adder tree
|
||||
*pvOuts = Vec_IntDup( vRoots );
|
||||
// collect boxes
|
||||
while ( 1 )
|
||||
{
|
||||
// iterate through boxes driving this one
|
||||
|
|
@ -140,9 +135,9 @@ Vec_Int_t * Gia_PolynCoreOrder( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t *
|
|||
Vec_IntRemove( vRoots, Entry1 );
|
||||
Vec_IntRemove( vRoots, Entry2 );
|
||||
// set new marks
|
||||
Entry1 = Vec_IntEntry( vAdds, 5*Index + 0 );
|
||||
Entry2 = Vec_IntEntry( vAdds, 5*Index + 1 );
|
||||
Driver = Vec_IntEntry( vAdds, 5*Index + 2 );
|
||||
Entry1 = Vec_IntEntry( vAdds, 6*Index + 0 );
|
||||
Entry2 = Vec_IntEntry( vAdds, 6*Index + 1 );
|
||||
Driver = Vec_IntEntry( vAdds, 6*Index + 2 );
|
||||
Vec_BitWriteEntry( vIsRoot, Entry1, 1 );
|
||||
Vec_BitWriteEntry( vIsRoot, Entry2, 1 );
|
||||
Vec_BitWriteEntry( vIsRoot, Driver, 1 );
|
||||
|
|
@ -155,17 +150,97 @@ Vec_Int_t * Gia_PolynCoreOrder( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t *
|
|||
break;
|
||||
}
|
||||
// collect remaining leaves
|
||||
Vec_BitForEachEntryStart( vIsRoot, Driver, i, 1 )
|
||||
if ( Driver )
|
||||
Vec_IntPush( vLeaves, i );
|
||||
*pvIns = vLeaves;
|
||||
// cleanup
|
||||
if ( pvIns )
|
||||
{
|
||||
*pvIns = Vec_IntAlloc( Vec_BitSize(vIsRoot) );
|
||||
Vec_BitForEachEntryStart( vIsRoot, Driver, i, 1 )
|
||||
if ( Driver )
|
||||
Vec_IntPush( *pvIns, i );
|
||||
}
|
||||
Vec_BitFree( vIsRoot );
|
||||
return vOrder;
|
||||
}
|
||||
Vec_Int_t * Gia_PolynCoreOrder( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vAddCos, Vec_Int_t ** pvIns, Vec_Int_t ** pvOuts )
|
||||
{
|
||||
Vec_Int_t * vOrder;
|
||||
Vec_Wec_t * vMap = Gia_PolynComputeMap( vAdds, Gia_ManObjNum(pGia) );
|
||||
Vec_Int_t * vRoots = Vec_IntAlloc( Gia_ManCoNum(pGia) );
|
||||
int i, Driver;
|
||||
// collect roots
|
||||
Gia_ManForEachCoDriverId( pGia, Driver, i )
|
||||
Vec_IntPush( vRoots, Driver );
|
||||
// collect additional outputs
|
||||
if ( vAddCos )
|
||||
Vec_IntForEachEntry( vAddCos, Driver, i )
|
||||
Vec_IntPush( vRoots, Driver );
|
||||
// remember roots
|
||||
if ( pvOuts )
|
||||
*pvOuts = Vec_IntDup( vRoots );
|
||||
// create order
|
||||
vOrder = Gia_PolynCoreOrder_int( pGia, vAdds, vMap, vRoots, pvIns );
|
||||
Vec_IntFree( vRoots );
|
||||
Vec_WecFree( vMap );
|
||||
printf( "Collected %d boxes.\n", Vec_IntSize(vOrder) );
|
||||
return vOrder;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_PolyCollectRoots_rec( Vec_Int_t * vAdds, Vec_Wec_t * vMap, Vec_Bit_t * vMarks, int iBox, Vec_Int_t * vRoots )
|
||||
{
|
||||
int k;
|
||||
for ( k = 0; k < 3; k++ )
|
||||
{
|
||||
int i, Index, Sum, Carry = Vec_IntEntry( vAdds, 6*iBox+k );
|
||||
Vec_Int_t * vLevel = Vec_WecEntry( vMap, Carry );
|
||||
if ( Carry == 0 )
|
||||
continue;
|
||||
Vec_IntForEachEntryDouble( vLevel, Index, Sum, i )
|
||||
if ( Vec_IntEntry(vAdds, 6*Index+4) == Carry && !Vec_BitEntry(vMarks, Sum) )
|
||||
{
|
||||
Vec_IntPush( vRoots, Sum );
|
||||
Gia_PolyCollectRoots_rec( vAdds, vMap, vMarks, Index, vRoots );
|
||||
}
|
||||
}
|
||||
}
|
||||
void Gia_PolyCollectRoots( Vec_Int_t * vAdds, Vec_Wec_t * vMap, Vec_Bit_t * vMarks, int iBox, Vec_Int_t * vRoots )
|
||||
{
|
||||
Vec_IntClear( vRoots );
|
||||
Vec_IntPush( vRoots, Vec_IntEntry(vAdds, 6*iBox+3) );
|
||||
Vec_IntPush( vRoots, Vec_IntEntry(vAdds, 6*iBox+4) );
|
||||
Gia_PolyCollectRoots_rec( vAdds, vMap, vMarks, iBox, vRoots );
|
||||
}
|
||||
Vec_Wec_t * Gia_PolynCoreOrderArray( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vRootBoxes )
|
||||
{
|
||||
extern Vec_Bit_t * Acec_ManPoolGetPointed( Gia_Man_t * p, Vec_Int_t * vAdds );
|
||||
Vec_Bit_t * vMarks = Acec_ManPoolGetPointed( pGia, vAdds );
|
||||
Vec_Wec_t * vMap = Gia_PolynComputeMap( vAdds, Gia_ManObjNum(pGia) );
|
||||
Vec_Wec_t * vRes = Vec_WecStart( Vec_IntSize(vRootBoxes) );
|
||||
Vec_Int_t * vRoots = Vec_IntAlloc( 64 );
|
||||
Vec_Int_t * vOrder;
|
||||
int i, iBox;
|
||||
Vec_IntForEachEntry( vRootBoxes, iBox, i )
|
||||
{
|
||||
Gia_PolyCollectRoots( vAdds, vMap, vMarks, iBox, vRoots );
|
||||
vOrder = Gia_PolynCoreOrder_int( pGia, vAdds, vMap, vRoots, NULL );
|
||||
Vec_IntAppend( Vec_WecEntry(vRes, i), vOrder );
|
||||
Vec_IntFree( vOrder );
|
||||
}
|
||||
Vec_BitFree( vMarks );
|
||||
Vec_IntFree( vRoots );
|
||||
Vec_WecFree( vMap );
|
||||
return vRes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collect internal node order.]
|
||||
|
|
@ -194,15 +269,15 @@ Vec_Int_t * Gia_PolynCoreCollect( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t
|
|||
Vec_IntForEachEntryReverse( vOrder, Index, i )
|
||||
{
|
||||
// mark inputs
|
||||
Entry1 = Vec_IntEntry( vAdds, 5*Index + 0 );
|
||||
Entry2 = Vec_IntEntry( vAdds, 5*Index + 1 );
|
||||
Entry3 = Vec_IntEntry( vAdds, 5*Index + 2 );
|
||||
Entry1 = Vec_IntEntry( vAdds, 6*Index + 0 );
|
||||
Entry2 = Vec_IntEntry( vAdds, 6*Index + 1 );
|
||||
Entry3 = Vec_IntEntry( vAdds, 6*Index + 2 );
|
||||
Vec_BitWriteEntry( vVisited, Entry1, 1 );
|
||||
Vec_BitWriteEntry( vVisited, Entry2, 1 );
|
||||
Vec_BitWriteEntry( vVisited, Entry3, 1 );
|
||||
// traverse from outputs
|
||||
Entry1 = Vec_IntEntry( vAdds, 5*Index + 3 );
|
||||
Entry2 = Vec_IntEntry( vAdds, 5*Index + 4 );
|
||||
Entry1 = Vec_IntEntry( vAdds, 6*Index + 3 );
|
||||
Entry2 = Vec_IntEntry( vAdds, 6*Index + 4 );
|
||||
Gia_PolynCoreCollect_rec( pGia, Entry1, vNodes, vVisited );
|
||||
Gia_PolynCoreCollect_rec( pGia, Entry2, vNodes, vVisited );
|
||||
}
|
||||
|
|
@ -312,14 +387,17 @@ Gia_Man_t * Gia_PolynCoreDupTree( Gia_Man_t * p, Vec_Int_t * vAddCos, Vec_Int_t
|
|||
***********************************************************************/
|
||||
Gia_Man_t * Gia_PolynCoreDetectTest_int( Gia_Man_t * pGia, Vec_Int_t * vAddCos, int fAddCones, int fVerbose )
|
||||
{
|
||||
extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, int fVerbose );
|
||||
extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose );
|
||||
abctime clk = Abc_Clock();
|
||||
Gia_Man_t * pNew;
|
||||
Vec_Int_t * vAdds = Ree_ManComputeCuts( pGia, 1 );
|
||||
Vec_Int_t * vAdds = Ree_ManComputeCuts( pGia, NULL, 1 );
|
||||
Vec_Int_t * vLeaves, * vRoots, * vOrder = Gia_PolynCoreOrder( pGia, vAdds, vAddCos, &vLeaves, &vRoots );
|
||||
Vec_Int_t * vNodes = Gia_PolynCoreCollect( pGia, vAdds, vOrder );
|
||||
|
||||
//Gia_ManShow( pGia, vNodes, 0 );
|
||||
|
||||
printf( "Detected %d FAs/HAs. Roots = %d. Leaves = %d. Nodes = %d. Adds = %d. ",
|
||||
Vec_IntSize(vAdds), Vec_IntSize(vLeaves), Vec_IntSize(vRoots), Vec_IntSize(vNodes), Vec_IntSize(vOrder) );
|
||||
Vec_IntSize(vAdds)/6, Vec_IntSize(vLeaves), Vec_IntSize(vRoots), Vec_IntSize(vNodes), Vec_IntSize(vOrder) );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
||||
|
||||
Gia_PolynCorePrintCones( pGia, vLeaves, fVerbose );
|
||||
|
|
|
|||
|
|
@ -0,0 +1,282 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [acecPa.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [CEC for arithmetic circuits.]
|
||||
|
||||
Synopsis [Core procedures.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: acecPa.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "acecInt.h"
|
||||
#include "misc/vec/vecWec.h"
|
||||
#include "misc/extra/extra.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Pas_ManVerifyPhaseOne_rec( Gia_Man_t * p, Gia_Obj_t * pObj )
|
||||
{
|
||||
int Truth0, Truth1;
|
||||
if ( Gia_ObjIsTravIdCurrent(p, pObj) )
|
||||
return pObj->Value;
|
||||
Gia_ObjSetTravIdCurrent(p, pObj);
|
||||
assert( Gia_ObjIsAnd(pObj) );
|
||||
assert( !Gia_ObjIsXor(pObj) );
|
||||
Truth0 = Pas_ManVerifyPhaseOne_rec( p, Gia_ObjFanin0(pObj) );
|
||||
Truth1 = Pas_ManVerifyPhaseOne_rec( p, Gia_ObjFanin1(pObj) );
|
||||
Truth0 = Gia_ObjFaninC0(pObj) ? 0xFF & ~Truth0 : Truth0;
|
||||
Truth1 = Gia_ObjFaninC1(pObj) ? 0xFF & ~Truth1 : Truth1;
|
||||
return (pObj->Value = Truth0 & Truth1);
|
||||
}
|
||||
void Pas_ManVerifyPhaseOne( Gia_Man_t * p, Vec_Int_t * vAdds, int iBox, Vec_Bit_t * vPhase )
|
||||
{
|
||||
Gia_Obj_t * pObj;
|
||||
unsigned TruthXor, TruthMaj, Truths[3] = { 0xAA, 0xCC, 0xF0 };
|
||||
int k, iObj, fFadd = Vec_IntEntry(vAdds, 6*iBox+2) > 0;
|
||||
|
||||
if ( !fFadd )
|
||||
return;
|
||||
|
||||
Gia_ManIncrementTravId( p );
|
||||
for ( k = 0; k < 3; k++ )
|
||||
{
|
||||
iObj = Vec_IntEntry( vAdds, 6*iBox+k );
|
||||
if ( iObj == 0 )
|
||||
continue;
|
||||
pObj = Gia_ManObj( p, iObj );
|
||||
pObj->Value = Vec_BitEntry(vPhase, iObj) ? 0xFF & ~Truths[k] : Truths[k];
|
||||
Gia_ObjSetTravIdCurrent( p, pObj );
|
||||
}
|
||||
|
||||
iObj = Vec_IntEntry( vAdds, 6*iBox+3 );
|
||||
TruthXor = Pas_ManVerifyPhaseOne_rec( p, Gia_ManObj(p, iObj) );
|
||||
TruthXor = Vec_BitEntry(vPhase, iObj) ? 0xFF & ~TruthXor : TruthXor;
|
||||
|
||||
iObj = Vec_IntEntry( vAdds, 6*iBox+4 );
|
||||
TruthMaj = Pas_ManVerifyPhaseOne_rec( p, Gia_ManObj(p, iObj) );
|
||||
TruthMaj = Vec_BitEntry(vPhase, iObj) ? 0xFF & ~TruthMaj : TruthMaj;
|
||||
|
||||
if ( fFadd ) // FADD
|
||||
{
|
||||
if ( TruthXor != 0x96 )
|
||||
printf( "Fadd %d sum is wrong.\n", iBox );
|
||||
if ( TruthMaj != 0xE8 )
|
||||
printf( "Fadd %d carry is wrong.\n", iBox );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( TruthXor != 0x66 )
|
||||
printf( "Hadd %d sum is wrong.\n", iBox );
|
||||
if ( TruthMaj != 0x88 )
|
||||
printf( "Hadd %d carry is wrong.\n", iBox );
|
||||
}
|
||||
}
|
||||
void Pas_ManVerifyPhase( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vOrder, Vec_Bit_t * vPhase )
|
||||
{
|
||||
int k, iBox;
|
||||
Vec_IntForEachEntry( vOrder, iBox, k )
|
||||
Pas_ManVerifyPhaseOne( p, vAdds, iBox, vPhase );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Pas_ManPhase_rec( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vMap, Gia_Obj_t * pObj, int fPhase, Vec_Bit_t * vPhase, Vec_Bit_t * vConstPhase )
|
||||
{
|
||||
int k, iBox, iXor, Sign, fXorPhase;
|
||||
assert( pObj != Gia_ManConst0(p) );
|
||||
if ( Gia_ObjIsTravIdCurrent(p, pObj) )
|
||||
return;
|
||||
Gia_ObjSetTravIdCurrent(p, pObj);
|
||||
if ( fPhase )
|
||||
Vec_BitWriteEntry( vPhase, Gia_ObjId(p, pObj), fPhase );
|
||||
if ( !Gia_ObjIsAnd(pObj) )
|
||||
return;
|
||||
iBox = Vec_IntEntry( vMap, Gia_ObjId(p, pObj) );
|
||||
if ( iBox == -1 )
|
||||
return;
|
||||
iXor = Vec_IntEntry( vAdds, 6*iBox+3 );
|
||||
Sign = Vec_IntEntry( vAdds, 6*iBox+5 );
|
||||
fXorPhase = ((Sign >> 3) & 1);
|
||||
// remember complemented HADD
|
||||
if ( Vec_IntEntry(vAdds, 6*iBox+2) == 0 && fPhase )
|
||||
Vec_BitWriteEntry( vConstPhase, iBox, 1 );
|
||||
for ( k = 0; k < 3; k++ )
|
||||
{
|
||||
int iObj = Vec_IntEntry( vAdds, 6*iBox+k );
|
||||
int fPhaseThis = ((Sign >> k) & 1) ^ fPhase;
|
||||
fXorPhase ^= fPhaseThis;
|
||||
if ( iObj == 0 )
|
||||
continue;
|
||||
Pas_ManPhase_rec( p, vAdds, vMap, Gia_ManObj(p, iObj), fPhaseThis, vPhase, vConstPhase );
|
||||
}
|
||||
Vec_BitWriteEntry( vPhase, iXor, fXorPhase );
|
||||
}
|
||||
Vec_Bit_t * Pas_ManPhase( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vMap, Vec_Int_t * vRoots, Vec_Bit_t ** pvConstPhase )
|
||||
{
|
||||
Vec_Bit_t * vPhase = Vec_BitStart( Vec_IntSize(vMap) );
|
||||
Vec_Bit_t * vConstPhase = Vec_BitStart( Vec_IntSize(vAdds)/6 );
|
||||
int i, iRoot;
|
||||
Gia_ManIncrementTravId( p );
|
||||
Vec_IntForEachEntry( vRoots, iRoot, i )
|
||||
Pas_ManPhase_rec( p, vAdds, vMap, Gia_ManObj(p, iRoot), 1, vPhase, vConstPhase );
|
||||
*pvConstPhase = vConstPhase;
|
||||
return vPhase;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Pas_ManComputeCuts( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vOrder, Vec_Int_t * vIns, Vec_Int_t * vOuts )
|
||||
{
|
||||
Vec_Bit_t * vUnique = Vec_BitStart( Gia_ManObjNum(p) );
|
||||
Vec_Bit_t * vUsed = Vec_BitStart( Gia_ManObjNum(p) );
|
||||
Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) );
|
||||
Vec_Int_t * vRoots = Vec_IntAlloc( 100 );
|
||||
Vec_Bit_t * vPhase, * vConstPhase;
|
||||
int i, k, Entry, nTrees;
|
||||
|
||||
// map carries into adder indexes and mark driven nodes
|
||||
Vec_IntForEachEntry( vOrder, i, k )
|
||||
{
|
||||
int Carry = Vec_IntEntry(vAdds, 6*i+4);
|
||||
if ( Vec_BitEntry(vUnique, Carry) )
|
||||
printf( "Carry %d participates more than once.\n", Carry );
|
||||
Vec_BitWriteEntry( vUnique, Carry, 1 );
|
||||
Vec_IntWriteEntry( vMap, Carry, i );
|
||||
// mark driven
|
||||
Vec_BitWriteEntry( vUsed, Vec_IntEntry(vAdds, 6*i+0), 1 );
|
||||
Vec_BitWriteEntry( vUsed, Vec_IntEntry(vAdds, 6*i+1), 1 );
|
||||
Vec_BitWriteEntry( vUsed, Vec_IntEntry(vAdds, 6*i+2), 1 );
|
||||
}
|
||||
// collect carries that do not drive other adders
|
||||
for ( i = 0; i < Gia_ManObjNum(p); i++ )
|
||||
if ( Vec_BitEntry(vUnique, i) && !Vec_BitEntry(vUsed, i) )
|
||||
Vec_IntPush( vRoots, i );
|
||||
nTrees = Vec_IntSize( vRoots );
|
||||
|
||||
Vec_IntPrint( vRoots );
|
||||
|
||||
// compute phases
|
||||
if ( Vec_IntSize(vRoots) > 0 )
|
||||
{
|
||||
int nCompls = 0;
|
||||
|
||||
vPhase = Pas_ManPhase( p, vAdds, vMap, vRoots, &vConstPhase );
|
||||
Pas_ManVerifyPhase( p, vAdds, vOrder, vPhase );
|
||||
|
||||
printf( "Outputs: " );
|
||||
Vec_IntForEachEntry( vOuts, Entry, i )
|
||||
printf( "%d(%d) ", Entry, Vec_BitEntry(vPhase, Entry) );
|
||||
printf( "\n" );
|
||||
|
||||
printf( "Inputs: " );
|
||||
Vec_IntForEachEntry( vIns, Entry, i )
|
||||
{
|
||||
printf( "%d(%d) ", Entry, Vec_BitEntry(vPhase, Entry) );
|
||||
nCompls += Vec_BitEntry(vPhase, Entry);
|
||||
}
|
||||
printf( " Compl = %d\n", nCompls );
|
||||
|
||||
Vec_BitFreeP( &vPhase );
|
||||
Vec_BitFreeP( &vConstPhase );
|
||||
}
|
||||
|
||||
Vec_IntFree( vRoots );
|
||||
Vec_IntFree( vMap );
|
||||
Vec_BitFree( vUnique );
|
||||
Vec_BitFree( vUsed );
|
||||
return nTrees;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Pas_ManComputeCutsTest( Gia_Man_t * p )
|
||||
{
|
||||
extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose );
|
||||
extern Vec_Int_t * Gia_PolynCoreOrder( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vAddCos, Vec_Int_t ** pvIns, Vec_Int_t ** pvOuts );
|
||||
|
||||
extern int Ree_ManCountFadds( Vec_Int_t * vAdds );
|
||||
extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose );
|
||||
abctime clk = Abc_Clock();
|
||||
Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, 1 );
|
||||
Vec_Int_t * vIns, * vOuts;
|
||||
Vec_Int_t * vOrder = Gia_PolynCoreOrder( p, vAdds, NULL, &vIns, &vOuts );
|
||||
int nTrees, nFadds = Ree_ManCountFadds( vAdds );
|
||||
//Ree_ManPrintAdders( vAdds, 1 );
|
||||
printf( "Detected %d FAs and %d HAs. Collected %d adders. ", nFadds, Vec_IntSize(vAdds)/6-nFadds, Vec_IntSize(vOrder) );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
||||
// detect trees
|
||||
clk = Abc_Clock();
|
||||
nTrees = Pas_ManComputeCuts( p, vAdds, vOrder, vIns, vOuts );
|
||||
Vec_IntFree( vAdds );
|
||||
Vec_IntFree( vOrder );
|
||||
Vec_IntFree( vIns );
|
||||
Vec_IntFree( vOuts );
|
||||
|
||||
printf( "Detected %d adder trees. ", nTrees );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
@ -429,7 +429,7 @@ void Gia_PolynBuild2( Gia_Man_t * pGia, int fSigned, int fVerbose, int fVeryVerb
|
|||
{
|
||||
Hsh_VecMan_t * pHashC = Hsh_VecManStart( 1000 ); // hash table for constants
|
||||
Hsh_VecMan_t * pHashM = Hsh_VecManStart( 1000 ); // hash table for monomials
|
||||
Vec_Wec_t * vLit2Mono = Vec_WecStart( Gia_ManObjNum(pGia) * 2 );
|
||||
//Vec_Wec_t * vLit2Mono = Vec_WecStart( Gia_ManObjNum(pGia) * 2 );
|
||||
|
||||
Hsh_VecManStop( pHashC );
|
||||
Hsh_VecManStop( pHashM );
|
||||
|
|
|
|||
|
|
@ -0,0 +1,445 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [acecPool.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [CEC for arithmetic circuits.]
|
||||
|
||||
Synopsis [Core procedures.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: acecPool.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "acecInt.h"
|
||||
#include "misc/vec/vecWec.h"
|
||||
#include "misc/extra/extra.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Acec_ManCreateCarryMap( Gia_Man_t * p, Vec_Int_t * vAdds )
|
||||
{
|
||||
// map carries into their boxes
|
||||
Vec_Int_t * vCarryMap = Vec_IntStartFull( Gia_ManObjNum(p) ); int i;
|
||||
for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ )
|
||||
Vec_IntWriteEntry( vCarryMap, Vec_IntEntry(vAdds, 6*i+4), i );
|
||||
return vCarryMap;
|
||||
}
|
||||
int Acec_ManCheckCarryMap( Gia_Man_t * p, int Carry, Vec_Int_t * vAdds, Vec_Int_t * vCarryMap )
|
||||
{
|
||||
int iBox = Vec_IntEntry( vCarryMap, Carry );
|
||||
assert( iBox >= 0 );
|
||||
return Vec_IntEntry( vCarryMap, Vec_IntEntry(vAdds, 6*iBox+0) ) >= 0 ||
|
||||
Vec_IntEntry( vCarryMap, Vec_IntEntry(vAdds, 6*iBox+1) ) >= 0 ||
|
||||
Vec_IntEntry( vCarryMap, Vec_IntEntry(vAdds, 6*iBox+2) ) >= 0;
|
||||
}
|
||||
Vec_Int_t * Acec_ManCollectCarryRoots( Gia_Man_t * p, Vec_Int_t * vAdds )
|
||||
{
|
||||
Vec_Int_t * vCarryRoots = Vec_IntAlloc( 100 );
|
||||
Vec_Bit_t * vIns = Vec_BitStart( Gia_ManObjNum(p) ); int i;
|
||||
// marks box inputs
|
||||
for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ )
|
||||
{
|
||||
Vec_BitWriteEntry( vIns, Vec_IntEntry(vAdds, 6*i+0), 1 );
|
||||
Vec_BitWriteEntry( vIns, Vec_IntEntry(vAdds, 6*i+1), 1 );
|
||||
Vec_BitWriteEntry( vIns, Vec_IntEntry(vAdds, 6*i+2), 1 );
|
||||
}
|
||||
// collect roots
|
||||
for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ )
|
||||
if ( !Vec_BitEntry(vIns, Vec_IntEntry(vAdds, 6*i+4)) )
|
||||
Vec_IntPush( vCarryRoots, Vec_IntEntry(vAdds, 6*i+4) );
|
||||
Vec_BitFree( vIns );
|
||||
return vCarryRoots;
|
||||
}
|
||||
Vec_Int_t * Acec_ManCollectXorRoots( Gia_Man_t * p, Vec_Int_t * vXors )
|
||||
{
|
||||
Vec_Int_t * vXorRoots = Vec_IntAlloc( 100 );
|
||||
Vec_Bit_t * vIns = Vec_BitStart( Gia_ManObjNum(p) ); int i;
|
||||
// marks box inputs
|
||||
for ( i = 0; 4*i < Vec_IntSize(vXors); i++ )
|
||||
{
|
||||
Vec_BitWriteEntry( vIns, Vec_IntEntry(vXors, 4*i+1), 1 );
|
||||
Vec_BitWriteEntry( vIns, Vec_IntEntry(vXors, 4*i+2), 1 );
|
||||
Vec_BitWriteEntry( vIns, Vec_IntEntry(vXors, 4*i+3), 1 );
|
||||
}
|
||||
// collect roots
|
||||
for ( i = 0; 4*i < Vec_IntSize(vXors); i++ )
|
||||
if ( !Vec_BitEntry(vIns, Vec_IntEntry(vXors, 4*i)) )
|
||||
Vec_IntPush( vXorRoots, Vec_IntEntry(vXors, 4*i) );
|
||||
Vec_BitFree( vIns );
|
||||
return vXorRoots;
|
||||
}
|
||||
void Acec_ManCountXorTreeInputs_rec( Gia_Man_t * p, int Node, Vec_Int_t * vXors, Vec_Int_t * vXorMap, Vec_Bit_t * vIsCarryRoot, Vec_Int_t * vCarryRootSet, Vec_Int_t * vXorSet )
|
||||
{
|
||||
int k, iXorBox;
|
||||
if ( Node == 0 || Gia_ObjIsTravIdCurrentId(p, Node) )
|
||||
return;
|
||||
Gia_ObjSetTravIdCurrentId(p, Node);
|
||||
iXorBox = Vec_IntEntry( vXorMap, Node );
|
||||
if ( iXorBox == -1 )
|
||||
{
|
||||
if ( Vec_BitEntry(vIsCarryRoot, Node) )
|
||||
Vec_IntPush( vCarryRootSet, Node );
|
||||
return;
|
||||
}
|
||||
for ( k = 1; k < 4; k++ )
|
||||
Acec_ManCountXorTreeInputs_rec( p, Vec_IntEntry(vXors, 4*iXorBox+k), vXors, vXorMap, vIsCarryRoot, vCarryRootSet, vXorSet );
|
||||
Vec_IntPush( vXorSet, Vec_IntEntry(vXors, 4*iXorBox) );
|
||||
}
|
||||
Vec_Wec_t * Acec_ManCollectCarryRootSets( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vCarryMap, Vec_Int_t * vXors, Vec_Int_t * vXorRoots, Vec_Int_t * vCarryRoots )
|
||||
{
|
||||
Vec_Wec_t * vCarryRootSets = Vec_WecAlloc( 100 ); // XorBoxes, CarryRoots, AdderBoxes, Ins/Ranks, Outs/Ranks
|
||||
Vec_Int_t * vCarryRootSet = Vec_IntAlloc( 100 );
|
||||
Vec_Bit_t * vIsCarryRoot = Vec_BitStart( Gia_ManObjNum(p) );
|
||||
Vec_Int_t * vXorSet = Vec_IntAlloc( 100 ), * vLevel;
|
||||
int i, k, XorRoot, CarryRoot;
|
||||
// map XORs into their cuts
|
||||
Vec_Int_t * vXorMap = Vec_IntStartFull( Gia_ManObjNum(p) );
|
||||
for ( i = 0; 4*i < Vec_IntSize(vXors); i++ )
|
||||
Vec_IntWriteEntry( vXorMap, Vec_IntEntry(vXors, 4*i), i );
|
||||
// create carry root marks
|
||||
Vec_IntForEachEntry( vCarryRoots, CarryRoot, i )
|
||||
Vec_BitWriteEntry( vIsCarryRoot, CarryRoot, 1 );
|
||||
// collect carry roots attached to each XOR root
|
||||
Vec_IntForEachEntry( vXorRoots, XorRoot, i )
|
||||
{
|
||||
Vec_IntClear( vXorSet );
|
||||
Vec_IntClear( vCarryRootSet );
|
||||
Gia_ManIncrementTravId( p );
|
||||
Acec_ManCountXorTreeInputs_rec( p, XorRoot, vXors, vXorMap, vIsCarryRoot, vCarryRootSet, vXorSet );
|
||||
// skip trivial
|
||||
Vec_IntForEachEntry( vCarryRootSet, CarryRoot, k )
|
||||
if ( Acec_ManCheckCarryMap(p, CarryRoot, vAdds, vCarryMap) )
|
||||
break;
|
||||
if ( k == Vec_IntSize(vCarryRootSet) )
|
||||
continue;
|
||||
Vec_IntSort( vCarryRootSet, 0 );
|
||||
vLevel = Vec_WecPushLevel( vCarryRootSets );
|
||||
Vec_IntAppend( vLevel, vXorSet );
|
||||
vLevel = Vec_WecPushLevel( vCarryRootSets );
|
||||
Vec_IntAppend( vLevel, vCarryRootSet );
|
||||
vLevel = Vec_WecPushLevel( vCarryRootSets );
|
||||
vLevel = Vec_WecPushLevel( vCarryRootSets );
|
||||
vLevel = Vec_WecPushLevel( vCarryRootSets );
|
||||
// unmark carry root set
|
||||
Vec_IntForEachEntry( vCarryRootSet, CarryRoot, k )
|
||||
{
|
||||
assert( Vec_BitEntry(vIsCarryRoot, CarryRoot) );
|
||||
Vec_BitWriteEntry( vIsCarryRoot, CarryRoot, 0 );
|
||||
}
|
||||
}
|
||||
Vec_IntFree( vCarryRootSet );
|
||||
Vec_IntFree( vXorSet );
|
||||
Vec_IntFree( vXorMap );
|
||||
// collect unmarked carry roots
|
||||
Vec_IntForEachEntry( vCarryRoots, CarryRoot, k )
|
||||
{
|
||||
if ( !Vec_BitEntry(vIsCarryRoot, CarryRoot) )
|
||||
continue;
|
||||
if ( !Acec_ManCheckCarryMap(p, CarryRoot, vAdds, vCarryMap) )
|
||||
continue;
|
||||
vLevel = Vec_WecPushLevel( vCarryRootSets );
|
||||
vLevel = Vec_WecPushLevel( vCarryRootSets );
|
||||
Vec_IntFill( vLevel, 1, CarryRoot );
|
||||
vLevel = Vec_WecPushLevel( vCarryRootSets );
|
||||
vLevel = Vec_WecPushLevel( vCarryRootSets );
|
||||
vLevel = Vec_WecPushLevel( vCarryRootSets );
|
||||
}
|
||||
Vec_BitFree( vIsCarryRoot );
|
||||
return vCarryRootSets;
|
||||
}
|
||||
int Acec_ManCompareTwo( int * pPair0, int * pPair1 )
|
||||
{
|
||||
if ( pPair0[1] < pPair1[1] ) return -1;
|
||||
if ( pPair0[1] > pPair1[1] ) return 1;
|
||||
return 0;
|
||||
}
|
||||
void Acec_ManCollectInsOuts( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vBoxes, Vec_Int_t * vBoxRanks, Vec_Bit_t * vBoxIns, Vec_Bit_t * vBoxOuts, Vec_Int_t * vResIns, Vec_Int_t * vResOuts )
|
||||
{
|
||||
int i, k, iBox, iObj, Rank, RankMax = 0;
|
||||
// mark box inputs/outputs
|
||||
Vec_IntForEachEntry( vBoxes, iBox, i )
|
||||
{
|
||||
Vec_BitWriteEntry( vBoxIns, Vec_IntEntry(vAdds, 6*iBox+0), 1 );
|
||||
Vec_BitWriteEntry( vBoxIns, Vec_IntEntry(vAdds, 6*iBox+1), 1 );
|
||||
Vec_BitWriteEntry( vBoxIns, Vec_IntEntry(vAdds, 6*iBox+2), 1 );
|
||||
Vec_BitWriteEntry( vBoxOuts, Vec_IntEntry(vAdds, 6*iBox+3), 1 );
|
||||
Vec_BitWriteEntry( vBoxOuts, Vec_IntEntry(vAdds, 6*iBox+4), 1 );
|
||||
}
|
||||
// collect unmarked inputs/output and their ranks
|
||||
Vec_IntForEachEntry( vBoxes, iBox, i )
|
||||
{
|
||||
for ( k = 0; k < 3; k++ )
|
||||
if ( !Vec_BitEntry(vBoxOuts, Vec_IntEntry(vAdds, 6*iBox+k)) )
|
||||
Vec_IntPushTwo( vResIns, Vec_IntEntry(vAdds, 6*iBox+k), Vec_IntEntry(vBoxRanks, iBox) );
|
||||
for ( k = 3; k < 5; k++ )
|
||||
if ( Vec_IntEntry(vAdds, 6*iBox+k) && !Vec_BitEntry(vBoxIns, Vec_IntEntry(vAdds, 6*iBox+k)) )
|
||||
Vec_IntPushTwo( vResOuts, Vec_IntEntry(vAdds, 6*iBox+k), Vec_IntEntry(vBoxRanks, iBox)-(int)(k==4) );
|
||||
}
|
||||
// unmark box inputs/outputs
|
||||
Vec_IntForEachEntry( vBoxes, iBox, i )
|
||||
{
|
||||
Vec_BitWriteEntry( vBoxIns, Vec_IntEntry(vAdds, 6*iBox+0), 0 );
|
||||
Vec_BitWriteEntry( vBoxIns, Vec_IntEntry(vAdds, 6*iBox+1), 0 );
|
||||
Vec_BitWriteEntry( vBoxIns, Vec_IntEntry(vAdds, 6*iBox+2), 0 );
|
||||
Vec_BitWriteEntry( vBoxOuts, Vec_IntEntry(vAdds, 6*iBox+3), 0 );
|
||||
Vec_BitWriteEntry( vBoxOuts, Vec_IntEntry(vAdds, 6*iBox+4), 0 );
|
||||
}
|
||||
// normalize ranks
|
||||
Vec_IntForEachEntryDouble( vResIns, iObj, Rank, k )
|
||||
RankMax = Abc_MaxInt( RankMax, Rank );
|
||||
Vec_IntForEachEntryDouble( vResOuts, iObj, Rank, k )
|
||||
RankMax = Abc_MaxInt( RankMax, Rank );
|
||||
Vec_IntForEachEntryDouble( vResIns, iObj, Rank, k )
|
||||
Vec_IntWriteEntry( vResIns, k+1, 1 + RankMax - Rank );
|
||||
Vec_IntForEachEntryDouble( vResOuts, iObj, Rank, k )
|
||||
Vec_IntWriteEntry( vResOuts, k+1, 1 + RankMax - Rank );
|
||||
// sort by rank
|
||||
qsort( Vec_IntArray(vResIns), Vec_IntSize(vResIns)/2, 8, (int (*)(const void *, const void *))Acec_ManCompareTwo );
|
||||
qsort( Vec_IntArray(vResOuts), Vec_IntSize(vResOuts)/2, 8, (int (*)(const void *, const void *))Acec_ManCompareTwo );
|
||||
}
|
||||
void Acec_ManCollectBoxSets_rec( Gia_Man_t * p, int Carry, int iRank, Vec_Int_t * vAdds, Vec_Int_t * vCarryMap, Vec_Int_t * vBoxes, Vec_Int_t * vBoxRanks )
|
||||
{
|
||||
int iBox = Vec_IntEntry( vCarryMap, Carry );
|
||||
if ( iBox == -1 )
|
||||
return;
|
||||
Acec_ManCollectBoxSets_rec( p, Vec_IntEntry(vAdds, 6*iBox+0), iRank+1, vAdds, vCarryMap, vBoxes, vBoxRanks );
|
||||
Acec_ManCollectBoxSets_rec( p, Vec_IntEntry(vAdds, 6*iBox+1), iRank+1, vAdds, vCarryMap, vBoxes, vBoxRanks );
|
||||
if ( Vec_IntEntry(vAdds, 6*iBox+2) )
|
||||
Acec_ManCollectBoxSets_rec( p, Vec_IntEntry(vAdds, 6*iBox+2), iRank+1, vAdds, vCarryMap, vBoxes, vBoxRanks );
|
||||
Vec_IntPush( vBoxes, iBox );
|
||||
Vec_IntWriteEntry( vBoxRanks, iBox, iRank );
|
||||
}
|
||||
Vec_Wec_t * Acec_ManCollectBoxSets( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vXors )
|
||||
{
|
||||
Vec_Int_t * vCarryMap = Acec_ManCreateCarryMap( p, vAdds );
|
||||
Vec_Int_t * vCarryRoots = Acec_ManCollectCarryRoots( p, vAdds );
|
||||
Vec_Int_t * vXorRoots = Acec_ManCollectXorRoots( p, vXors );
|
||||
Vec_Wec_t * vBoxSets = Acec_ManCollectCarryRootSets( p, vAdds, vCarryMap, vXors, vXorRoots, vCarryRoots );
|
||||
Vec_Int_t * vBoxRanks = Vec_IntStart( Vec_IntSize(vAdds)/6 );
|
||||
Vec_Bit_t * vBoxIns = Vec_BitStart( Gia_ManObjNum(p) );
|
||||
Vec_Bit_t * vBoxOuts = Vec_BitStart( Gia_ManObjNum(p) ); int i, k, Root;
|
||||
Vec_IntFree( vCarryRoots );
|
||||
Vec_IntFree( vXorRoots );
|
||||
// collect boxes for each carry set
|
||||
assert( Vec_WecSize(vBoxSets) % 5 == 0 );
|
||||
for ( i = 0; 5*i < Vec_WecSize(vBoxSets); i++ )
|
||||
{
|
||||
Vec_Int_t * vRoots = Vec_WecEntry( vBoxSets, 5*i+1 );
|
||||
Vec_Int_t * vBoxes = Vec_WecEntry( vBoxSets, 5*i+2 );
|
||||
Vec_Int_t * vIns = Vec_WecEntry( vBoxSets, 5*i+3 );
|
||||
Vec_Int_t * vOuts = Vec_WecEntry( vBoxSets, 5*i+4 );
|
||||
Vec_IntForEachEntry( vRoots, Root, k )
|
||||
Acec_ManCollectBoxSets_rec( p, Root, 1, vAdds, vCarryMap, vBoxes, vBoxRanks );
|
||||
Acec_ManCollectInsOuts( p, vAdds, vBoxes, vBoxRanks, vBoxIns, vBoxOuts, vIns, vOuts );
|
||||
}
|
||||
Vec_IntFree( vBoxRanks );
|
||||
Vec_BitFree( vBoxIns );
|
||||
Vec_BitFree( vBoxOuts );
|
||||
Vec_IntFree( vCarryMap );
|
||||
return vBoxSets;
|
||||
}
|
||||
void Acec_ManPrintRanks2( Vec_Int_t * vPairs )
|
||||
{
|
||||
int k, iObj, Rank;
|
||||
Vec_IntForEachEntryDouble( vPairs, iObj, Rank, k )
|
||||
printf( "%d ", Rank );
|
||||
printf( "\n" );
|
||||
}
|
||||
void Acec_ManPrintRanks( Vec_Int_t * vPairs )
|
||||
{
|
||||
int k, iObj, Count, Rank, RankMax = 0;
|
||||
Vec_Int_t * vCounts = Vec_IntStart( 100 );
|
||||
Vec_IntForEachEntryDouble( vPairs, iObj, Rank, k )
|
||||
{
|
||||
Vec_IntFillExtra( vCounts, Rank+1, 0 );
|
||||
Vec_IntAddToEntry( vCounts, Rank, 1 );
|
||||
RankMax = Abc_MaxInt( RankMax, Rank );
|
||||
}
|
||||
Vec_IntForEachEntryStartStop( vCounts, Count, Rank, 1, RankMax+1 )
|
||||
printf( "%2d=%2d ", Rank, Count );
|
||||
printf( "\n" );
|
||||
Vec_IntFree( vCounts );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Acec_ManProfile( Gia_Man_t * p, int fVerbose )
|
||||
{
|
||||
extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose );
|
||||
extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds );
|
||||
extern void Ree_ManRemoveContained( Gia_Man_t * p, Vec_Int_t * vAdds );
|
||||
extern int Ree_ManCountFadds( Vec_Int_t * vAdds );
|
||||
extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose );
|
||||
|
||||
abctime clk = Abc_Clock();
|
||||
Vec_Wec_t * vBoxes; int i;
|
||||
Vec_Int_t * vXors, * vAdds = Ree_ManComputeCuts( p, &vXors, fVerbose );
|
||||
Ree_ManRemoveTrivial( p, vAdds );
|
||||
Ree_ManRemoveContained( p, vAdds );
|
||||
|
||||
//Ree_ManPrintAdders( vAdds, 1 );
|
||||
printf( "Detected %d full-adders and %d half-adders. Found %d XOR-cuts. ", Ree_ManCountFadds(vAdds), Vec_IntSize(vAdds)/6-Ree_ManCountFadds(vAdds), Vec_IntSize(vXors)/4 );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
||||
|
||||
clk = Abc_Clock();
|
||||
vBoxes = Acec_ManCollectBoxSets( p, vAdds, vXors );
|
||||
printf( "Detected %d adder-tree%s. ", Vec_WecSize(vBoxes)/5, Vec_WecSize(vBoxes)/5 > 1 ? "s":"" );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
||||
|
||||
if ( fVerbose )
|
||||
for ( i = 0; 5*i < Vec_WecSize(vBoxes); i++ )
|
||||
{
|
||||
printf( "Tree %3d : ", i );
|
||||
printf( "Xor = %4d ", Vec_IntSize(Vec_WecEntry(vBoxes,5*i+0)) );
|
||||
printf( "Root = %4d ", Vec_IntSize(Vec_WecEntry(vBoxes,5*i+1)) );
|
||||
//printf( "(Top = %5d) ", Vec_IntEntryLast(Vec_WecEntry(vBoxes,5*i+1)) );
|
||||
printf( "Adder = %4d ", Vec_IntSize(Vec_WecEntry(vBoxes,5*i+2)) );
|
||||
printf( "In = %4d ", Vec_IntSize(Vec_WecEntry(vBoxes,5*i+3))/2 );
|
||||
printf( "Out = %4d ", Vec_IntSize(Vec_WecEntry(vBoxes,5*i+4))/2 );
|
||||
printf( "\n" );
|
||||
printf( " Ins: " );
|
||||
Acec_ManPrintRanks( Vec_WecEntry(vBoxes,5*i+3) );
|
||||
printf( " Outs: " );
|
||||
Acec_ManPrintRanks( Vec_WecEntry(vBoxes,5*i+4) );
|
||||
}
|
||||
|
||||
Vec_IntFree( vXors );
|
||||
Vec_IntFree( vAdds );
|
||||
Vec_WecFree( vBoxes );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Bit_t * Acec_ManPoolGetPointed( Gia_Man_t * p, Vec_Int_t * vAdds )
|
||||
{
|
||||
Vec_Bit_t * vMarks = Vec_BitStart( Gia_ManObjNum(p) );
|
||||
int i, k;
|
||||
for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ )
|
||||
for ( k = 0; k < 3; k++ )
|
||||
Vec_BitWriteEntry( vMarks, Vec_IntEntry(vAdds, 6*i+k), 1 );
|
||||
return vMarks;
|
||||
}
|
||||
|
||||
Vec_Int_t * Acec_ManPoolTopMost( Gia_Man_t * p, Vec_Int_t * vAdds )
|
||||
{
|
||||
int i, k, iTop, fVerbose = 0;
|
||||
Vec_Int_t * vTops = Vec_IntAlloc( 1000 );
|
||||
Vec_Bit_t * vMarks = Acec_ManPoolGetPointed( p, vAdds );
|
||||
|
||||
for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ )
|
||||
if ( !Vec_BitEntry(vMarks, Vec_IntEntry(vAdds, 6*i+3)) &&
|
||||
!Vec_BitEntry(vMarks, Vec_IntEntry(vAdds, 6*i+4)) )
|
||||
Vec_IntPush( vTops, i );
|
||||
|
||||
if ( fVerbose )
|
||||
Vec_IntForEachEntry( vTops, iTop, i )
|
||||
{
|
||||
printf( "%4d : ", iTop );
|
||||
for ( k = 0; k < 3; k++ )
|
||||
printf( "%4d ", Vec_IntEntry(vAdds, 6*iTop+k) );
|
||||
printf( " -> " );
|
||||
for ( k = 3; k < 5; k++ )
|
||||
printf( "%4d ", Vec_IntEntry(vAdds, 6*iTop+k) );
|
||||
printf( "\n" );
|
||||
}
|
||||
|
||||
Vec_BitFree( vMarks );
|
||||
return vTops;
|
||||
}
|
||||
void Acec_ManPool( Gia_Man_t * p )
|
||||
{
|
||||
extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose );
|
||||
extern Vec_Wec_t * Gia_PolynCoreOrderArray( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vRootBoxes );
|
||||
|
||||
extern int Ree_ManCountFadds( Vec_Int_t * vAdds );
|
||||
extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose );
|
||||
extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds );
|
||||
extern void Ree_ManRemoveContained( Gia_Man_t * p, Vec_Int_t * vAdds );
|
||||
Vec_Int_t * vTops, * vTree;
|
||||
Vec_Wec_t * vTrees;
|
||||
|
||||
abctime clk = Abc_Clock();
|
||||
Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, 1 );
|
||||
int i, nFadds = Ree_ManCountFadds( vAdds );
|
||||
printf( "Detected %d FAs and %d HAs. ", nFadds, Vec_IntSize(vAdds)/6-nFadds );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
||||
|
||||
clk = Abc_Clock();
|
||||
Ree_ManRemoveTrivial( p, vAdds );
|
||||
Ree_ManRemoveContained( p, vAdds );
|
||||
nFadds = Ree_ManCountFadds( vAdds );
|
||||
printf( "Detected %d FAs and %d HAs. ", nFadds, Vec_IntSize(vAdds)/6-nFadds );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
||||
|
||||
//Ree_ManPrintAdders( vAdds, 1 );
|
||||
|
||||
// detect topmost nodes
|
||||
vTops = Acec_ManPoolTopMost( p, vAdds );
|
||||
printf( "Detected %d topmost adder%s.\n", Vec_IntSize(vTops), Vec_IntSize(vTops) > 1 ? "s":"" );
|
||||
|
||||
// collect adder trees
|
||||
vTrees = Gia_PolynCoreOrderArray( p, vAdds, vTops );
|
||||
Vec_WecForEachLevel( vTrees, vTree, i )
|
||||
printf( "Adder %5d : Tree with %5d nodes.\n", Vec_IntEntry(vTops, i), Vec_IntSize(vTree) );
|
||||
|
||||
Vec_WecFree( vTrees );
|
||||
Vec_IntFree( vAdds );
|
||||
Vec_IntFree( vTops );
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
@ -69,6 +69,18 @@ void Ree_TruthPrecompute()
|
|||
}
|
||||
printf( "\n" );
|
||||
}
|
||||
void Ree_TruthPrecompute2()
|
||||
{
|
||||
int i, b;
|
||||
for ( i = 0; i < 8; i++ )
|
||||
{
|
||||
word Truth = 0xE8;
|
||||
for ( b = 0; b < 3; b++ )
|
||||
if ( (i >> b) & 1 )
|
||||
Truth = Abc_Tt6Flip( Truth, b );
|
||||
printf( "%d = %X\n", i, 0xFF & (int)Truth );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
@ -236,10 +248,11 @@ void Ree_ManCutPrint( int * pCut, int Count, word Truth )
|
|||
Abc_TtPrintHexRev( stdout, &Truth, 3 );
|
||||
printf( "\n" );
|
||||
}
|
||||
void Ree_ManCutMerge( Gia_Man_t * p, int iObj, int * pList0, int * pList1, Vec_Int_t * vCuts, Hash_IntMan_t * pHash, Vec_Int_t * vData )
|
||||
void Ree_ManCutMerge( Gia_Man_t * p, int iObj, int * pList0, int * pList1, Vec_Int_t * vCuts, Hash_IntMan_t * pHash, Vec_Int_t * vData, Vec_Int_t * vXors )
|
||||
{
|
||||
int fVerbose = 0;
|
||||
int i, k, c, Value, Truth, TruthC, * pCut0, * pCut1, pCut[5], Count = 0;
|
||||
int i, k, c, Value, Truth, TruthC, * pCut0, * pCut1, pCut[6], Count = 0;
|
||||
int iXor2 = -1, iXor3 = -1;
|
||||
if ( fVerbose )
|
||||
printf( "Object %d\n", iObj );
|
||||
Vec_IntFill( vCuts, 2, 1 );
|
||||
|
|
@ -254,12 +267,16 @@ void Ree_ManCutMerge( Gia_Man_t * p, int iObj, int * pList0, int * pList1, Vec_I
|
|||
continue;
|
||||
Truth = TruthC = Ree_ManCutTruth(Gia_ManObj(p, iObj), pCut0, pCut1, pCut);
|
||||
//assert( Truth == Ree_ObjComputeTruth(p, iObj, pCut) );
|
||||
if ( Truth & 0x80 )
|
||||
Truth = 0xFF & ~Truth;
|
||||
if ( Truth == 0x66 && iXor2 == -1 )
|
||||
iXor2 = Vec_IntSize(vCuts);
|
||||
else if ( Truth == 0x69 && iXor3 == -1 )
|
||||
iXor3 = Vec_IntSize(vCuts);
|
||||
Vec_IntAddToEntry( vCuts, 0, 1 );
|
||||
for ( c = 0; c <= pCut[0]; c++ )
|
||||
Vec_IntPush( vCuts, pCut[c] );
|
||||
Vec_IntPush( vCuts, Truth );
|
||||
if ( Truth & 0x80 )
|
||||
Truth = 0xFF & ~Truth;
|
||||
Vec_IntPush( vCuts, TruthC );
|
||||
if ( (Truth == 0x66 || Truth == 0x11 || Truth == 0x22 || Truth == 0x44 || Truth == 0x77) && pCut[0] == 2 )
|
||||
{
|
||||
assert( pCut[0] == 2 );
|
||||
|
|
@ -275,6 +292,19 @@ void Ree_ManCutMerge( Gia_Man_t * p, int iObj, int * pList0, int * pList1, Vec_I
|
|||
if ( fVerbose )
|
||||
Ree_ManCutPrint( pCut, ++Count, TruthC );
|
||||
}
|
||||
if ( !vXors )
|
||||
return;
|
||||
if ( iXor2 > 0 )
|
||||
pCut0 = Vec_IntEntryP( vCuts, iXor2 );
|
||||
else if ( iXor3 > 0 )
|
||||
pCut0 = Vec_IntEntryP( vCuts, iXor3 );
|
||||
else
|
||||
return;
|
||||
Vec_IntPush( vXors, iObj );
|
||||
for ( c = 1; c <= pCut0[0]; c++ )
|
||||
Vec_IntPush( vXors, pCut0[c] );
|
||||
if ( pCut0[0] == 2 )
|
||||
Vec_IntPush( vXors, 0 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -288,9 +318,9 @@ void Ree_ManCutMerge( Gia_Man_t * p, int iObj, int * pList0, int * pList1, Vec_I
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Ree_ManDeriveAdds( Hash_IntMan_t * p, Vec_Int_t * vData )
|
||||
Vec_Int_t * Ree_ManDeriveAdds( Hash_IntMan_t * p, Vec_Int_t * vData, int fVerbose )
|
||||
{
|
||||
int i, j, k, iObj, iObj2, Value, Truth, CountX, CountM, Index = 0;
|
||||
int i, j, k, iObj, iObj2, Value, Truth, Truth2, CountX, CountM, Index = 0;
|
||||
int nEntries = Hash_IntManEntryNum(p);
|
||||
Vec_Int_t * vAdds = Vec_IntAlloc( 1000 );
|
||||
Vec_Int_t * vXors = Vec_IntStart( nEntries + 1 );
|
||||
|
|
@ -315,7 +345,8 @@ Vec_Int_t * Ree_ManDeriveAdds( Hash_IntMan_t * p, Vec_Int_t * vData )
|
|||
}
|
||||
Vec_IntFree( vXors );
|
||||
Vec_IntFree( vMajs );
|
||||
printf( "Detected %d shared cuts among %d hashed cuts.\n", Index, nEntries );
|
||||
//if ( fVerbose )
|
||||
// printf( "Detected %d shared cuts among %d hashed cuts.\n", Index, nEntries );
|
||||
// collect nodes
|
||||
vXorMap = Vec_WecStart( Index );
|
||||
vMajMap = Vec_WecStart( Index );
|
||||
|
|
@ -325,9 +356,9 @@ Vec_Int_t * Ree_ManDeriveAdds( Hash_IntMan_t * p, Vec_Int_t * vData )
|
|||
if ( Index == -1 )
|
||||
continue;
|
||||
if ( Truth == 0x66 || Truth == 0x99 || Truth == 0x69 || Truth == 0x96 )
|
||||
Vec_WecPush( vXorMap, Index, iObj );
|
||||
Vec_IntPushTwo( Vec_WecEntry(vXorMap, Index), iObj, Truth );
|
||||
else
|
||||
Vec_WecPush( vMajMap, Index, iObj );
|
||||
Vec_IntPushTwo( Vec_WecEntry(vMajMap, Index), iObj, Truth );
|
||||
}
|
||||
Vec_IntFree( vIndex );
|
||||
// create pairs
|
||||
|
|
@ -336,11 +367,22 @@ Vec_Int_t * Ree_ManDeriveAdds( Hash_IntMan_t * p, Vec_Int_t * vData )
|
|||
Vec_Int_t * vXorOne = Vec_WecEntry( vXorMap, i );
|
||||
Vec_Int_t * vMajOne = Vec_WecEntry( vMajMap, i );
|
||||
Hash_IntObj_t * pObj = Hash_IntObj( p, Value );
|
||||
Vec_IntForEachEntry( vXorOne, iObj, j )
|
||||
Vec_IntForEachEntry( vMajOne, iObj2, k )
|
||||
Vec_IntForEachEntryDouble( vXorOne, iObj, Truth, j )
|
||||
Vec_IntForEachEntryDouble( vMajOne, iObj2, Truth2, k )
|
||||
{
|
||||
int SignAnd[8] = {0x88, 0x44, 0x22, 0x11, 0xEE, 0xDD, 0xBB, 0x77};
|
||||
int SignMaj[8] = {0xE8, 0xD4, 0xB2, 0x71, 0x8E, 0x4D, 0x2B, 0x17};
|
||||
int n, SignXor = (Truth == 0x99 || Truth == 0x69) << 3;
|
||||
for ( n = 0; n < 8; n++ )
|
||||
if ( Truth2 == SignMaj[n] )
|
||||
break;
|
||||
if ( n == 8 )
|
||||
for ( n = 0; n < 8; n++ )
|
||||
if ( Truth2 == SignAnd[n] )
|
||||
break;
|
||||
assert( n < 8 );
|
||||
Vec_IntPushThree( vAdds, pObj->iData0, pObj->iData1, pObj->iData2 );
|
||||
Vec_IntPushTwo( vAdds, iObj, iObj2 );
|
||||
Vec_IntPushThree( vAdds, iObj, iObj2, SignXor | n );
|
||||
}
|
||||
}
|
||||
Vec_IntFree( vIndexRev );
|
||||
|
|
@ -348,7 +390,7 @@ Vec_Int_t * Ree_ManDeriveAdds( Hash_IntMan_t * p, Vec_Int_t * vData )
|
|||
Vec_WecFree( vMajMap );
|
||||
return vAdds;
|
||||
}
|
||||
Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, int fVerbose )
|
||||
Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose )
|
||||
{
|
||||
Gia_Obj_t * pObj;
|
||||
int * pList0, * pList1, i, nCuts = 0;
|
||||
|
|
@ -367,29 +409,76 @@ Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, int fVerbose )
|
|||
Vec_IntPush( vCuts, Gia_ObjId(p, pObj) );
|
||||
Vec_IntPush( vCuts, 0xAA );
|
||||
}
|
||||
if ( pvXors ) *pvXors = Vec_IntAlloc( 1000 );
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
{
|
||||
pList0 = Vec_IntEntryP( vCuts, Vec_IntEntry(vCuts, Gia_ObjFaninId0(pObj, i)) );
|
||||
pList1 = Vec_IntEntryP( vCuts, Vec_IntEntry(vCuts, Gia_ObjFaninId1(pObj, i)) );
|
||||
Ree_ManCutMerge( p, i, pList0, pList1, vTemp, pHash, vData );
|
||||
Ree_ManCutMerge( p, i, pList0, pList1, vTemp, pHash, vData, pvXors ? *pvXors : NULL );
|
||||
Vec_IntWriteEntry( vCuts, i, Vec_IntSize(vCuts) );
|
||||
Vec_IntAppend( vCuts, vTemp );
|
||||
nCuts += Vec_IntEntry( vTemp, 0 );
|
||||
}
|
||||
if ( fVerbose )
|
||||
printf( "Nodes = %d. Cuts = %d. Cuts/Node = %.2f. Ints/Node = %.2f.\n",
|
||||
printf( "AIG nodes = %d. Cuts = %d. Cuts/Node = %.2f. Ints/Node = %.2f.\n",
|
||||
Gia_ManAndNum(p), nCuts, 1.0*nCuts/Gia_ManAndNum(p), 1.0*Vec_IntSize(vCuts)/Gia_ManAndNum(p) );
|
||||
Vec_IntFree( vTemp );
|
||||
Vec_IntFree( vCuts );
|
||||
vAdds = Ree_ManDeriveAdds( pHash, vData );
|
||||
vAdds = Ree_ManDeriveAdds( pHash, vData, fVerbose );
|
||||
if ( fVerbose )
|
||||
printf( "Adds = %d. Total = %d. Hashed = %d. Hashed/Adds = %.2f.\n",
|
||||
Vec_IntSize(vAdds)/5, Vec_IntSize(vData)/3, Hash_IntManEntryNum(pHash), 5.0*Hash_IntManEntryNum(pHash)/Vec_IntSize(vAdds) );
|
||||
printf( "Adders = %d. Total cuts = %d. Hashed cuts = %d. Hashed/Adders = %.2f.\n",
|
||||
Vec_IntSize(vAdds)/6, Vec_IntSize(vData)/3, Hash_IntManEntryNum(pHash), 6.0*Hash_IntManEntryNum(pHash)/Vec_IntSize(vAdds) );
|
||||
Vec_IntFree( vData );
|
||||
Hash_IntManStop( pHash );
|
||||
return vAdds;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Highlight nodes inside FAs.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ree_CollectInsiders_rec( Gia_Man_t * pGia, int iObj, Vec_Bit_t * vVisited, Vec_Bit_t * vInsiders )
|
||||
{
|
||||
if ( Vec_BitEntry(vVisited, iObj) )
|
||||
return;
|
||||
Vec_BitSetEntry( vVisited, iObj, 1 );
|
||||
Ree_CollectInsiders_rec( pGia, Gia_ObjFaninId0p(pGia, Gia_ManObj(pGia, iObj)), vVisited, vInsiders );
|
||||
Ree_CollectInsiders_rec( pGia, Gia_ObjFaninId1p(pGia, Gia_ManObj(pGia, iObj)), vVisited, vInsiders );
|
||||
Vec_BitSetEntry( vInsiders, iObj, 1 );
|
||||
}
|
||||
Vec_Bit_t * Ree_CollectInsiders( Gia_Man_t * pGia, Vec_Int_t * vAdds )
|
||||
{
|
||||
Vec_Bit_t * vVisited = Vec_BitStart( Gia_ManObjNum(pGia) );
|
||||
Vec_Bit_t * vInsiders = Vec_BitStart( Gia_ManObjNum(pGia) );
|
||||
int i, Entry1, Entry2, Entry3;
|
||||
for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ )
|
||||
{
|
||||
if ( Vec_IntEntry(vAdds, 6*i+2) == 0 ) // HADD
|
||||
continue;
|
||||
// mark inputs
|
||||
Entry1 = Vec_IntEntry( vAdds, 6*i + 0 );
|
||||
Entry2 = Vec_IntEntry( vAdds, 6*i + 1 );
|
||||
Entry3 = Vec_IntEntry( vAdds, 6*i + 2 );
|
||||
Vec_BitWriteEntry( vVisited, Entry1, 1 );
|
||||
Vec_BitWriteEntry( vVisited, Entry2, 1 );
|
||||
Vec_BitWriteEntry( vVisited, Entry3, 1 );
|
||||
// traverse from outputs
|
||||
Entry1 = Vec_IntEntry( vAdds, 6*i + 3 );
|
||||
Entry2 = Vec_IntEntry( vAdds, 6*i + 4 );
|
||||
Ree_CollectInsiders_rec( pGia, Entry1, vVisited, vInsiders );
|
||||
Ree_CollectInsiders_rec( pGia, Entry2, vVisited, vInsiders );
|
||||
}
|
||||
Vec_BitFree( vVisited );
|
||||
return vInsiders;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -401,28 +490,80 @@ Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, int fVerbose )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
// removes HAs whose AND2 is part of XOR2 without additional fanout
|
||||
void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds )
|
||||
{
|
||||
Gia_Obj_t * pObjX, * pObjM;
|
||||
int i, k = 0;
|
||||
ABC_FREE( p->pRefs );
|
||||
Gia_ManCreateRefs( p );
|
||||
for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ )
|
||||
{
|
||||
if ( Vec_IntEntry(vAdds, 6*i+2) == 0 ) // HADD
|
||||
{
|
||||
pObjX = Gia_ManObj( p, Vec_IntEntry(vAdds, 6*i+3) );
|
||||
pObjM = Gia_ManObj( p, Vec_IntEntry(vAdds, 6*i+4) );
|
||||
if ( (pObjM == Gia_ObjFanin0(pObjX) || pObjM == Gia_ObjFanin1(pObjX)) && Gia_ObjRefNum(p, pObjM) == 1 )
|
||||
continue;
|
||||
}
|
||||
memmove( Vec_IntArray(vAdds) + 6*k++, Vec_IntArray(vAdds) + 6*i, 6*sizeof(int) );
|
||||
}
|
||||
assert( k <= i );
|
||||
Vec_IntShrink( vAdds, 6*k );
|
||||
}
|
||||
// removes HAs fully contained inside FAs
|
||||
void Ree_ManRemoveContained( Gia_Man_t * p, Vec_Int_t * vAdds )
|
||||
{
|
||||
Vec_Bit_t * vInsiders = Ree_CollectInsiders( p, vAdds );
|
||||
int i, k = 0;
|
||||
for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ )
|
||||
{
|
||||
if ( Vec_IntEntry(vAdds, 6*i+2) == 0 ) // HADD
|
||||
if ( Vec_BitEntry(vInsiders, Vec_IntEntry(vAdds, 6*i+3)) && Vec_BitEntry(vInsiders, Vec_IntEntry(vAdds, 6*i+4)) )
|
||||
continue;
|
||||
memmove( Vec_IntArray(vAdds) + 6*k++, Vec_IntArray(vAdds) + 6*i, 6*sizeof(int) );
|
||||
}
|
||||
assert( k <= i );
|
||||
Vec_IntShrink( vAdds, 6*k );
|
||||
Vec_BitFree( vInsiders );
|
||||
}
|
||||
|
||||
int Ree_ManCountFadds( Vec_Int_t * vAdds )
|
||||
{
|
||||
int i, Count = 0;
|
||||
for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ )
|
||||
if ( Vec_IntEntry(vAdds, 6*i+2) != 0 )
|
||||
Count++;
|
||||
return Count;
|
||||
}
|
||||
void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ )
|
||||
{
|
||||
//if ( Vec_IntEntry(vAdds, 6*i+2) == 0 )
|
||||
// continue;
|
||||
if ( !fVerbose )
|
||||
continue;
|
||||
printf( "%6d : ", i );
|
||||
printf( "%6d ", Vec_IntEntry(vAdds, 6*i+0) );
|
||||
printf( "%6d ", Vec_IntEntry(vAdds, 6*i+1) );
|
||||
printf( "%6d ", Vec_IntEntry(vAdds, 6*i+2) );
|
||||
printf( " -> " );
|
||||
printf( "%6d ", Vec_IntEntry(vAdds, 6*i+3) );
|
||||
printf( "%6d ", Vec_IntEntry(vAdds, 6*i+4) );
|
||||
printf( " (%d)", Vec_IntEntry(vAdds, 6*i+5) );
|
||||
printf( "\n" );
|
||||
}
|
||||
}
|
||||
void Ree_ManComputeCutsTest( Gia_Man_t * p )
|
||||
{
|
||||
abctime clk = Abc_Clock();
|
||||
Vec_Int_t * vAdds = Ree_ManComputeCuts( p, 1 );
|
||||
int i, Count = 0;
|
||||
for ( i = 0; 5*i < Vec_IntSize(vAdds); i++ )
|
||||
{
|
||||
if ( Vec_IntEntry(vAdds, 5*i+2) == 0 )
|
||||
continue;
|
||||
Count++;
|
||||
continue;
|
||||
printf( "%6d : ", i );
|
||||
printf( "%6d ", Vec_IntEntry(vAdds, 5*i+0) );
|
||||
printf( "%6d ", Vec_IntEntry(vAdds, 5*i+1) );
|
||||
printf( "%6d ", Vec_IntEntry(vAdds, 5*i+2) );
|
||||
printf( " -> " );
|
||||
printf( "%6d ", Vec_IntEntry(vAdds, 5*i+3) );
|
||||
printf( "%6d ", Vec_IntEntry(vAdds, 5*i+4) );
|
||||
printf( "\n" );
|
||||
}
|
||||
Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, 1 );
|
||||
int nFadds = Ree_ManCountFadds( vAdds );
|
||||
Ree_ManPrintAdders( vAdds, 1 );
|
||||
printf( "Detected %d FAs and %d HAs. ", nFadds, Vec_IntSize(vAdds)/6-nFadds );
|
||||
Vec_IntFree( vAdds );
|
||||
printf( "Detected %d FAs and %d HAs. ", Count, Vec_IntSize(vAdds)/5-Count );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
SRC += src/proof/acec/acecCore.c \
|
||||
SRC += src/proof/acec/acecCl.c \
|
||||
src/proof/acec/acecCore.c \
|
||||
src/proof/acec/acecCo.c \
|
||||
src/proof/acec/acecRe.c \
|
||||
src/proof/acec/acecPa.c \
|
||||
src/proof/acec/acecPo.c \
|
||||
src/proof/acec/acecPool.c \
|
||||
src/proof/acec/acecCover.c \
|
||||
src/proof/acec/acecFadds.c \
|
||||
src/proof/acec/acecOrder.c \
|
||||
|
|
|
|||
Loading…
Reference in New Issue