mirror of https://github.com/YosysHQ/abc.git
Merge branch 'master' of https://github.com/berkeley-abc/abc into yosys-experimental
This commit is contained in:
commit
208b48667f
|
|
@ -61,3 +61,4 @@ tags
|
|||
|
||||
/cmake
|
||||
/cscope
|
||||
abc.history
|
||||
|
|
|
|||
4
Makefile
4
Makefile
|
|
@ -20,7 +20,7 @@ MODULES := \
|
|||
$(wildcard src/ext*) \
|
||||
src/base/abc src/base/abci src/base/cmd src/base/io src/base/main src/base/exor \
|
||||
src/base/ver src/base/wlc src/base/wln src/base/acb src/base/bac src/base/cba src/base/pla src/base/test \
|
||||
src/map/mapper src/map/mio src/map/super src/map/if \
|
||||
src/map/mapper src/map/mio src/map/super src/map/if src/map/if/acd \
|
||||
src/map/amap src/map/cov src/map/scl src/map/mpm \
|
||||
src/misc/extra src/misc/mvc src/misc/st src/misc/util src/misc/nm \
|
||||
src/misc/vec src/misc/hash src/misc/tim src/misc/bzlib src/misc/zlib \
|
||||
|
|
@ -152,7 +152,7 @@ ifdef ABC_USE_LIBSTDCXX
|
|||
endif
|
||||
|
||||
$(info $(MSG_PREFIX)Using CFLAGS=$(CFLAGS))
|
||||
CXXFLAGS += $(CFLAGS)
|
||||
CXXFLAGS += $(CFLAGS) -std=c++11
|
||||
|
||||
SRC :=
|
||||
GARBAGE := core core.* *.stackdump ./tags $(PROG) arch_flags
|
||||
|
|
|
|||
16
abclib.dsp
16
abclib.dsp
|
|
@ -3527,6 +3527,10 @@ SOURCE=.\src\map\if\ifDec16.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\map\if\ifDec66.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\map\if\ifDec75.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
@ -3591,6 +3595,10 @@ SOURCE=.\src\map\if\ifTune.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\map\if\acd\ac_wrapper.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\map\if\ifUtil.c
|
||||
# End Source File
|
||||
# End Group
|
||||
|
|
@ -4903,6 +4911,10 @@ SOURCE=.\src\aig\gia\giaBidec.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\gia\giaBound.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\gia\giaCCof.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
@ -5627,6 +5639,10 @@ SOURCE=.\src\proof\cec\cecPat.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\proof\cec\cecProve.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\proof\cec\cecSat.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
|
|||
|
|
@ -453,7 +453,7 @@ Aig_Obj_t * Aig_Miter( Aig_Man_t * p, Vec_Ptr_t * vPairs )
|
|||
Aig_Obj_t * Aig_MiterTwo( Aig_Man_t * p, Vec_Ptr_t * vNodes1, Vec_Ptr_t * vNodes2 )
|
||||
{
|
||||
int i;
|
||||
assert( vNodes1->nSize > 0 && vNodes1->nSize > 0 );
|
||||
assert( vNodes1->nSize > 0 && vNodes2->nSize > 0 );
|
||||
assert( vNodes1->nSize == vNodes2->nSize );
|
||||
for ( i = 0; i < vNodes1->nSize; i++ )
|
||||
vNodes1->pArray[i] = Aig_Not( Aig_Exor( p, (Aig_Obj_t *)vNodes1->pArray[i], (Aig_Obj_t *)vNodes2->pArray[i] ) );
|
||||
|
|
|
|||
|
|
@ -241,6 +241,9 @@ struct Gia_Man_t_
|
|||
Vec_Int_t vSuppVars; // used variables
|
||||
Vec_Int_t vVarMap; // used variables
|
||||
Gia_Dat_t * pUData;
|
||||
// retiming data
|
||||
Vec_Str_t * vStopsF;
|
||||
Vec_Str_t * vStopsB;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -1250,6 +1253,7 @@ extern int Gia_FileSize( char * pFileName );
|
|||
extern Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSimple, int fSkipStrash, int fCheck );
|
||||
extern Gia_Man_t * Gia_AigerRead( char * pFileName, int fGiaSimple, int fSkipStrash, int fCheck );
|
||||
extern void Gia_AigerWrite( Gia_Man_t * p, char * pFileName, int fWriteSymbols, int fCompact, int fWriteNewLine );
|
||||
extern void Gia_AigerWriteS( Gia_Man_t * p, char * pFileName, int fWriteSymbols, int fCompact, int fWriteNewLine, int fSkipComment );
|
||||
extern void Gia_DumpAiger( Gia_Man_t * p, char * pFilePrefix, int iFileNum, int nFileNumDigits );
|
||||
extern Vec_Str_t * Gia_AigerWriteIntoMemoryStr( Gia_Man_t * p );
|
||||
extern Vec_Str_t * Gia_AigerWriteIntoMemoryStrPart( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAnds, Vec_Int_t * vCos, int nRegs );
|
||||
|
|
@ -1527,7 +1531,8 @@ extern void Gia_ManPrintStatsMiter( Gia_Man_t * p, int fVerbose )
|
|||
extern void Gia_ManSetRegNum( Gia_Man_t * p, int nRegs );
|
||||
extern void Gia_ManReportImprovement( Gia_Man_t * p, Gia_Man_t * pNew );
|
||||
extern void Gia_ManPrintNpnClasses( Gia_Man_t * p );
|
||||
extern void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs, int fVerBufs, int fInter );
|
||||
extern void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs, int fVerBufs, int fInter, int fInterComb, int fAssign, int fReverse );
|
||||
extern void Gia_ManDumpVerilogNand( Gia_Man_t * p, char * pFileName );
|
||||
/*=== giaMem.c ===========================================================*/
|
||||
extern Gia_MmFixed_t * Gia_MmFixedStart( int nEntrySize, int nEntriesMax );
|
||||
extern void Gia_MmFixedStop( Gia_MmFixed_t * p, int fVerbose );
|
||||
|
|
@ -1786,6 +1791,39 @@ extern void Tas_ManSatPrintStats( Tas_Man_t * p );
|
|||
extern int Tas_ManSolve( Tas_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pObj2 );
|
||||
extern int Tas_ManSolveArray( Tas_Man_t * p, Vec_Ptr_t * vObjs );
|
||||
|
||||
/*=== giaBound.c ===========================================================*/
|
||||
typedef struct Bnd_Man_t_ Bnd_Man_t;
|
||||
|
||||
extern Bnd_Man_t* Bnd_ManStart( Gia_Man_t *pSpec, Gia_Man_t *pImpl, int fVerbose );
|
||||
extern void Bnd_ManStop();
|
||||
|
||||
// getter
|
||||
extern int Bnd_ManGetNInternal();
|
||||
extern int Bnd_ManGetNExtra();
|
||||
|
||||
//for fraig
|
||||
extern void Bnd_ManMap( int iLit, int id, int spec );
|
||||
extern void Bnd_ManMerge( int id1, int id2, int phaseDiff );
|
||||
extern void Bnd_ManFinalizeMappings();
|
||||
extern void Bnd_ManPrintMappings();
|
||||
extern Gia_Man_t* Bnd_ManStackGias( Gia_Man_t *pSpec, Gia_Man_t *pImpl );
|
||||
extern int Bnd_ManCheckCoMerged( Gia_Man_t *p );
|
||||
|
||||
// for eco
|
||||
extern int Bnd_ManCheckBound( Gia_Man_t *p, int fVerbose );
|
||||
extern void Bnd_ManFindBound( Gia_Man_t *p, Gia_Man_t *pImpl );
|
||||
extern Gia_Man_t* Bnd_ManGenSpecOut( Gia_Man_t *p );
|
||||
extern Gia_Man_t* Bnd_ManGenImplOut( Gia_Man_t *p );
|
||||
extern Gia_Man_t* Bnd_ManGenPatched( Gia_Man_t *pOut, Gia_Man_t *pSpec, Gia_Man_t *pPatch );
|
||||
extern Gia_Man_t* Bnd_ManGenPatched1( Gia_Man_t *pOut, Gia_Man_t *pSpec );
|
||||
extern Gia_Man_t* Bnd_ManGenPatched2( Gia_Man_t *pImpl, Gia_Man_t *pPatch, int fSkiptStrash, int fVerbose );
|
||||
extern void Bnd_ManSetEqOut( int eq );
|
||||
extern void Bnd_ManSetEqRes( int eq );
|
||||
extern void Bnd_ManPrintStats();
|
||||
|
||||
// util
|
||||
extern Gia_Man_t* Bnd_ManCutBoundary( Gia_Man_t *p, Vec_Int_t* vEI, Vec_Int_t* vEO, Vec_Bit_t* vEI_phase, Vec_Bit_t* vEO_phase );
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1217,7 +1217,7 @@ Vec_Str_t * Gia_AigerWriteIntoMemoryStrPart( Gia_Man_t * p, Vec_Int_t * vCis, Ve
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_AigerWrite( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int fCompact, int fWriteNewLine )
|
||||
void Gia_AigerWriteS( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int fCompact, int fWriteNewLine, int fSkipComment )
|
||||
{
|
||||
int fVerbose = XAIG_VERBOSE;
|
||||
FILE * pFile;
|
||||
|
|
@ -1557,8 +1557,10 @@ void Gia_AigerWrite( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int
|
|||
// write comments
|
||||
if ( fWriteNewLine )
|
||||
fprintf( pFile, "c\n" );
|
||||
fprintf( pFile, "\nThis file was produced by the GIA package in ABC on %s\n", Gia_TimeStamp() );
|
||||
fprintf( pFile, "For information about AIGER format, refer to %s\n", "http://fmv.jku.at/aiger" );
|
||||
if ( !fSkipComment ) {
|
||||
fprintf( pFile, "\nThis file was produced by the GIA package in ABC on %s\n", Gia_TimeStamp() );
|
||||
fprintf( pFile, "For information about AIGER format, refer to %s\n", "http://fmv.jku.at/aiger" );
|
||||
}
|
||||
fclose( pFile );
|
||||
if ( p != pInit )
|
||||
{
|
||||
|
|
@ -1567,6 +1569,22 @@ void Gia_AigerWrite( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int
|
|||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Writes the AIG in the binary AIGER format.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_AigerWrite( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int fCompact, int fWriteNewLine )
|
||||
{
|
||||
Gia_AigerWriteS( pInit, pFileName, fWriteSymbols, fCompact, fWriteNewLine, 0 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Writes the AIG in the binary AIGER format.]
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -55,6 +55,7 @@ Gia_Man_t * Gia_ManDeepSynOne( int nNoImpr, int TimeOut, int nAnds, int Seed, in
|
|||
Abc_Random(0);
|
||||
for ( i = 0; i < IterMax; i++ )
|
||||
{
|
||||
char * pCompress2rs = "balance -l; resub -K 6 -l; rewrite -l; resub -K 6 -N 2 -l; refactor -l; resub -K 8 -l; balance -l; resub -K 8 -N 2 -l; rewrite -l; resub -K 10 -l; rewrite -z -l; resub -K 10 -N 2 -l; balance -l; resub -K 12 -l; refactor -z -l; resub -K 12 -N 2 -l; rewrite -z -l; balance -l";
|
||||
unsigned Rand = Abc_Random(0);
|
||||
int fDch = Rand & 1;
|
||||
//int fCom = (Rand >> 1) & 3;
|
||||
|
|
@ -62,16 +63,16 @@ Gia_Man_t * Gia_ManDeepSynOne( int nNoImpr, int TimeOut, int nAnds, int Seed, in
|
|||
int fFx = (Rand >> 2) & 1;
|
||||
int KLut = fUseTwo ? 2 + (i % 5) : 3 + (i % 4);
|
||||
int fChange = 0;
|
||||
char Command[1000];
|
||||
char * pComp = NULL;
|
||||
char Command[2000];
|
||||
char pComp[1000];
|
||||
if ( fCom == 3 )
|
||||
pComp = "; &put; compress2rs; compress2rs; compress2rs; &get";
|
||||
sprintf( pComp, "; &put; %s; %s; %s; &get", pCompress2rs, pCompress2rs, pCompress2rs );
|
||||
else if ( fCom == 2 )
|
||||
pComp = "; &put; compress2rs; compress2rs; &get";
|
||||
sprintf( pComp, "; &put; %s; %s; &get", pCompress2rs, pCompress2rs );
|
||||
else if ( fCom == 1 )
|
||||
pComp = "; &put; compress2rs; &get";
|
||||
sprintf( pComp, "; &put; %s; &get", pCompress2rs );
|
||||
else if ( fCom == 0 )
|
||||
pComp = "; &dc2";
|
||||
sprintf( pComp, "; &dc2" );
|
||||
sprintf( Command, "&dch%s; &if -a -K %d; &mfs -e -W 20 -L 20%s%s",
|
||||
fDch ? " -f" : "", KLut, fFx ? "; &fx; &st" : "", pComp );
|
||||
if ( Abc_FrameIsBatchMode() )
|
||||
|
|
|
|||
|
|
@ -30,6 +30,9 @@ ABC_NAMESPACE_IMPL_START
|
|||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
extern Bnd_Man_t* pBnd;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -788,6 +791,11 @@ Gia_Man_t * Gia_ManDupWithAttributes( Gia_Man_t * p )
|
|||
pNew->vConfigs = Vec_IntDup( p->vConfigs );
|
||||
if ( p->pCellStr )
|
||||
pNew->pCellStr = Abc_UtilStrsav( p->pCellStr );
|
||||
// copy names if present
|
||||
if ( p->vNamesIn )
|
||||
pNew->vNamesIn = Vec_PtrDupStr( p->vNamesIn );
|
||||
if ( p->vNamesOut )
|
||||
pNew->vNamesOut = Vec_PtrDupStr( p->vNamesOut );
|
||||
return pNew;
|
||||
}
|
||||
Gia_Man_t * Gia_ManDupRemovePis( Gia_Man_t * p, int nRemPis )
|
||||
|
|
@ -5669,7 +5677,7 @@ Gia_Man_t * Gia_ManDupAddFlop( Gia_Man_t * p )
|
|||
***********************************************************************/
|
||||
Gia_Man_t * Gia_ManBoundaryMiter( Gia_Man_t * p1, Gia_Man_t * p2, int fVerbose )
|
||||
{
|
||||
Vec_Int_t * vLits;
|
||||
// Vec_Int_t * vLits;
|
||||
Gia_Man_t * pNew, * pTemp;
|
||||
Gia_Obj_t * pObj;
|
||||
int i, iLit;
|
||||
|
|
@ -5687,7 +5695,7 @@ Gia_Man_t * Gia_ManBoundaryMiter( Gia_Man_t * p1, Gia_Man_t * p2, int fVerbose )
|
|||
assert( Gia_ManRegNum(p2) == 0 );
|
||||
assert( Gia_ManCiNum(p1) == Gia_ManCiNum(p2) );
|
||||
assert( Gia_ManCoNum(p1) == Gia_ManCoNum(p2) );
|
||||
vLits = Vec_IntAlloc( Gia_ManBufNum(p1) );
|
||||
// vLits = Vec_IntAlloc( Gia_ManBufNum(p1) );
|
||||
if ( fVerbose )
|
||||
printf( "Creating a boundary miter with %d inputs, %d outputs, and %d buffers.\n",
|
||||
Gia_ManCiNum(p1), Gia_ManCoNum(p1), Gia_ManBufNum(p1) );
|
||||
|
|
@ -5697,28 +5705,124 @@ Gia_Man_t * Gia_ManBoundaryMiter( Gia_Man_t * p1, Gia_Man_t * p2, int fVerbose )
|
|||
Gia_ManHashStart( pNew );
|
||||
Gia_ManConst0(p1)->Value = 0;
|
||||
Gia_ManConst0(p2)->Value = 0;
|
||||
Gia_ManForEachCi( p1, pObj, i )
|
||||
pObj->Value = Gia_ManCi(p2, i)->Value = Gia_ManAppendCi( pNew );
|
||||
Gia_ManForEachAnd( p2, pObj, i )
|
||||
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
Gia_ManForEachAnd( p1, pObj, i ) {
|
||||
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
if ( Gia_ObjIsBuf(pObj) )
|
||||
Vec_IntPush( vLits, pObj->Value );
|
||||
|
||||
|
||||
for( int i = 0; i < Gia_ManCiNum(p1); i++ )
|
||||
{
|
||||
int iLit = Gia_ManCi(p1, i)->Value = Gia_ManCi(p2, i) -> Value = Gia_ManAppendCi(pNew);
|
||||
|
||||
pObj = Gia_ManCi(p1, i);
|
||||
if ( pBnd ) Bnd_ManMap( iLit, Gia_ObjId( p1, pObj ), 1 );
|
||||
|
||||
pObj = Gia_ManCi(p2, i);
|
||||
if ( pBnd ) Bnd_ManMap( iLit, Gia_ObjId( p2, pObj) , 0 );
|
||||
|
||||
}
|
||||
|
||||
// record the corresponding impl node of each lit
|
||||
Gia_ManForEachAnd( p2, pObj, i )
|
||||
{
|
||||
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
if ( pBnd ) Bnd_ManMap( pObj -> Value, Gia_ObjId(p2, pObj), 0 );
|
||||
}
|
||||
|
||||
// record hashed equivalent nodes
|
||||
Gia_ManForEachAnd( p1, pObj, i )
|
||||
{
|
||||
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
if ( pBnd ) Bnd_ManMap( pObj -> Value, Gia_ObjId(p1, pObj), 1 );
|
||||
}
|
||||
|
||||
Gia_ManForEachCo( p2, pObj, i )
|
||||
Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
|
||||
{
|
||||
iLit = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
|
||||
}
|
||||
Gia_ManForEachCo( p1, pObj, i )
|
||||
Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
|
||||
Vec_IntForEachEntry( vLits, iLit, i )
|
||||
Gia_ManAppendCo( pNew, iLit );
|
||||
Vec_IntFree( vLits );
|
||||
{
|
||||
iLit = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
|
||||
}
|
||||
|
||||
// Vec_IntForEachEntry( vLits, iLit, i )
|
||||
// Gia_ManAppendCo( pNew, iLit );
|
||||
// Vec_IntFree( vLits );
|
||||
Gia_ManHashStop( pNew );
|
||||
pNew = Gia_ManCleanup( pTemp = pNew );
|
||||
Gia_ManStop( pTemp );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
Synopsis [Duplicates AIG while putting objects in the DFS order.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Gia_Man_t * Gia_ManImplFromBMiter( Gia_Man_t * p, int nPo, int nBInput )
|
||||
{
|
||||
Gia_Man_t * pNew, *pTemp;
|
||||
Gia_Obj_t * pObj, *pObj2;
|
||||
int i;
|
||||
int nBoundI = 0, nBoundO = 0;
|
||||
int nExtra;
|
||||
Gia_ManFillValue( p );
|
||||
pNew = Gia_ManStart( Gia_ManObjNum(p) );
|
||||
// pNew->pName = Abc_UtilStrsav( p->pName );
|
||||
// pNew->pSpec = Abc_UtilStrsav( p->pSpec );
|
||||
Gia_ManConst0(p)->Value = 0;
|
||||
|
||||
// add po of impl
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
{
|
||||
if ( i < nPo )
|
||||
{
|
||||
Gia_ManDupOrderDfs_rec( pNew, p, pObj );
|
||||
}
|
||||
}
|
||||
nExtra = Gia_ManAndNum( pNew );
|
||||
|
||||
// add boundary as buf
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
{
|
||||
if ( i >= 2 * nPo )
|
||||
{
|
||||
pObj2 = Gia_ObjFanin0(pObj);
|
||||
if (~pObj2->Value) // visited boundary
|
||||
{
|
||||
if ( i >= 2 * nPo + nBInput )
|
||||
{
|
||||
nBoundO ++;
|
||||
}
|
||||
else nBoundI ++;
|
||||
}
|
||||
|
||||
Gia_ManDupOrderDfs_rec( pNew, p, pObj2 );
|
||||
Gia_ManAppendBuf( pNew, Gia_ObjFanin0Copy(pObj) );
|
||||
}
|
||||
}
|
||||
nExtra = Gia_ManAndNum( pNew ) - nExtra - Gia_ManBufNum( pNew );
|
||||
|
||||
Gia_ManForEachCi( p, pObj, i )
|
||||
if ( !~pObj->Value )
|
||||
pObj->Value = Gia_ManAppendCi(pNew);
|
||||
assert( Gia_ManCiNum(pNew) == Gia_ManCiNum(p) );
|
||||
|
||||
Gia_ManDupRemapCis( pNew, p );
|
||||
pNew = Gia_ManCleanup( pTemp = pNew );
|
||||
Gia_ManStop( pTemp );
|
||||
|
||||
|
||||
printf( "synthesized implementation:\n" );
|
||||
printf( "\t%d / %d input boundary recovered.\n", nBoundI, nBInput );
|
||||
printf( "\t%d / %d output boundary recovered.\n", nBoundO, Gia_ManCoNum(p)-2*nPo-nBInput );
|
||||
printf( "\t%d / %d unused nodes in the box.\n", nExtra, Gia_ManAndNum(pNew) - Gia_ManBufNum( pNew ) );
|
||||
|
||||
return pNew;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -715,6 +715,30 @@ Gia_Man_t * Gia_ManEquivReduce( Gia_Man_t * p, int fUseAll, int fDualOut, int fS
|
|||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Duplicates the AIG in the DFS order.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Gia_Obj_t * Gia_MakeRandomChoice( Gia_Man_t * p, int iRepr )
|
||||
{
|
||||
int iTemp, Rand, Count = 0;
|
||||
Gia_ClassForEachObj( p, iRepr, iTemp )
|
||||
Count++;
|
||||
Rand = rand() % Count;
|
||||
Count = 0;
|
||||
Gia_ClassForEachObj( p, iRepr, iTemp )
|
||||
if ( Count++ == Rand )
|
||||
break;
|
||||
return Gia_ManObj(p, iTemp);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Duplicates the AIG in the DFS order.]
|
||||
|
|
@ -735,7 +759,7 @@ void Gia_ManEquivReduce2_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj,
|
|||
if ( fDiveIn && (pRepr = Gia_ManEquivRepr(p, pObj, 1, 0)) )
|
||||
{
|
||||
int iTemp, iRepr = Gia_ObjId(p, pRepr);
|
||||
Gia_Obj_t * pRepr2 = Gia_ManObj( p, Vec_IntEntry(vMap, iRepr) );
|
||||
Gia_Obj_t * pRepr2 = vMap ? Gia_ManObj( p, Vec_IntEntry(vMap, iRepr) ) : Gia_MakeRandomChoice(p, iRepr);
|
||||
Gia_ManEquivReduce2_rec( pNew, p, pRepr2, vMap, 0 );
|
||||
Gia_ClassForEachObj( p, iRepr, iTemp )
|
||||
{
|
||||
|
|
@ -751,12 +775,13 @@ void Gia_ManEquivReduce2_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj,
|
|||
Gia_ManEquivReduce2_rec( pNew, p, Gia_ObjFanin1(pObj), vMap, 1 );
|
||||
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
}
|
||||
Gia_Man_t * Gia_ManEquivReduce2( Gia_Man_t * p )
|
||||
Gia_Man_t * Gia_ManEquivReduce2( Gia_Man_t * p, int fRandom )
|
||||
{
|
||||
Vec_Int_t * vMap;
|
||||
Gia_Man_t * pNew;
|
||||
Gia_Obj_t * pObj;
|
||||
int i;
|
||||
if ( fRandom ) srand(time(NULL));
|
||||
if ( !p->pReprs && p->pSibls )
|
||||
{
|
||||
int * pMap = ABC_FALLOC( int, Gia_ManObjNum(p) );
|
||||
|
|
@ -789,7 +814,7 @@ Gia_Man_t * Gia_ManEquivReduce2( Gia_Man_t * p )
|
|||
break;
|
||||
if ( i == Gia_ManObjNum(p) )
|
||||
return Gia_ManDup( p );
|
||||
vMap = Gia_ManChoiceMinLevel( p );
|
||||
vMap = fRandom ? NULL : Gia_ManChoiceMinLevel( p );
|
||||
Gia_ManSetPhase( p );
|
||||
pNew = Gia_ManStart( Gia_ManObjNum(p) );
|
||||
pNew->pName = Abc_UtilStrsav( p->pName );
|
||||
|
|
@ -805,7 +830,7 @@ Gia_Man_t * Gia_ManEquivReduce2( Gia_Man_t * p )
|
|||
pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
|
||||
Gia_ManHashStop( pNew );
|
||||
Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
|
||||
Vec_IntFree( vMap );
|
||||
Vec_IntFreeP( &vMap );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -150,6 +150,13 @@ Vec_Wrd_t * Gia_ManComputeTruths( Gia_Man_t * p, int nCutSize, int nLutNum, int
|
|||
// collect and sort fanins
|
||||
vLeaves.nCap = vLeaves.nSize = Gia_ObjLutSize( p, i );
|
||||
vLeaves.pArray = Gia_ObjLutFanins( p, i );
|
||||
if( !Vec_IntCheckUniqueSmall(&vLeaves) )
|
||||
{
|
||||
Vec_IntUniqify(&vLeaves);
|
||||
Vec_IntWriteEntry(p->vMapping, Vec_IntEntry(p->vMapping, i), vLeaves.nSize);
|
||||
for ( k = 0; k < vLeaves.nSize; k++ )
|
||||
Vec_IntWriteEntry(p->vMapping, Vec_IntEntry(p->vMapping, i) + 1 + k, vLeaves.pArray[k]);
|
||||
}
|
||||
assert( Vec_IntCheckUniqueSmall(&vLeaves) );
|
||||
Vec_IntSelectSort( Vec_IntArray(&vLeaves), Vec_IntSize(&vLeaves) );
|
||||
if ( !fReverse )
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ Vec_Wec_t * Gia_Iso4Gia( Gia_Man_t * p )
|
|||
Vec_WecForEachLevel( vLevs, vLevel, l )
|
||||
{
|
||||
Gia_Obj_t * pObj; int i;
|
||||
int RandC[2] = { (int)Abc_Random(0), (int)Abc_Random(0) };
|
||||
unsigned RandC[2] = { Abc_Random(0), Abc_Random(0) };
|
||||
if ( l == 0 )
|
||||
{
|
||||
Gia_ManForEachObjVec( vLevel, p, pObj, i )
|
||||
|
|
|
|||
|
|
@ -156,6 +156,8 @@ void Gia_ManStop( Gia_Man_t * p )
|
|||
Vec_IntErase( &p->vHash );
|
||||
Vec_IntErase( &p->vHTable );
|
||||
Vec_IntErase( &p->vRefs );
|
||||
Vec_StrFreeP( &p->vStopsF );
|
||||
Vec_StrFreeP( &p->vStopsB );
|
||||
ABC_FREE( p->pData2 );
|
||||
ABC_FREE( p->pTravIds );
|
||||
ABC_FREE( p->pPlacement );
|
||||
|
|
@ -1252,7 +1254,7 @@ void Gia_ManDfsSlacksPrint( Gia_Man_t * p )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManWriteNamesInter( FILE * pFile, char c, int n, int Start, int Skip, int nRegs )
|
||||
void Gia_ManWriteNamesInter( FILE * pFile, char c, int n, int Start, int Skip, int nRegs, int fReverse )
|
||||
{
|
||||
int Length = Start, i, fFirst = 1;
|
||||
char pName[100];
|
||||
|
|
@ -1291,7 +1293,7 @@ void Gia_ManDumpModuleName( FILE * pFile, char * pName )
|
|||
else
|
||||
fprintf( pFile, "_" );
|
||||
}
|
||||
void Gia_ManDumpInterface( Gia_Man_t * p, FILE * pFile )
|
||||
void Gia_ManDumpInterface2( Gia_Man_t * p, FILE * pFile )
|
||||
{
|
||||
int fPrintClk = 0;
|
||||
fprintf( pFile, "module " );
|
||||
|
|
@ -1316,15 +1318,14 @@ void Gia_ManDumpInterface( Gia_Man_t * p, FILE * pFile )
|
|||
fprintf( pFile, "_inst" );
|
||||
|
||||
fprintf( pFile, " (\n " );
|
||||
Gia_ManWriteNamesInter( pFile, 'i', Gia_ManCiNum(p), 4, 4, Gia_ManRegNum(p) );
|
||||
Gia_ManWriteNamesInter( pFile, 'i', Gia_ManCiNum(p), 4, 4, Gia_ManRegNum(p), 0 );
|
||||
fprintf( pFile, ",\n " );
|
||||
Gia_ManWriteNamesInter( pFile, 'o', Gia_ManCoNum(p), 4, 4, Gia_ManRegNum(p) );
|
||||
Gia_ManWriteNamesInter( pFile, 'o', Gia_ManCoNum(p), 4, 4, Gia_ManRegNum(p), 0 );
|
||||
fprintf( pFile, "\n );\n\n" );
|
||||
|
||||
fprintf( pFile, "endmodule\n\n" );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Compute arrival/required times.]
|
||||
|
|
@ -1386,16 +1387,17 @@ char * Gia_ObjGetDumpName( Vec_Ptr_t * vNames, char c, int i, int d )
|
|||
sprintf( pBuffer, "%c%0*d%c", c, d, i, c );
|
||||
return pBuffer;
|
||||
}
|
||||
void Gia_ManWriteNames( FILE * pFile, char c, int n, Vec_Ptr_t * vNames, int Start, int Skip, Vec_Bit_t * vObjs )
|
||||
void Gia_ManWriteNames( FILE * pFile, char c, int n, Vec_Ptr_t * vNames, int Start, int Skip, Vec_Bit_t * vObjs, int fReverse )
|
||||
{
|
||||
int Digits = Abc_Base10Log( n );
|
||||
int Length = Start, i, fFirst = 1;
|
||||
char * pName;
|
||||
for ( i = 0; i < n; i++ )
|
||||
{
|
||||
if ( vObjs && !Vec_BitEntry(vObjs, i) )
|
||||
int k = fReverse ? n-1-i : i;
|
||||
if ( vObjs && !Vec_BitEntry(vObjs, k) )
|
||||
continue;
|
||||
pName = Gia_ObjGetDumpName( vNames, c, i, Digits );
|
||||
pName = Gia_ObjGetDumpName( vNames, c, k, Digits );
|
||||
Length += strlen(pName) + 2;
|
||||
if ( Length > 60 )
|
||||
{
|
||||
|
|
@ -1407,7 +1409,32 @@ void Gia_ManWriteNames( FILE * pFile, char c, int n, Vec_Ptr_t * vNames, int Sta
|
|||
fFirst = 0;
|
||||
}
|
||||
}
|
||||
void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs, int fVerBufs, int fInter )
|
||||
void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs, int fVerBufs, int fInter, int fInterComb, int fAssign, int fReverse )
|
||||
{
|
||||
if ( fInterComb )
|
||||
{
|
||||
if ( fAssign ) {
|
||||
extern void Gia_ManDumpInterfaceAssign( Gia_Man_t * p, char * pFileName );
|
||||
Gia_ManDumpInterfaceAssign( p, pFileName );
|
||||
}
|
||||
else {
|
||||
extern void Gia_ManDumpInterface( Gia_Man_t * p, char * pFileName );
|
||||
Gia_ManDumpInterface( p, pFileName );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( fAssign ) {
|
||||
extern void Gia_ManDumpVerilogNoInterAssign( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs, int fVerBufs, int fInter );
|
||||
Gia_ManDumpVerilogNoInterAssign( p, pFileName, vObjs, fVerBufs, fInter );
|
||||
}
|
||||
else {
|
||||
extern void Gia_ManDumpVerilogNoInter( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs, int fVerBufs, int fInter );
|
||||
Gia_ManDumpVerilogNoInter( p, pFileName, vObjs, fVerBufs, fInter );
|
||||
}
|
||||
}
|
||||
}
|
||||
void Gia_ManDumpVerilogNoInter( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs, int fVerBufs, int fInter )
|
||||
{
|
||||
Gia_Obj_t * pObj;
|
||||
Vec_Bit_t * vInvs, * vUsed;
|
||||
|
|
@ -1423,7 +1450,7 @@ void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs, int
|
|||
}
|
||||
|
||||
if ( fInter || nRegs )
|
||||
Gia_ManDumpInterface( p, pFile );
|
||||
Gia_ManDumpInterface2( p, pFile );
|
||||
//Gia_ManSetRegNum( p, 0 );
|
||||
p->nRegs = 0;
|
||||
|
||||
|
|
@ -1438,26 +1465,26 @@ void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs, int
|
|||
if ( fVerBufs )
|
||||
{
|
||||
fprintf( pFile, " (\n " );
|
||||
Gia_ManWriteNames( pFile, 'a', Gia_ManPiNum(p), NULL, 4, 4, NULL );
|
||||
Gia_ManWriteNames( pFile, 'a', Gia_ManPiNum(p), NULL, 4, 4, NULL, 0 );
|
||||
fprintf( pFile, ",\n " );
|
||||
|
||||
Gia_ManWriteNames( pFile, 'y', Gia_ManPoNum(p), NULL, 4, 4, NULL );
|
||||
Gia_ManWriteNames( pFile, 'y', Gia_ManPoNum(p), NULL, 4, 4, NULL, 0 );
|
||||
fprintf( pFile, "\n );\n\n" );
|
||||
|
||||
fprintf( pFile, " input " );
|
||||
Gia_ManWriteNames( pFile, 'a', Gia_ManPiNum(p), NULL, 8, 4, NULL );
|
||||
Gia_ManWriteNames( pFile, 'a', Gia_ManPiNum(p), NULL, 8, 4, NULL, 0 );
|
||||
fprintf( pFile, ";\n\n" );
|
||||
|
||||
fprintf( pFile, " output " );
|
||||
Gia_ManWriteNames( pFile, 'y', Gia_ManPoNum(p), NULL, 9, 4, NULL );
|
||||
Gia_ManWriteNames( pFile, 'y', Gia_ManPoNum(p), NULL, 9, 4, NULL, 0 );
|
||||
fprintf( pFile, ";\n\n" );
|
||||
|
||||
fprintf( pFile, " wire " );
|
||||
Gia_ManWriteNames( pFile, 'x', Gia_ManPiNum(p), p->vNamesIn, 8, 4, NULL );
|
||||
Gia_ManWriteNames( pFile, 'x', Gia_ManPiNum(p), p->vNamesIn, 8, 4, NULL, 0 );
|
||||
fprintf( pFile, ";\n\n" );
|
||||
|
||||
fprintf( pFile, " wire " );
|
||||
Gia_ManWriteNames( pFile, 'z', Gia_ManPoNum(p), p->vNamesOut, 9, 4, NULL );
|
||||
Gia_ManWriteNames( pFile, 'z', Gia_ManPoNum(p), p->vNamesOut, 9, 4, NULL, 0 );
|
||||
fprintf( pFile, ";\n\n" );
|
||||
|
||||
Gia_ManForEachPi( p, pObj, i )
|
||||
|
|
@ -1477,32 +1504,32 @@ void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs, int
|
|||
else
|
||||
{
|
||||
fprintf( pFile, " (\n " );
|
||||
Gia_ManWriteNames( pFile, 'x', Gia_ManPiNum(p), p->vNamesIn, 4, 4, NULL );
|
||||
Gia_ManWriteNames( pFile, 'x', Gia_ManPiNum(p), p->vNamesIn, 4, 4, NULL, 0 );
|
||||
fprintf( pFile, ",\n " );
|
||||
|
||||
Gia_ManWriteNames( pFile, 'z', Gia_ManPoNum(p), p->vNamesOut, 4, 4, NULL );
|
||||
Gia_ManWriteNames( pFile, 'z', Gia_ManPoNum(p), p->vNamesOut, 4, 4, NULL, 0 );
|
||||
fprintf( pFile, "\n );\n\n" );
|
||||
|
||||
fprintf( pFile, " input " );
|
||||
Gia_ManWriteNames( pFile, 'x', Gia_ManPiNum(p), p->vNamesIn, 8, 4, NULL );
|
||||
Gia_ManWriteNames( pFile, 'x', Gia_ManPiNum(p), p->vNamesIn, 8, 4, NULL, 0 );
|
||||
fprintf( pFile, ";\n\n" );
|
||||
|
||||
fprintf( pFile, " output " );
|
||||
Gia_ManWriteNames( pFile, 'z', Gia_ManPoNum(p), p->vNamesOut, 9, 4, NULL );
|
||||
Gia_ManWriteNames( pFile, 'z', Gia_ManPoNum(p), p->vNamesOut, 9, 4, NULL, 0 );
|
||||
fprintf( pFile, ";\n\n" );
|
||||
}
|
||||
|
||||
if ( Vec_BitCount(vUsed) )
|
||||
{
|
||||
fprintf( pFile, " wire " );
|
||||
Gia_ManWriteNames( pFile, 'n', Gia_ManObjNum(p), NULL, 7, 4, vUsed );
|
||||
Gia_ManWriteNames( pFile, 'n', Gia_ManObjNum(p), NULL, 7, 4, vUsed, 0 );
|
||||
fprintf( pFile, ";\n\n" );
|
||||
}
|
||||
|
||||
if ( Vec_BitCount(vInvs) )
|
||||
{
|
||||
fprintf( pFile, " wire " );
|
||||
Gia_ManWriteNames( pFile, 'i', Gia_ManObjNum(p), NULL, 7, 4, vInvs );
|
||||
Gia_ManWriteNames( pFile, 'i', Gia_ManObjNum(p), NULL, 7, 4, vInvs, 0 );
|
||||
fprintf( pFile, ";\n\n" );
|
||||
}
|
||||
|
||||
|
|
@ -1587,6 +1614,682 @@ void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs, int
|
|||
|
||||
Gia_ManSetRegNum( p, nRegs );
|
||||
}
|
||||
void Gia_ManDumpVerilogNoInterAssign( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs, int fVerBufs, int fInter )
|
||||
{
|
||||
Gia_Obj_t * pObj;
|
||||
Vec_Bit_t * vInvs, * vUsed;
|
||||
int nDigits = Abc_Base10Log( Gia_ManObjNum(p) );
|
||||
int nDigitsI = Abc_Base10Log( Gia_ManPiNum(p) );
|
||||
int nDigitsO = Abc_Base10Log( Gia_ManPoNum(p) );
|
||||
int i, k, iObj, nRegs = Gia_ManRegNum(p);
|
||||
FILE * pFile = fopen( pFileName, "wb" );
|
||||
if ( pFile == NULL )
|
||||
{
|
||||
printf( "Cannot open output file \"%s\".\n", pFileName );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( fInter || nRegs )
|
||||
Gia_ManDumpInterface2( p, pFile );
|
||||
//Gia_ManSetRegNum( p, 0 );
|
||||
p->nRegs = 0;
|
||||
|
||||
vInvs = Gia_ManGenUsed( p, 0 );
|
||||
vUsed = Gia_ManGenUsed( p, 1 );
|
||||
|
||||
//fprintf( pFile, "// This Verilog file is written by ABC on %s\n\n", Extra_TimeStamp() );
|
||||
|
||||
fprintf( pFile, "module " );
|
||||
Gia_ManDumpModuleName( pFile, p->pName );
|
||||
|
||||
if ( fVerBufs )
|
||||
{
|
||||
fprintf( pFile, " (\n " );
|
||||
Gia_ManWriteNames( pFile, 'a', Gia_ManPiNum(p), NULL, 4, 4, NULL, 0 );
|
||||
fprintf( pFile, ",\n " );
|
||||
|
||||
Gia_ManWriteNames( pFile, 'y', Gia_ManPoNum(p), NULL, 4, 4, NULL, 0 );
|
||||
fprintf( pFile, "\n );\n\n" );
|
||||
|
||||
fprintf( pFile, " input " );
|
||||
Gia_ManWriteNames( pFile, 'a', Gia_ManPiNum(p), NULL, 8, 4, NULL, 0 );
|
||||
fprintf( pFile, ";\n\n" );
|
||||
|
||||
fprintf( pFile, " output " );
|
||||
Gia_ManWriteNames( pFile, 'y', Gia_ManPoNum(p), NULL, 9, 4, NULL, 0 );
|
||||
fprintf( pFile, ";\n\n" );
|
||||
|
||||
fprintf( pFile, " wire " );
|
||||
Gia_ManWriteNames( pFile, 'x', Gia_ManPiNum(p), p->vNamesIn, 8, 4, NULL, 0 );
|
||||
fprintf( pFile, ";\n\n" );
|
||||
|
||||
fprintf( pFile, " wire " );
|
||||
Gia_ManWriteNames( pFile, 'z', Gia_ManPoNum(p), p->vNamesOut, 9, 4, NULL, 0 );
|
||||
fprintf( pFile, ";\n\n" );
|
||||
|
||||
Gia_ManForEachPi( p, pObj, i )
|
||||
{
|
||||
fprintf( pFile, " assign %s =", Gia_ObjGetDumpName(p->vNamesIn, 'x', i, nDigitsI) );
|
||||
fprintf( pFile, " %s;\n", Gia_ObjGetDumpName(NULL, 'a', i, nDigitsI) );
|
||||
}
|
||||
fprintf( pFile, "\n" );
|
||||
|
||||
Gia_ManForEachPo( p, pObj, i )
|
||||
{
|
||||
fprintf( pFile, " assign %s =", Gia_ObjGetDumpName(NULL, 'y', i, nDigitsO) );
|
||||
fprintf( pFile, " %s;\n", Gia_ObjGetDumpName(p->vNamesOut, 'z', i, nDigitsO) );
|
||||
}
|
||||
fprintf( pFile, "\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( pFile, " (\n " );
|
||||
Gia_ManWriteNames( pFile, 'x', Gia_ManPiNum(p), p->vNamesIn, 4, 4, NULL, 0 );
|
||||
fprintf( pFile, ",\n " );
|
||||
|
||||
Gia_ManWriteNames( pFile, 'z', Gia_ManPoNum(p), p->vNamesOut, 4, 4, NULL, 0 );
|
||||
fprintf( pFile, "\n );\n\n" );
|
||||
|
||||
fprintf( pFile, " input " );
|
||||
Gia_ManWriteNames( pFile, 'x', Gia_ManPiNum(p), p->vNamesIn, 8, 4, NULL, 0 );
|
||||
fprintf( pFile, ";\n\n" );
|
||||
|
||||
fprintf( pFile, " output " );
|
||||
Gia_ManWriteNames( pFile, 'z', Gia_ManPoNum(p), p->vNamesOut, 9, 4, NULL, 0 );
|
||||
fprintf( pFile, ";\n\n" );
|
||||
}
|
||||
|
||||
if ( Vec_BitCount(vUsed) )
|
||||
{
|
||||
fprintf( pFile, " wire " );
|
||||
Gia_ManWriteNames( pFile, 'n', Gia_ManObjNum(p), NULL, 7, 4, vUsed, 0 );
|
||||
fprintf( pFile, ";\n\n" );
|
||||
}
|
||||
|
||||
if ( Vec_BitCount(vInvs) )
|
||||
{
|
||||
fprintf( pFile, " wire " );
|
||||
Gia_ManWriteNames( pFile, 'i', Gia_ManObjNum(p), NULL, 7, 4, vInvs, 0 );
|
||||
fprintf( pFile, ";\n\n" );
|
||||
}
|
||||
|
||||
if ( vObjs )
|
||||
{
|
||||
fprintf( pFile, " wire " );
|
||||
Vec_IntForEachEntry( vObjs, iObj, i )
|
||||
fprintf( pFile, " t_%d%s", i, i==Vec_IntSize(vObjs)-1 ? "" : "," );
|
||||
fprintf( pFile, ";\n\n" );
|
||||
Vec_IntForEachEntry( vObjs, iObj, i )
|
||||
{
|
||||
fprintf( pFile, " assign %s =", Gia_ObjGetDumpName(NULL, 'n', iObj, nDigits) );
|
||||
fprintf( pFile, " t_%d;\n", i );
|
||||
}
|
||||
fprintf( pFile, "\n" );
|
||||
}
|
||||
|
||||
// input inverters
|
||||
Gia_ManForEachPi( p, pObj, i )
|
||||
{
|
||||
if ( Vec_BitEntry(vUsed, Gia_ObjId(p, pObj)) )
|
||||
{
|
||||
fprintf( pFile, " assign %s =", Gia_ObjGetDumpName(NULL, 'n', Gia_ObjId(p, pObj), nDigits) );
|
||||
fprintf( pFile, " %s;\n", Gia_ObjGetDumpName(p->vNamesIn, 'x', i, nDigitsI) );
|
||||
}
|
||||
if ( Vec_BitEntry(vInvs, Gia_ObjId(p, pObj)) )
|
||||
{
|
||||
fprintf( pFile, " assign %s =", Gia_ObjGetDumpName(NULL, 'i', Gia_ObjId(p, pObj), nDigits) );
|
||||
fprintf( pFile, " ~%s;\n", Gia_ObjGetDumpName(p->vNamesIn, 'x', i, nDigitsI) );
|
||||
}
|
||||
}
|
||||
|
||||
// internal nodes and their inverters
|
||||
fprintf( pFile, "\n" );
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
{
|
||||
int fSkip = 0;
|
||||
if ( vObjs )
|
||||
{
|
||||
Vec_IntForEachEntry( vObjs, iObj, k )
|
||||
if ( iObj == i )
|
||||
break;
|
||||
if ( k < Vec_IntSize(vObjs) )
|
||||
fSkip = 1;
|
||||
}
|
||||
if ( !fSkip )
|
||||
{
|
||||
fprintf( pFile, " assign %s =", Gia_ObjGetDumpName(NULL, 'n', i, nDigits) );
|
||||
fprintf( pFile, " %s &", Gia_ObjGetDumpName(NULL, (char)(Gia_ObjFaninC0(pObj)? 'i':'n'), Gia_ObjFaninId0(pObj, i), nDigits) );
|
||||
fprintf( pFile, " %s;\n", Gia_ObjGetDumpName(NULL, (char)(Gia_ObjFaninC1(pObj)? 'i':'n'), Gia_ObjFaninId1(pObj, i), nDigits) );
|
||||
}
|
||||
if ( Vec_BitEntry(vInvs, i) )
|
||||
{
|
||||
fprintf( pFile, " assign %s =", Gia_ObjGetDumpName(NULL, 'i', i, nDigits) );
|
||||
fprintf( pFile, " ~%s;\n", Gia_ObjGetDumpName(NULL, 'n', i, nDigits) );
|
||||
}
|
||||
}
|
||||
|
||||
// output drivers
|
||||
fprintf( pFile, "\n" );
|
||||
Gia_ManForEachPo( p, pObj, i )
|
||||
{
|
||||
fprintf( pFile, " assign %s = ", Gia_ObjGetDumpName(p->vNamesOut, 'z', i, nDigitsO) );
|
||||
if ( Gia_ObjIsConst0(Gia_ObjFanin0(pObj)) )
|
||||
fprintf( pFile, "1\'b%d;\n", Gia_ObjFaninC0(pObj) );
|
||||
else
|
||||
fprintf( pFile, "%s;\n", Gia_ObjGetDumpName(NULL, (char)(Gia_ObjFaninC0(pObj)? 'i':'n'), Gia_ObjFaninId0p(p, pObj), nDigits) );
|
||||
}
|
||||
|
||||
fprintf( pFile, "\nendmodule\n\n" );
|
||||
fclose( pFile );
|
||||
|
||||
Vec_BitFree( vInvs );
|
||||
Vec_BitFree( vUsed );
|
||||
|
||||
Gia_ManSetRegNum( p, nRegs );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManPrintOneName( FILE * pFile, char * pName, int Size )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < Size; i++ )
|
||||
fprintf( pFile, "%c", pName[i] );
|
||||
}
|
||||
int Gia_ManCountSymbs( char * pName )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; pName[i]; i++ )
|
||||
if ( pName[i] == '[' )
|
||||
break;
|
||||
return i;
|
||||
}
|
||||
int Gia_ManReadRangeNum( char * pName, int Size )
|
||||
{
|
||||
if ( pName[Size] == 0 )
|
||||
return -1;
|
||||
assert( pName[Size] == '[' );
|
||||
return atoi(pName+Size+1);
|
||||
}
|
||||
Vec_Int_t * Gia_ManCountSymbsAll( Vec_Ptr_t * vNames )
|
||||
{
|
||||
char * pNameLast = (char *)Vec_PtrEntry(vNames, 0), * pName;
|
||||
int i, nSymbsLast = Gia_ManCountSymbs(pNameLast);
|
||||
Vec_Int_t * vArray = Vec_IntAlloc( Vec_PtrSize(vNames) * 2 );
|
||||
Vec_IntPush( vArray, 0 );
|
||||
Vec_IntPush( vArray, nSymbsLast );
|
||||
Vec_PtrForEachEntryStart( char *, vNames, pName, i, 1 )
|
||||
{
|
||||
int nSymbs = Gia_ManCountSymbs(pName);
|
||||
if ( nSymbs == nSymbsLast && !strncmp(pName, pNameLast, nSymbsLast) )
|
||||
continue;
|
||||
Vec_IntPush( vArray, i );
|
||||
Vec_IntPush( vArray, nSymbs );
|
||||
pNameLast = pName;
|
||||
nSymbsLast = nSymbs;
|
||||
}
|
||||
return vArray;
|
||||
}
|
||||
void Gia_ManDumpIoList( Gia_Man_t * p, FILE * pFile, int fOuts, int fReverse )
|
||||
{
|
||||
Vec_Ptr_t * vNames = fOuts ? p->vNamesOut : p->vNamesIn;
|
||||
if ( vNames == NULL )
|
||||
fprintf( pFile, "_%c_", fOuts ? 'o' : 'i' );
|
||||
else
|
||||
{
|
||||
Vec_Int_t * vArray = Gia_ManCountSymbsAll( vNames );
|
||||
int iName, Size, i;
|
||||
Vec_IntForEachEntryDouble( vArray, iName, Size, i )
|
||||
{
|
||||
if ( fReverse )
|
||||
{
|
||||
iName = Vec_IntEntry(vArray, Vec_IntSize(vArray)-2-i);
|
||||
Size = Vec_IntEntry(vArray, Vec_IntSize(vArray)-1-i);
|
||||
}
|
||||
if ( i ) fprintf( pFile, ", " );
|
||||
Gia_ManPrintOneName( pFile, (char *)Vec_PtrEntry(vNames, iName), Size );
|
||||
}
|
||||
Vec_IntFree( vArray );
|
||||
}
|
||||
}
|
||||
void Gia_ManDumpIoRanges( Gia_Man_t * p, FILE * pFile, int fOuts )
|
||||
{
|
||||
Vec_Ptr_t * vNames = fOuts ? p->vNamesOut : p->vNamesIn;
|
||||
if ( p->vNamesOut == NULL )
|
||||
fprintf( pFile, "%s [%d:0] _%c_;\n", fOuts ? "output" : "input", fOuts ? Gia_ManPoNum(p)-1 : Gia_ManPiNum(p)-1, fOuts ? 'o' : 'i' );
|
||||
else
|
||||
{
|
||||
Vec_Int_t * vArray = Gia_ManCountSymbsAll( vNames );
|
||||
int iName, Size, i;
|
||||
Vec_IntForEachEntryDouble( vArray, iName, Size, i )
|
||||
{
|
||||
int iNameNext = Vec_IntSize(vArray) > i+2 ? Vec_IntEntry(vArray, i+2) : Vec_PtrSize(vNames);
|
||||
char * pName = (char *)Vec_PtrEntry(vNames, iName);
|
||||
char * pNameLast = (char *)Vec_PtrEntry(vNames, iNameNext-1);
|
||||
assert( !strncmp(pName, pNameLast, Size) );
|
||||
int NumBeg = Gia_ManReadRangeNum( pName, Size );
|
||||
int NumEnd = Gia_ManReadRangeNum( pNameLast, Size );
|
||||
fprintf( pFile, " %s ", fOuts ? "output" : "input" );
|
||||
if ( NumBeg != -1 && iName < iNameNext-1 )
|
||||
fprintf( pFile, "[%d:%d] ", NumEnd, NumBeg );
|
||||
Gia_ManPrintOneName( pFile, pName, Size );
|
||||
fprintf( pFile, ";\n" );
|
||||
}
|
||||
Vec_IntFree( vArray );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManDumpInterface( Gia_Man_t * p, char * pFileName )
|
||||
{
|
||||
Gia_Obj_t * pObj;
|
||||
Vec_Bit_t * vInvs, * vUsed;
|
||||
int nDigits = Abc_Base10Log( Gia_ManObjNum(p) );
|
||||
int nDigitsI = Abc_Base10Log( Gia_ManPiNum(p) );
|
||||
int nDigitsO = Abc_Base10Log( Gia_ManPoNum(p) );
|
||||
int i;
|
||||
|
||||
FILE * pFile = fopen( pFileName, "wb" );
|
||||
if ( pFile == NULL )
|
||||
{
|
||||
printf( "Cannot open output file \"%s\".\n", pFileName );
|
||||
return;
|
||||
}
|
||||
|
||||
vInvs = Gia_ManGenUsed( p, 0 );
|
||||
vUsed = Gia_ManGenUsed( p, 1 );
|
||||
|
||||
fprintf( pFile, "module " );
|
||||
Gia_ManDumpModuleName( pFile, p->pName );
|
||||
fprintf( pFile, "_wrapper" );
|
||||
fprintf( pFile, " ( " );
|
||||
Gia_ManDumpIoList( p, pFile, 0, 0 );
|
||||
fprintf( pFile, ", " );
|
||||
Gia_ManDumpIoList( p, pFile, 1, 0 );
|
||||
fprintf( pFile, " );\n\n" );
|
||||
Gia_ManDumpIoRanges( p, pFile, 0 );
|
||||
Gia_ManDumpIoRanges( p, pFile, 1 );
|
||||
fprintf( pFile, "\n" );
|
||||
|
||||
fprintf( pFile, " wire " );
|
||||
Gia_ManWriteNames( pFile, 'x', Gia_ManPiNum(p), p->vNamesIn, 8, 4, NULL, 0 );
|
||||
fprintf( pFile, ";\n\n" );
|
||||
|
||||
fprintf( pFile, " wire " );
|
||||
Gia_ManWriteNames( pFile, 'z', Gia_ManPoNum(p), p->vNamesOut, 9, 4, NULL, 0 );
|
||||
fprintf( pFile, ";\n\n" );
|
||||
|
||||
fprintf( pFile, " assign { " );
|
||||
Gia_ManWriteNames( pFile, 'x', Gia_ManCiNum(p), p->vNamesIn, 8, 4, NULL, 1 );
|
||||
fprintf( pFile, " } = { " );
|
||||
Gia_ManDumpIoList( p, pFile, 0, 1 );
|
||||
fprintf( pFile, " };\n\n" );
|
||||
|
||||
fprintf( pFile, " assign { " );
|
||||
Gia_ManDumpIoList( p, pFile, 1, 1 );
|
||||
fprintf( pFile, " } = { " );
|
||||
Gia_ManWriteNames( pFile, 'z', Gia_ManCoNum(p), p->vNamesOut, 9, 4, NULL, 1 );
|
||||
fprintf( pFile, " };\n\n" );
|
||||
|
||||
if ( Vec_BitCount(vUsed) )
|
||||
{
|
||||
fprintf( pFile, " wire " );
|
||||
Gia_ManWriteNames( pFile, 'n', Gia_ManObjNum(p), NULL, 7, 4, vUsed, 0 );
|
||||
fprintf( pFile, ";\n\n" );
|
||||
}
|
||||
|
||||
if ( Vec_BitCount(vInvs) )
|
||||
{
|
||||
fprintf( pFile, " wire " );
|
||||
Gia_ManWriteNames( pFile, 'i', Gia_ManObjNum(p), NULL, 7, 4, vInvs, 0 );
|
||||
fprintf( pFile, ";\n\n" );
|
||||
}
|
||||
|
||||
// input inverters
|
||||
Gia_ManForEachCi( p, pObj, i )
|
||||
{
|
||||
if ( Vec_BitEntry(vUsed, Gia_ObjId(p, pObj)) )
|
||||
{
|
||||
fprintf( pFile, " buf ( %s,", Gia_ObjGetDumpName(NULL, 'n', Gia_ObjId(p, pObj), nDigits) );
|
||||
fprintf( pFile, " %s );\n", Gia_ObjGetDumpName(p->vNamesIn, 'x', i, nDigitsI) );
|
||||
}
|
||||
if ( Vec_BitEntry(vInvs, Gia_ObjId(p, pObj)) )
|
||||
{
|
||||
fprintf( pFile, " not ( %s,", Gia_ObjGetDumpName(NULL, 'i', Gia_ObjId(p, pObj), nDigits) );
|
||||
fprintf( pFile, " %s );\n", Gia_ObjGetDumpName(p->vNamesIn, 'x', i, nDigitsI) );
|
||||
}
|
||||
}
|
||||
|
||||
// internal nodes and their inverters
|
||||
fprintf( pFile, "\n" );
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
{
|
||||
fprintf( pFile, " and ( %s,", Gia_ObjGetDumpName(NULL, 'n', i, nDigits) );
|
||||
fprintf( pFile, " %s,", Gia_ObjGetDumpName(NULL, (char)(Gia_ObjFaninC0(pObj)? 'i':'n'), Gia_ObjFaninId0(pObj, i), nDigits) );
|
||||
fprintf( pFile, " %s );\n", Gia_ObjGetDumpName(NULL, (char)(Gia_ObjFaninC1(pObj)? 'i':'n'), Gia_ObjFaninId1(pObj, i), nDigits) );
|
||||
if ( Vec_BitEntry(vInvs, i) )
|
||||
{
|
||||
fprintf( pFile, " not ( %s,", Gia_ObjGetDumpName(NULL, 'i', i, nDigits) );
|
||||
fprintf( pFile, " %s );\n", Gia_ObjGetDumpName(NULL, 'n', i, nDigits) );
|
||||
}
|
||||
}
|
||||
|
||||
// output drivers
|
||||
fprintf( pFile, "\n" );
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
{
|
||||
fprintf( pFile, " buf ( %s, ", Gia_ObjGetDumpName(p->vNamesOut, 'z', i, nDigitsO) );
|
||||
if ( Gia_ObjIsConst0(Gia_ObjFanin0(pObj)) )
|
||||
fprintf( pFile, "1\'b%d );\n", Gia_ObjFaninC0(pObj) );
|
||||
else
|
||||
fprintf( pFile, "%s );\n", Gia_ObjGetDumpName(NULL, (char)(Gia_ObjFaninC0(pObj)? 'i':'n'), Gia_ObjFaninId0p(p, pObj), nDigits) );
|
||||
}
|
||||
|
||||
fprintf( pFile, "\nendmodule\n\n" );
|
||||
fclose( pFile );
|
||||
|
||||
Vec_BitFree( vInvs );
|
||||
Vec_BitFree( vUsed );
|
||||
}
|
||||
void Gia_ManDumpInterfaceAssign( Gia_Man_t * p, char * pFileName )
|
||||
{
|
||||
Gia_Obj_t * pObj;
|
||||
Vec_Bit_t * vInvs, * vUsed;
|
||||
int nDigits = Abc_Base10Log( Gia_ManObjNum(p) );
|
||||
int nDigitsI = Abc_Base10Log( Gia_ManPiNum(p) );
|
||||
int nDigitsO = Abc_Base10Log( Gia_ManPoNum(p) );
|
||||
int i;
|
||||
|
||||
FILE * pFile = fopen( pFileName, "wb" );
|
||||
if ( pFile == NULL )
|
||||
{
|
||||
printf( "Cannot open output file \"%s\".\n", pFileName );
|
||||
return;
|
||||
}
|
||||
|
||||
vInvs = Gia_ManGenUsed( p, 0 );
|
||||
vUsed = Gia_ManGenUsed( p, 1 );
|
||||
|
||||
fprintf( pFile, "module " );
|
||||
Gia_ManDumpModuleName( pFile, p->pName );
|
||||
fprintf( pFile, "_wrapper" );
|
||||
fprintf( pFile, " ( " );
|
||||
Gia_ManDumpIoList( p, pFile, 0, 0 );
|
||||
fprintf( pFile, ", " );
|
||||
Gia_ManDumpIoList( p, pFile, 1, 0 );
|
||||
fprintf( pFile, " );\n\n" );
|
||||
Gia_ManDumpIoRanges( p, pFile, 0 );
|
||||
Gia_ManDumpIoRanges( p, pFile, 1 );
|
||||
fprintf( pFile, "\n" );
|
||||
|
||||
fprintf( pFile, " wire " );
|
||||
Gia_ManWriteNames( pFile, 'x', Gia_ManPiNum(p), p->vNamesIn, 8, 4, NULL, 0 );
|
||||
fprintf( pFile, ";\n\n" );
|
||||
|
||||
fprintf( pFile, " wire " );
|
||||
Gia_ManWriteNames( pFile, 'z', Gia_ManPoNum(p), p->vNamesOut, 9, 4, NULL, 0 );
|
||||
fprintf( pFile, ";\n\n" );
|
||||
|
||||
fprintf( pFile, " assign { " );
|
||||
Gia_ManWriteNames( pFile, 'x', Gia_ManCiNum(p), p->vNamesIn, 8, 4, NULL, 1 );
|
||||
fprintf( pFile, " } = { " );
|
||||
Gia_ManDumpIoList( p, pFile, 0, 1 );
|
||||
fprintf( pFile, " };\n\n" );
|
||||
|
||||
fprintf( pFile, " assign { " );
|
||||
Gia_ManDumpIoList( p, pFile, 1, 1 );
|
||||
fprintf( pFile, " } = { " );
|
||||
Gia_ManWriteNames( pFile, 'z', Gia_ManCoNum(p), p->vNamesOut, 9, 4, NULL, 1 );
|
||||
fprintf( pFile, " };\n\n" );
|
||||
|
||||
if ( Vec_BitCount(vUsed) )
|
||||
{
|
||||
fprintf( pFile, " wire " );
|
||||
Gia_ManWriteNames( pFile, 'n', Gia_ManObjNum(p), NULL, 7, 4, vUsed, 0 );
|
||||
fprintf( pFile, ";\n\n" );
|
||||
}
|
||||
|
||||
if ( Vec_BitCount(vInvs) )
|
||||
{
|
||||
fprintf( pFile, " wire " );
|
||||
Gia_ManWriteNames( pFile, 'i', Gia_ManObjNum(p), NULL, 7, 4, vInvs, 0 );
|
||||
fprintf( pFile, ";\n\n" );
|
||||
}
|
||||
|
||||
// input inverters
|
||||
Gia_ManForEachCi( p, pObj, i )
|
||||
{
|
||||
if ( Vec_BitEntry(vUsed, Gia_ObjId(p, pObj)) )
|
||||
{
|
||||
fprintf( pFile, " assign %s =", Gia_ObjGetDumpName(NULL, 'n', Gia_ObjId(p, pObj), nDigits) );
|
||||
fprintf( pFile, " %s;\n", Gia_ObjGetDumpName(p->vNamesIn, 'x', i, nDigitsI) );
|
||||
}
|
||||
if ( Vec_BitEntry(vInvs, Gia_ObjId(p, pObj)) )
|
||||
{
|
||||
fprintf( pFile, " assign %s =", Gia_ObjGetDumpName(NULL, 'i', Gia_ObjId(p, pObj), nDigits) );
|
||||
fprintf( pFile, " ~%s;\n", Gia_ObjGetDumpName(p->vNamesIn, 'x', i, nDigitsI) );
|
||||
}
|
||||
}
|
||||
|
||||
// internal nodes and their inverters
|
||||
fprintf( pFile, "\n" );
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
{
|
||||
fprintf( pFile, " assign %s =", Gia_ObjGetDumpName(NULL, 'n', i, nDigits) );
|
||||
fprintf( pFile, " %s &", Gia_ObjGetDumpName(NULL, (char)(Gia_ObjFaninC0(pObj)? 'i':'n'), Gia_ObjFaninId0(pObj, i), nDigits) );
|
||||
fprintf( pFile, " %s;\n", Gia_ObjGetDumpName(NULL, (char)(Gia_ObjFaninC1(pObj)? 'i':'n'), Gia_ObjFaninId1(pObj, i), nDigits) );
|
||||
if ( Vec_BitEntry(vInvs, i) )
|
||||
{
|
||||
fprintf( pFile, " assign %s =", Gia_ObjGetDumpName(NULL, 'i', i, nDigits) );
|
||||
fprintf( pFile, " ~%s;\n", Gia_ObjGetDumpName(NULL, 'n', i, nDigits) );
|
||||
}
|
||||
}
|
||||
|
||||
// output drivers
|
||||
fprintf( pFile, "\n" );
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
{
|
||||
fprintf( pFile, " assign %s = ", Gia_ObjGetDumpName(p->vNamesOut, 'z', i, nDigitsO) );
|
||||
if ( Gia_ObjIsConst0(Gia_ObjFanin0(pObj)) )
|
||||
fprintf( pFile, "1\'b%d;\n", Gia_ObjFaninC0(pObj) );
|
||||
else
|
||||
fprintf( pFile, "%s;\n", Gia_ObjGetDumpName(NULL, (char)(Gia_ObjFaninC0(pObj)? 'i':'n'), Gia_ObjFaninId0p(p, pObj), nDigits) );
|
||||
}
|
||||
|
||||
fprintf( pFile, "\nendmodule\n\n" );
|
||||
fclose( pFile );
|
||||
|
||||
Vec_BitFree( vInvs );
|
||||
Vec_BitFree( vUsed );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManDumpNandLit( FILE * pFile, int nIns, int Lit, int nDigits )
|
||||
{
|
||||
if ( Lit == 0 )
|
||||
fprintf( pFile, "1\'b0" );
|
||||
else if ( Lit == 1 )
|
||||
fprintf( pFile, "1\'b1" );
|
||||
else if ( Abc_Lit2Var(Lit) <= nIns )
|
||||
fprintf( pFile, "%cn%0*d", (char)(Abc_LitIsCompl(Lit)? '~':' '), nDigits, Abc_Lit2Var(Lit) );
|
||||
else
|
||||
fprintf( pFile, "%cn%0*d", (char)(Abc_LitIsCompl(Lit)? ' ':'~'), nDigits, Abc_Lit2Var(Lit) );
|
||||
}
|
||||
void Gia_ManDumpVerilogNand( Gia_Man_t * p, char * pFileName )
|
||||
{
|
||||
Gia_Obj_t * pObj; int i, nPis = Gia_ManPiNum(p);
|
||||
int nDigits = Abc_Base10Log( Gia_ManObjNum(p) );
|
||||
int nDigitsI = Abc_Base10Log( Gia_ManPiNum(p) );
|
||||
int nDigitsO = Abc_Base10Log( Gia_ManPoNum(p) );
|
||||
FILE * pFile = fopen( pFileName, "wb" );
|
||||
if ( pFile == NULL )
|
||||
{
|
||||
printf( "Cannot open output file \"%s\".\n", pFileName );
|
||||
return;
|
||||
}
|
||||
assert( Gia_ManRegNum(p) == 0 );
|
||||
fprintf( pFile, "module " );
|
||||
Gia_ManDumpModuleName( pFile, p->pName );
|
||||
fprintf( pFile, "_wrapper" );
|
||||
fprintf( pFile, " ( " );
|
||||
if ( p->vNamesIn ) {
|
||||
Gia_ManDumpIoList( p, pFile, 0, 0 );
|
||||
fprintf( pFile, ", " );
|
||||
Gia_ManDumpIoList( p, pFile, 1, 0 );
|
||||
fprintf( pFile, " );\n\n" );
|
||||
Gia_ManDumpIoRanges( p, pFile, 0 );
|
||||
Gia_ManDumpIoRanges( p, pFile, 1 );
|
||||
}
|
||||
else {
|
||||
fprintf( pFile, "\n " );
|
||||
Gia_ManForEachPi( p, pObj, i )
|
||||
fprintf( pFile, "%s, ", Gia_ObjGetDumpName(NULL, 'x', i, nDigitsI) );
|
||||
fprintf( pFile, "\n " );
|
||||
Gia_ManForEachPo( p, pObj, i )
|
||||
fprintf( pFile, "%s%s ", Gia_ObjGetDumpName(NULL, 'z', i, nDigitsO), i < Gia_ManPoNum(p)-1 ? ",":"" );
|
||||
fprintf( pFile, "\n);\n\n" );
|
||||
fprintf( pFile, " input" );
|
||||
Gia_ManForEachPi( p, pObj, i )
|
||||
fprintf( pFile, " %s%s", Gia_ObjGetDumpName(NULL, 'x', i, nDigitsI), i < Gia_ManPiNum(p)-1 ? ",":"" );
|
||||
fprintf( pFile, ";\n" );
|
||||
fprintf( pFile, " output" );
|
||||
Gia_ManForEachPo( p, pObj, i )
|
||||
fprintf( pFile, " %s%s", Gia_ObjGetDumpName(NULL, 'z', i, nDigitsO), i < Gia_ManPoNum(p)-1 ? ",":"" );
|
||||
fprintf( pFile, ";\n" );
|
||||
}
|
||||
fprintf( pFile, "\n" );
|
||||
Gia_ManForEachPi( p, pObj, i )
|
||||
fprintf( pFile, " wire n%0*d = %s;\n", nDigits, i+1, p->vNamesIn ? (char *)Vec_PtrEntry(p->vNamesIn, i) : Gia_ObjGetDumpName(p->vNamesIn, 'x', i, nDigitsI) );
|
||||
fprintf( pFile, "\n" );
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
{
|
||||
fprintf( pFile, " wire n%0*d = ~(", nDigits, i );
|
||||
Gia_ManDumpNandLit( pFile, nPis, Gia_ObjFaninLit0(pObj, i), nDigits );
|
||||
fprintf( pFile, " & " );
|
||||
Gia_ManDumpNandLit( pFile, nPis, Gia_ObjFaninLit1(pObj, i), nDigits );
|
||||
fprintf( pFile, ");\n" );
|
||||
}
|
||||
fprintf( pFile, "\n" );
|
||||
Gia_ManForEachPo( p, pObj, i )
|
||||
{
|
||||
fprintf( pFile, " assign %s = ", p->vNamesOut ? (char *)Vec_PtrEntry(p->vNamesOut, i) : Gia_ObjGetDumpName(p->vNamesOut, 'z', i, nDigitsO) );
|
||||
Gia_ManDumpNandLit( pFile, nPis, Gia_ObjFaninLit0p(p, pObj), nDigits );
|
||||
fprintf( pFile, ";\n" );
|
||||
}
|
||||
fprintf( pFile, "\nendmodule\n\n" );
|
||||
fclose( pFile );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Generate hierarchical design.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_FreeMany( Gia_Man_t ** pGias, int nGias )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < nGias; i++ )
|
||||
Gia_ManStopP( &pGias[i] );
|
||||
}
|
||||
void Gia_GenSandwich( char ** pFNames, int nFNames, char * pFileName )
|
||||
{
|
||||
FILE * pFile = NULL;
|
||||
Gia_Man_t * pGias[16] = {0};
|
||||
int i, k;
|
||||
assert( nFNames <= 16 );
|
||||
for ( i = 0; i < nFNames; i++ )
|
||||
{
|
||||
FILE * pFile = fopen( pFNames[i], "rb" );
|
||||
if ( pFile == NULL ) {
|
||||
printf( "Cannot open input file \"%s\".\n", pFNames[i] );
|
||||
Gia_FreeMany( pGias, nFNames );
|
||||
return;
|
||||
}
|
||||
fclose( pFile );
|
||||
pGias[i] = Gia_AigerRead( pFNames[i], 0, 0, 0 );
|
||||
if ( pGias[i] == NULL ) {
|
||||
printf( "Failed to read an AIG from file \"%s\".\n", pFNames[i] );
|
||||
Gia_FreeMany( pGias, nFNames );
|
||||
return;
|
||||
}
|
||||
}
|
||||
for ( i = 0; i < nFNames-1; i++ )
|
||||
if ( Gia_ManPoNum(pGias[i]) < Gia_ManPiNum(pGias[i+1]) ) {
|
||||
printf( "AIG in file \"%s\" has fewer outputs than inputs of AIG in file \"%s\".\n", pFNames[i], pFNames[i+1] );
|
||||
Gia_FreeMany( pGias, nFNames );
|
||||
return;
|
||||
}
|
||||
pFile = fopen( pFileName, "wb" );
|
||||
if ( pFile == NULL )
|
||||
{
|
||||
printf( "Cannot open output file \"%s\".\n", pFileName );
|
||||
Gia_FreeMany( pGias, nFNames );
|
||||
return;
|
||||
}
|
||||
fprintf( pFile, "\n" );
|
||||
for ( i = 0; i < nFNames; i++ )
|
||||
fprintf( pFile, "`include \"%s\"\n", Extra_FileNameGenericAppend(pGias[i]->pSpec, ".v") );
|
||||
fprintf( pFile, "\n" );
|
||||
fprintf( pFile, "module sandwich ( in, out );\n" );
|
||||
fprintf( pFile, " input [%3d:0] in;\n", Gia_ManPiNum(pGias[0])-1 );
|
||||
fprintf( pFile, " output [%3d:0] out;\n", Gia_ManPoNum(pGias[nFNames-1])-1 );
|
||||
fprintf( pFile, " wire [%3d:0] tmp0 = in;\n", Gia_ManPiNum(pGias[0])-1 );
|
||||
for ( i = 0; i < nFNames; i++ ) {
|
||||
fprintf( pFile, " wire [%3d:0] tmp%d; ", Gia_ManPoNum(pGias[i])-1, i+1 );
|
||||
Gia_ManDumpModuleName( pFile, pGias[i]->pName );
|
||||
fprintf( pFile, "_wrapper" );
|
||||
for ( k = strlen(pGias[i]->pName); k < 24; k++ )
|
||||
fprintf( pFile, " " );
|
||||
fprintf( pFile, " i%d ( tmp%d, tmp%d );\n", i+1, i, i+1 );
|
||||
}
|
||||
fprintf( pFile, " assign out = tmp%d;\n", nFNames );
|
||||
fprintf( pFile, "endmodule\n" );
|
||||
fclose( pFile );
|
||||
for ( i = 0; i < nFNames; i++ ) {
|
||||
Vec_PtrFreeFree( pGias[i]->vNamesIn ); pGias[i]->vNamesIn = NULL;
|
||||
Vec_PtrFreeFree( pGias[i]->vNamesOut ); pGias[i]->vNamesOut = NULL;
|
||||
Gia_ManDumpVerilog( pGias[i], Extra_FileNameGenericAppend(pGias[i]->pSpec, ".v"), NULL, 0, 0, 1, 0, 0 );
|
||||
printf( "Dumped Verilog file \"%s\"\n", Extra_FileNameGenericAppend(pGias[i]->pSpec, ".v") );
|
||||
}
|
||||
Gia_FreeMany( pGias, nFNames );
|
||||
printf( "Dumped hierarchical design into file \"%s\"\n", pFileName );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
|
|
|
|||
|
|
@ -1228,6 +1228,127 @@ void Gia_MiniAigGenerateFromFile()
|
|||
Mini_AigStop( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Str_t * Gia_ManRetimableF( Gia_Man_t * p, int * pRst, int * pSet, int * pEna )
|
||||
{
|
||||
Vec_Str_t * vStops = Vec_StrStart( Gia_ManObjNum(p) );
|
||||
Vec_Int_t * vTemps = Vec_IntStartFull( 3*Gia_ManObjNum(p) );
|
||||
Gia_Obj_t * pObj, * pObjRi, * pObjRo; int i;
|
||||
char * pStops = Vec_StrArray(vStops);
|
||||
assert( Gia_ManRegNum(p) > 0 );
|
||||
Gia_ManForEachRiRo( p, pObjRi, pObjRo, i ) {
|
||||
Vec_IntWriteEntry( vTemps, 3*Gia_ObjId(p, pObjRo) + 0, pRst[i] );
|
||||
Vec_IntWriteEntry( vTemps, 3*Gia_ObjId(p, pObjRo) + 1, pSet[i] );
|
||||
Vec_IntWriteEntry( vTemps, 3*Gia_ObjId(p, pObjRo) + 2, pEna[i] );
|
||||
}
|
||||
Gia_ManForEachAnd( p, pObj, i ) {
|
||||
int * pFan0 = Vec_IntEntryP( vTemps, 3*Gia_ObjFaninId0(pObj, i) );
|
||||
int * pFan1 = Vec_IntEntryP( vTemps, 3*Gia_ObjFaninId1(pObj, i) );
|
||||
int * pNode = Vec_IntEntryP( vTemps, 3*i );
|
||||
pStops[i] = (char)1;
|
||||
if ( pFan0[0] != -1 && pFan0[0] == pFan1[0] && pFan0[1] == pFan1[1] && pFan0[2] == pFan1[2] )
|
||||
pStops[i] = (char)0, pNode[0] = pFan0[0], pNode[1] = pFan0[1], pNode[2] = pFan0[2];
|
||||
}
|
||||
Vec_IntFree( vTemps );
|
||||
return vStops;
|
||||
}
|
||||
Vec_Str_t * Gia_ManRetimableB( Gia_Man_t * p, int * pRst, int * pSet, int * pEna )
|
||||
{
|
||||
Vec_Str_t * vStops = Vec_StrStart( Gia_ManObjNum(p) );
|
||||
Vec_Int_t * vTemps = Vec_IntStartFull( 3*Gia_ManObjNum(p) );
|
||||
Gia_Obj_t * pObj, * pObjRi, * pObjRo; int i, n, iFanout;
|
||||
char * pStops = Vec_StrArray(vStops);
|
||||
assert( Gia_ManRegNum(p) > 0 );
|
||||
Gia_ManForEachRiRo( p, pObjRi, pObjRo, i ) {
|
||||
Vec_IntWriteEntry( vTemps, 3*Gia_ObjId(p, pObjRi) + 0, pRst[i] );
|
||||
Vec_IntWriteEntry( vTemps, 3*Gia_ObjId(p, pObjRi) + 1, pSet[i] );
|
||||
Vec_IntWriteEntry( vTemps, 3*Gia_ObjId(p, pObjRi) + 2, pEna[i] );
|
||||
}
|
||||
Gia_ManStaticFanoutStart( p );
|
||||
Gia_ManForEachAndReverse( p, pObj, i ) {
|
||||
int * pFan0 = Vec_IntEntryP( vTemps, 3*Gia_ObjFanoutId(p, i, 0) );
|
||||
int * pNode = Vec_IntEntryP( vTemps, 3*i );
|
||||
pStops[i] = (char)1;
|
||||
if ( pFan0[0] == -1 )
|
||||
continue;
|
||||
Gia_ObjForEachFanoutStaticId( p, i, iFanout, n ) {
|
||||
int * pFan1 = Vec_IntEntryP( vTemps, 3*iFanout );
|
||||
if ( pFan1[0] == -1 || pFan0[0] != pFan1[0] || pFan0[1] != pFan1[1] || pFan0[2] != pFan1[2] )
|
||||
break;
|
||||
}
|
||||
if ( n < Gia_ObjFanoutNum(p, pObj) )
|
||||
continue;
|
||||
pStops[i] = (char)0, pNode[0] = pFan0[0], pNode[1] = pFan0[1], pNode[2] = pFan0[2];
|
||||
}
|
||||
Gia_ManStaticFanoutStop( p );
|
||||
Vec_IntFree( vTemps );
|
||||
Gia_ManForEachRiRo( p, pObjRi, pObjRo, i ) {
|
||||
if ( Gia_ObjIsAnd(Gia_ManObj(p, Abc_Lit2Var(pRst[i]))) ) pStops[Abc_Lit2Var(pRst[i])] = 1;
|
||||
if ( Gia_ObjIsAnd(Gia_ManObj(p, Abc_Lit2Var(pSet[i]))) ) pStops[Abc_Lit2Var(pSet[i])] = 1;
|
||||
if ( Gia_ObjIsAnd(Gia_ManObj(p, Abc_Lit2Var(pEna[i]))) ) pStops[Abc_Lit2Var(pEna[i])] = 1;
|
||||
}
|
||||
return vStops;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_FrameRemapLits( int * pLits, int nLits, Vec_Int_t * vMap )
|
||||
{
|
||||
for ( int i = 0; i < nLits; i++ )
|
||||
pLits[i] = Abc_Lit2LitL( Vec_IntArray(vMap), pLits[i] );
|
||||
}
|
||||
void Abc_FrameSetRetimingData( Abc_Frame_t * pAbc, int * pRst, int * pSet, int * pEna, int nRegs )
|
||||
{
|
||||
Gia_Man_t * pGia;
|
||||
int * pRstNew = ABC_CALLOC( int, nRegs );
|
||||
int * pSetNew = ABC_CALLOC( int, nRegs );
|
||||
int * pEnaNew = ABC_CALLOC( int, nRegs );
|
||||
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" );
|
||||
else {
|
||||
assert( nRegs == Gia_ManRegNum(pGia) );
|
||||
memmove( pRstNew, pRst, sizeof(int)*nRegs );
|
||||
memmove( pSetNew, pSet, sizeof(int)*nRegs );
|
||||
memmove( pEnaNew, pEna, sizeof(int)*nRegs );
|
||||
}
|
||||
if ( pAbc->vCopyMiniAig == NULL )
|
||||
printf( "Mapping of MiniAig nodes is not available.\n" );
|
||||
else {
|
||||
Abc_FrameRemapLits( pRstNew, nRegs, pAbc->vCopyMiniAig );
|
||||
Abc_FrameRemapLits( pSetNew, nRegs, pAbc->vCopyMiniAig );
|
||||
Abc_FrameRemapLits( pEnaNew, nRegs, pAbc->vCopyMiniAig );
|
||||
}
|
||||
assert( pGia->vStopsF == NULL );
|
||||
assert( pGia->vStopsB == NULL );
|
||||
pGia->vStopsF = Gia_ManRetimableF( pGia, pRstNew, pSetNew, pEnaNew );
|
||||
pGia->vStopsB = Gia_ManRetimableB( pGia, pRstNew, pSetNew, pEnaNew );
|
||||
ABC_FREE( pRstNew );
|
||||
ABC_FREE( pSetNew );
|
||||
ABC_FREE( pEnaNew );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -490,13 +490,16 @@ int Gia_ManSifCheckIter( Gia_Man_t * p, Vec_Int_t * vCuts, Vec_Int_t * vTimes, i
|
|||
}
|
||||
int Gia_ManSifCheckPeriod( Gia_Man_t * p, Vec_Int_t * vCuts, Vec_Int_t * vTimes, int nLutSize, int Period, int * pIters )
|
||||
{
|
||||
Gia_Obj_t * pObj; int i, Id, nSize = nLutSize+1;
|
||||
Gia_Obj_t * pObj; int i, Id, Stop, nSize = nLutSize+1;
|
||||
assert( Gia_ManRegNum(p) > 0 );
|
||||
Gia_ManForEachCiId( p, Id, i )
|
||||
Vec_IntWriteEntry( vCuts, Id*nSize, 1 );
|
||||
Gia_ManForEachCiId( p, Id, i )
|
||||
Vec_IntWriteEntry( vCuts, Id*nSize+1, Id << 8 );
|
||||
Vec_IntFill( vTimes, Gia_ManObjNum(p), -Period );
|
||||
if ( p->vStopsF )
|
||||
Vec_StrForEachEntry( p->vStopsF, Stop, i )
|
||||
if ( Stop ) Vec_IntWriteEntry( vTimes, i, 0 );
|
||||
Vec_IntWriteEntry( vTimes, 0, 0 );
|
||||
Gia_ManForEachPi( p, pObj, i )
|
||||
Vec_IntWriteEntry( vTimes, Gia_ObjId(p, pObj), 0 );
|
||||
|
|
@ -510,6 +513,10 @@ int Gia_ManSifCheckPeriod( Gia_Man_t * p, Vec_Int_t * vCuts, Vec_Int_t * vTimes,
|
|||
Gia_ManForEachObj( p, pObj, i )
|
||||
if ( Vec_IntEntry(vTimes, Gia_ObjId(p, pObj)) > 2*Period )
|
||||
return 0;
|
||||
if ( p->vStopsB )
|
||||
Vec_StrForEachEntry( p->vStopsB, Stop, i )
|
||||
if ( Stop && Vec_IntEntry(vTimes, i) > Period )
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,32 +60,35 @@ ABC_NAMESPACE_IMPL_START
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Gia_Man_t * Gia_StochProcessOne( Gia_Man_t * p, char * pScript, int Rand, int TimeSecs )
|
||||
Gia_Man_t * Gia_StochProcessSingle( Gia_Man_t * p, char * pScript, int Rand, int TimeSecs )
|
||||
{
|
||||
Gia_Man_t * pNew;
|
||||
char FileName[100], Command[1000];
|
||||
sprintf( FileName, "%06x.aig", Rand );
|
||||
Gia_AigerWrite( p, FileName, 0, 0, 0 );
|
||||
sprintf( Command, "./abc -q \"&read %s; %s; &write %s\"", FileName, pScript, FileName );
|
||||
#if defined(__wasm)
|
||||
if ( 1 )
|
||||
#else
|
||||
if ( system( (char *)Command ) )
|
||||
#endif
|
||||
Gia_Man_t * pTemp, * pNew = Gia_ManDup( p );
|
||||
Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), Gia_ManDup(p) );
|
||||
if ( Abc_FrameIsBatchMode() )
|
||||
{
|
||||
fprintf( stderr, "The following command has returned non-zero exit status:\n" );
|
||||
fprintf( stderr, "\"%s\"\n", (char *)Command );
|
||||
fprintf( stderr, "Sorry for the inconvenience.\n" );
|
||||
fflush( stdout );
|
||||
unlink( FileName );
|
||||
return Gia_ManDup(p);
|
||||
}
|
||||
pNew = Gia_AigerRead( FileName, 0, 0, 0 );
|
||||
unlink( FileName );
|
||||
if ( pNew && Gia_ManAndNum(pNew) < Gia_ManAndNum(p) )
|
||||
return pNew;
|
||||
Gia_ManStopP( &pNew );
|
||||
return Gia_ManDup(p);
|
||||
if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), pScript) )
|
||||
{
|
||||
Abc_Print( 1, "Something did not work out with the command \"%s\".\n", pScript );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Abc_FrameSetBatchMode( 1 );
|
||||
if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), pScript) )
|
||||
{
|
||||
Abc_Print( 1, "Something did not work out with the command \"%s\".\n", pScript );
|
||||
return NULL;
|
||||
}
|
||||
Abc_FrameSetBatchMode( 0 );
|
||||
}
|
||||
pTemp = Abc_FrameReadGia(Abc_FrameGetGlobalFrame());
|
||||
if ( Gia_ManAndNum(pNew) > Gia_ManAndNum(pTemp) )
|
||||
{
|
||||
Gia_ManStop( pNew );
|
||||
pNew = Gia_ManDup( pTemp );
|
||||
}
|
||||
return pNew;
|
||||
}
|
||||
void Gia_StochProcessArray( Vec_Ptr_t * vGias, char * pScript, int TimeSecs, int fVerbose )
|
||||
{
|
||||
|
|
@ -96,7 +99,7 @@ void Gia_StochProcessArray( Vec_Ptr_t * vGias, char * pScript, int TimeSecs, int
|
|||
Vec_IntPush( vRands, Abc_Random(0) % 0x1000000 );
|
||||
Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i )
|
||||
{
|
||||
pNew = Gia_StochProcessOne( pGia, pScript, Vec_IntEntry(vRands, i), TimeSecs );
|
||||
pNew = Gia_StochProcessSingle( pGia, pScript, Vec_IntEntry(vRands, i), TimeSecs );
|
||||
Gia_ManStop( pGia );
|
||||
Vec_PtrWriteEntry( vGias, i, pNew );
|
||||
}
|
||||
|
|
@ -135,6 +138,30 @@ typedef struct Gia_StochThData_t_
|
|||
int fWorking;
|
||||
} Gia_StochThData_t;
|
||||
|
||||
Gia_Man_t * Gia_StochProcessOne( Gia_Man_t * p, char * pScript, int Rand, int TimeSecs )
|
||||
{
|
||||
Gia_Man_t * pNew;
|
||||
char FileName[100], Command[1000];
|
||||
sprintf( FileName, "%06x.aig", Rand );
|
||||
Gia_AigerWrite( p, FileName, 0, 0, 0 );
|
||||
sprintf( Command, "./abc -q \"&read %s; %s; &write %s\"", FileName, pScript, FileName );
|
||||
if ( system( (char *)Command ) )
|
||||
{
|
||||
fprintf( stderr, "The following command has returned non-zero exit status:\n" );
|
||||
fprintf( stderr, "\"%s\"\n", (char *)Command );
|
||||
fprintf( stderr, "Sorry for the inconvenience.\n" );
|
||||
fflush( stdout );
|
||||
unlink( FileName );
|
||||
return Gia_ManDup(p);
|
||||
}
|
||||
pNew = Gia_AigerRead( FileName, 0, 0, 0 );
|
||||
unlink( FileName );
|
||||
if ( pNew && Gia_ManAndNum(pNew) < Gia_ManAndNum(p) )
|
||||
return pNew;
|
||||
Gia_ManStopP( &pNew );
|
||||
return Gia_ManDup(p);
|
||||
}
|
||||
|
||||
void * Gia_StochWorkerThread( void * pArg )
|
||||
{
|
||||
Gia_StochThData_t * pThData = (Gia_StochThData_t *)pArg;
|
||||
|
|
|
|||
|
|
@ -572,6 +572,10 @@ int Supp_FindNextDiv( Supp_Man_t * p, int Pair )
|
|||
iDiv1 = iDiv1 == -1 ? ABC_INFINITY : iDiv1;
|
||||
iDiv2 = iDiv2 == -1 ? ABC_INFINITY : iDiv2;
|
||||
iDiv = Abc_MinInt( iDiv1, iDiv2 );
|
||||
// return -1 if the pair cannot be distinguished by any divisor
|
||||
// in this case the original resub problem has no solution
|
||||
if ( iDiv == ABC_INFINITY )
|
||||
return -1;
|
||||
assert( iDiv >= 0 && iDiv < Vec_IntSize(p->vCands) );
|
||||
return iDiv;
|
||||
}
|
||||
|
|
@ -582,6 +586,8 @@ int Supp_ManRandomSolution( Supp_Man_t * p, int iSet, int fVerbose )
|
|||
{
|
||||
int Pair = Supp_ComputePair( p, iSet );
|
||||
int iDiv = Supp_FindNextDiv( p, Pair );
|
||||
if ( iDiv == -1 )
|
||||
return -1;
|
||||
iSet = Supp_ManSubsetAdd( p, iSet, iDiv, fVerbose );
|
||||
if ( Supp_SetFuncNum(p, iSet) > 0 )
|
||||
Vec_IntPush( p->vTempSets, iSet );
|
||||
|
|
@ -883,6 +889,10 @@ Vec_Int_t * Supp_ManCompute( Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t *
|
|||
{
|
||||
Supp_ManAddPatternsFunc( p, i );
|
||||
iSet = Supp_ManRandomSolution( p, 0, fVeryVerbose );
|
||||
if ( iSet == -1 ) {
|
||||
Supp_ManDelete( p );
|
||||
return NULL;
|
||||
}
|
||||
for ( r = 0; r < p->nRounds; r++ )
|
||||
{
|
||||
if ( fVeryVerbose )
|
||||
|
|
@ -898,6 +908,10 @@ Vec_Int_t * Supp_ManCompute( Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t *
|
|||
iBest = iSet;
|
||||
}
|
||||
iSet = Supp_ManReconstruct( p, fVeryVerbose );
|
||||
if ( iSet == -1 ) {
|
||||
Supp_ManDelete( p );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if ( fVeryVerbose )
|
||||
printf( "Matrix size %d.\n", Vec_PtrSize(p->vMatrix) );
|
||||
|
|
|
|||
|
|
@ -3161,6 +3161,119 @@ void Gia_ManPrintArray( Gia_Man_t * p )
|
|||
printf( "};\n" );
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_GetMValue( int i, int nIns, int Mint, unsigned Truth )
|
||||
{
|
||||
assert( i >= 0 && i < 16 );
|
||||
if ( i < nIns )
|
||||
return (Mint >> i) & 1;
|
||||
if ( i == nIns )
|
||||
{
|
||||
if ( Mint < (1 << nIns) )
|
||||
return (Truth >> Mint) & 1;
|
||||
else
|
||||
return ((Truth >> (Mint-(1 << nIns))) & 1) == 0;
|
||||
}
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
void Gia_ManTestProblem()
|
||||
{
|
||||
unsigned Truth = 0xFE;
|
||||
int i, j, k, c, nIns = 3, nAux = 3;
|
||||
int nTotal = nIns + 1 + nAux;
|
||||
int nPairs = nTotal * (nTotal - 1) / 2;
|
||||
int nMints = (1 << (nIns+1));
|
||||
int M[64][100] = {{0}};
|
||||
float Value[64] = {0};
|
||||
float Solution[100] = {0};
|
||||
assert( nMints <= 64 );
|
||||
assert( nPairs <= 100 );
|
||||
// 7 nodes: 3 inputs + 1 output + 3 aux
|
||||
// 7*6/2 = 21 pairs
|
||||
// 16 minterms
|
||||
for ( k = 0; k < nMints; k++ )
|
||||
{
|
||||
for ( i = c = 0; i < nTotal; i++ )
|
||||
for ( j = i+1; j < nTotal; j++ )
|
||||
{
|
||||
int iVal = Gia_GetMValue( i, nIns, k, Truth );
|
||||
int jVal = Gia_GetMValue( j, nIns, k, Truth );
|
||||
M[k][c++] = iVal == jVal ? 1 : -1;
|
||||
}
|
||||
Value[k] = k < (1 << nIns) ? -1 : 1;
|
||||
assert( c == nPairs );
|
||||
}
|
||||
|
||||
for ( k = 0; k < nMints; k++ )
|
||||
{
|
||||
for ( c = 0; c < nPairs; c++ )
|
||||
printf( "%2d ", M[k][c] );
|
||||
printf( "%3f\n", Value[k] );
|
||||
}
|
||||
|
||||
// solve
|
||||
float Delta = 0.02;
|
||||
for ( i = 0; i < 100; i++ )
|
||||
{
|
||||
float Error = 0;
|
||||
for ( k = 0; k < nMints; k++ )
|
||||
Error += Value[k] > 0 ? Value[k] : -Value[k];
|
||||
printf( "Round %3d : Error = %5f ", i, Error );
|
||||
for ( c = 0; c < nPairs; c++ )
|
||||
printf( "%2f ", Solution[c] );
|
||||
printf( "\n" );
|
||||
|
||||
//if ( Error < 1 )
|
||||
// Delta /= 10;
|
||||
|
||||
for ( c = 0; c < nPairs; c++ )
|
||||
{
|
||||
int Count = 0;
|
||||
for ( k = 0; k < nMints; k++ )
|
||||
if ( (M[k][c] > 0 && Value[k] > 0) || (M[k][c] < 0 && Value[k] < 0) )
|
||||
Count++;
|
||||
else
|
||||
Count--;
|
||||
if ( Count == 0 )
|
||||
continue;
|
||||
printf( "Count = %3d ", Count );
|
||||
if ( Count > 0 )
|
||||
{
|
||||
printf( "Increasing %d by %f\n", c, Delta );
|
||||
Solution[c] += Delta;
|
||||
for ( k = 0; k < nMints; k++ )
|
||||
if ( M[k][c] > 0 )
|
||||
Value[k] -= Delta;
|
||||
else
|
||||
Value[k] -= Delta;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "Reducing %d by %f\n", c, Delta );
|
||||
Solution[c] -= Delta;
|
||||
for ( k = 0; k < nMints; k++ )
|
||||
if ( M[k][c] > 0 )
|
||||
Value[k] += Delta;
|
||||
else
|
||||
Value[k] += Delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -109,4 +109,5 @@ SRC += src/aig/gia/giaAig.c \
|
|||
src/aig/gia/giaTsim.c \
|
||||
src/aig/gia/giaTtopt.cpp \
|
||||
src/aig/gia/giaUnate.c \
|
||||
src/aig/gia/giaUtil.c
|
||||
src/aig/gia/giaUtil.c \
|
||||
src/aig/gia/giaBound.c
|
||||
|
|
@ -841,7 +841,7 @@ extern ABC_DLL void Abc_NtkPrintFanioNew( FILE * pFile, Abc_Ntk_t
|
|||
extern ABC_DLL void Abc_NodePrintFanio( FILE * pFile, Abc_Obj_t * pNode );
|
||||
extern ABC_DLL void Abc_NtkPrintFactor( FILE * pFile, Abc_Ntk_t * pNtk, int fUseRealNames );
|
||||
extern ABC_DLL void Abc_NodePrintFactor( FILE * pFile, Abc_Obj_t * pNode, int fUseRealNames );
|
||||
extern ABC_DLL void Abc_NtkPrintLevel( FILE * pFile, Abc_Ntk_t * pNtk, int fProfile, int fListNodes, int fVerbose );
|
||||
extern ABC_DLL void Abc_NtkPrintLevel( FILE * pFile, Abc_Ntk_t * pNtk, int fProfile, int fListNodes, int fOutputs, int fVerbose );
|
||||
extern ABC_DLL void Abc_NodePrintLevel( FILE * pFile, Abc_Obj_t * pNode );
|
||||
extern ABC_DLL void Abc_NtkPrintSkews( FILE * pFile, Abc_Ntk_t * pNtk, int fPrintAll );
|
||||
extern ABC_DLL void Abc_ObjPrint( FILE * pFile, Abc_Obj_t * pObj );
|
||||
|
|
|
|||
1116
src/base/abci/abc.c
1116
src/base/abci/abc.c
File diff suppressed because it is too large
Load Diff
|
|
@ -116,7 +116,7 @@ Abc_Ntk_t * Abc_NtkIf( Abc_Ntk_t * pNtk, If_Par_t * pPars )
|
|||
pPars->pTimesReq = Abc_NtkGetCoRequiredFloats(pNtk);
|
||||
|
||||
// update timing info to reflect logic level
|
||||
if ( (pPars->fDelayOpt || pPars->fDsdBalance || pPars->fUserRecLib || pPars->fUserSesLib) && pNtk->pManTime )
|
||||
if ( (pPars->fDelayOpt || pPars->fDsdBalance || pPars->fUserRecLib || pPars->fUserSesLib || pPars->fUserLutDec || pPars->fUserLut2D ) && pNtk->pManTime )
|
||||
{
|
||||
int c;
|
||||
if ( pNtk->AndGateDelay == 0.0 )
|
||||
|
|
@ -426,6 +426,127 @@ Hop_Obj_t * Abc_NodeBuildFromMini( Hop_Man_t * pMan, If_Man_t * p, If_Cut_t * pC
|
|||
return Abc_NodeBuildFromMiniInt( pMan, p->vArray, If_CutLeaveNum(pCut) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
Synopsis [Implements decomposed LUT-structure of the cut.]
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
SeeAlso []
|
||||
***********************************************************************/
|
||||
void Abc_DecRecordToHop( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Cut_t * pCutBest, If_Obj_t * pIfObj, Vec_Int_t * vCover, Abc_Obj_t * pNodeTop )
|
||||
{
|
||||
extern Hop_Obj_t * Kit_TruthToHop( Hop_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory );
|
||||
assert( !pIfMan->pPars->fUseTtPerm );
|
||||
|
||||
// get the truth table
|
||||
word * pTruth = If_CutTruthW(pIfMan, pCutBest);
|
||||
int v;
|
||||
If_Obj_t * pIfLeaf;
|
||||
|
||||
if ( pCutBest->nLeaves <= pIfMan->pPars->nLutDecSize )
|
||||
{
|
||||
/* add fanins */
|
||||
If_CutForEachLeaf( pIfMan, pCutBest, pIfLeaf, v )
|
||||
Abc_ObjAddFanin( pNodeTop, (Abc_Obj_t *)If_ObjCopy( pIfLeaf ) );
|
||||
|
||||
pNodeTop->Level = Abc_ObjLevelNew( pNodeTop );
|
||||
|
||||
pNodeTop->pData = Kit_TruthToHop( (Hop_Man_t *)pNtkNew->pManFunc, (unsigned *)pTruth, If_CutLeaveNum(pCutBest), vCover );
|
||||
return;
|
||||
}
|
||||
|
||||
// get the delay profile
|
||||
unsigned delayProfile = pCutBest->decDelay;
|
||||
|
||||
// perform LUT-decomposition and return the LUT-structure
|
||||
unsigned char decompArray[92];
|
||||
int val;
|
||||
if ( pIfMan->pPars->fUserLutDec )
|
||||
{
|
||||
val = acd_decompose( pTruth, pCutBest->nLeaves, pIfMan->pPars->nLutDecSize, &(delayProfile), decompArray );
|
||||
}
|
||||
else
|
||||
{
|
||||
val = acd2_decompose( pTruth, pCutBest->nLeaves, pIfMan->pPars->nLutDecSize, &(delayProfile), decompArray );
|
||||
}
|
||||
assert( val == 0 );
|
||||
|
||||
// convert the LUT-structure into a set of logic nodes in Abc_Ntk_t
|
||||
unsigned char bytes_check = decompArray[0];
|
||||
assert( bytes_check <= 92 );
|
||||
|
||||
int byte_p = 2;
|
||||
unsigned char i, j, k, num_fanins, num_words, num_bytes;
|
||||
int level, fanin;
|
||||
word *tt;
|
||||
Abc_Obj_t *pNewNodes[5];
|
||||
|
||||
/* create intermediate LUTs */
|
||||
assert( decompArray[1] <= 6 );
|
||||
Abc_Obj_t * pFanin;
|
||||
for ( i = 0; i < decompArray[1]; ++i )
|
||||
{
|
||||
if ( i < decompArray[1] - 1 )
|
||||
{
|
||||
pNewNodes[i] = Abc_NtkCreateNode( pNtkNew );
|
||||
}
|
||||
else
|
||||
{
|
||||
pNewNodes[i] = pNodeTop;
|
||||
}
|
||||
num_fanins = decompArray[byte_p++];
|
||||
level = 0;
|
||||
for ( j = 0; j < num_fanins; ++j )
|
||||
{
|
||||
fanin = (int)decompArray[byte_p++];
|
||||
if ( fanin < If_CutLeaveNum(pCutBest) )
|
||||
{
|
||||
pFanin = (Abc_Obj_t *)If_ObjCopy( If_CutLeaf(pIfMan, pCutBest, fanin) );
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( fanin - If_CutLeaveNum(pCutBest) < i );
|
||||
pFanin = pNewNodes[fanin - If_CutLeaveNum(pCutBest)];
|
||||
}
|
||||
Abc_ObjAddFanin( pNewNodes[i], pFanin );
|
||||
level = Abc_MaxInt( level, Abc_ObjLevel(pFanin) );
|
||||
}
|
||||
|
||||
pNewNodes[i]->Level = level + (int)(Abc_ObjFaninNum(pNewNodes[i]) > 0);
|
||||
|
||||
/* extract the truth table */
|
||||
tt = pIfMan->puTempW;
|
||||
num_words = ( num_fanins <= 6 ) ? 1 : ( 1 << ( num_fanins - 6 ) );
|
||||
num_bytes = ( num_fanins <= 3 ) ? 1 : ( 1 << ( Abc_MinInt( (int)num_fanins, 6 ) - 3 ) );
|
||||
for ( j = 0; j < num_words; ++j )
|
||||
{
|
||||
tt[j] = 0;
|
||||
for ( k = 0; k < num_bytes; ++k )
|
||||
{
|
||||
tt[j] |= ( (word)(decompArray[byte_p++]) ) << ( k << 3 );
|
||||
}
|
||||
}
|
||||
|
||||
/* extend truth table if size < 5 */
|
||||
assert( num_fanins != 1 );
|
||||
if ( num_fanins == 2 )
|
||||
{
|
||||
tt[0] |= tt[0] << 4;
|
||||
}
|
||||
while ( num_bytes < 4 )
|
||||
{
|
||||
tt[0] |= tt[0] << ( num_bytes << 3 );
|
||||
num_bytes <<= 1;
|
||||
}
|
||||
|
||||
/* add node data */
|
||||
pNewNodes[i]->pData = Kit_TruthToHop( (Hop_Man_t *)pNtkNew->pManFunc, (unsigned *)tt, (int) num_fanins, vCover );
|
||||
}
|
||||
|
||||
/* check correct read */
|
||||
assert( byte_p == decompArray[0] );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derive one node after FPGA mapping.]
|
||||
|
|
@ -464,13 +585,19 @@ Abc_Obj_t * Abc_NodeFromIf_rec( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Obj_t
|
|||
pNodeNew = Abc_NtkCreateNode( pNtkNew );
|
||||
// if ( pIfMan->pPars->pLutLib && pIfMan->pPars->pLutLib->fVarPinDelays )
|
||||
if ( !pIfMan->pPars->fDelayOpt && !pIfMan->pPars->fDelayOptLut && !pIfMan->pPars->fDsdBalance && !pIfMan->pPars->fUseTtPerm &&
|
||||
!pIfMan->pPars->pLutStruct && !pIfMan->pPars->fUserRecLib && !pIfMan->pPars->fUserSesLib && !pIfMan->pPars->nGateSize )
|
||||
!pIfMan->pPars->pLutStruct && !pIfMan->pPars->fUserLutDec && !pIfMan->pPars->fUserLut2D && !pIfMan->pPars->fUserRecLib &&
|
||||
!pIfMan->pPars->fUserSesLib && !pIfMan->pPars->nGateSize )
|
||||
If_CutRotatePins( pIfMan, pCutBest );
|
||||
if ( pIfMan->pPars->fUseCnfs || pIfMan->pPars->fUseMv )
|
||||
{
|
||||
If_CutForEachLeafReverse( pIfMan, pCutBest, pIfLeaf, i )
|
||||
Abc_ObjAddFanin( pNodeNew, Abc_NodeFromIf_rec(pNtkNew, pIfMan, pIfLeaf, vCover) );
|
||||
}
|
||||
else if ( pIfMan->pPars->fUserLutDec || pIfMan->pPars->fUserLut2D )
|
||||
{
|
||||
If_CutForEachLeaf( pIfMan, pCutBest, pIfLeaf, i )
|
||||
Abc_NodeFromIf_rec(pNtkNew, pIfMan, pIfLeaf, vCover);
|
||||
}
|
||||
else
|
||||
{
|
||||
If_CutForEachLeaf( pIfMan, pCutBest, pIfLeaf, i )
|
||||
|
|
@ -524,6 +651,11 @@ Abc_Obj_t * Abc_NodeFromIf_rec( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Obj_t
|
|||
extern Hop_Obj_t * Abc_RecToHop3( Hop_Man_t * pMan, If_Man_t * pIfMan, If_Cut_t * pCut, If_Obj_t * pIfObj );
|
||||
pNodeNew->pData = Abc_RecToHop3( (Hop_Man_t *)pNtkNew->pManFunc, pIfMan, pCutBest, pIfObj );
|
||||
}
|
||||
else if ( pIfMan->pPars->fUserLutDec || pIfMan->pPars->fUserLut2D )
|
||||
{
|
||||
extern void Abc_DecRecordToHop( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Cut_t * pCut, If_Obj_t * pIfObj, Vec_Int_t * vMemory, Abc_Obj_t * pNodeTop );
|
||||
Abc_DecRecordToHop( pNtkNew, pIfMan, pCutBest, pIfObj, vCover, pNodeNew );
|
||||
}
|
||||
else
|
||||
{
|
||||
extern Hop_Obj_t * Kit_TruthToHop( Hop_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory );
|
||||
|
|
|
|||
|
|
@ -789,6 +789,7 @@ Abc_Ntk_t * Abc_NtkFrames( Abc_Ntk_t * pNtk, int nFrames, int fInitial, int fVer
|
|||
pNtkFrames->pName = Extra_UtilStrsav(Buffer);
|
||||
// map the constant nodes
|
||||
Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkFrames);
|
||||
|
||||
// create new latches (or their initial values) and remember them in the new latches
|
||||
if ( !fInitial )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -237,7 +237,7 @@ Abc_Obj_t * Abc_NodeBddToMuxes_rec( DdManager * dd, DdNode * bFunc, Abc_Ntk_t *
|
|||
{
|
||||
Abc_Obj_t * pNodeNew, * pNodeNew0, * pNodeNew1, * pNodeNewC;
|
||||
assert( !Cudd_IsComplement(bFunc) );
|
||||
assert( b1 == a1 );
|
||||
//assert( b1 == a1 );
|
||||
if ( bFunc == a1 )
|
||||
return Abc_NtkCreateNodeConst1(pNtkNew);
|
||||
if ( bFunc == a0 )
|
||||
|
|
|
|||
|
|
@ -198,7 +198,7 @@ Rwr_ManAddTimeCuts( pManRwr, Abc_Clock() - clk );
|
|||
pManRwr->nNodesBeg = Abc_NtkNodeNum(pNtk);
|
||||
nNodes = Abc_NtkObjNumMax(pNtk);
|
||||
|
||||
printf("nNodes: %d\n", nNodes);
|
||||
//printf("nNodes: %d\n", nNodes);
|
||||
if ( pGain_rw ) *pGain_rw = Vec_IntAlloc(1);
|
||||
|
||||
pProgress = Extra_ProgressBarStart( stdout, nNodes );
|
||||
|
|
@ -489,7 +489,7 @@ int Abc_NtkRefactor3( Abc_Ntk_t * pNtk, Vec_Int_t **pGain_ref, int nNodeSizeMax,
|
|||
Abc_NtkStartReverseLevels( pNtk, 0 );
|
||||
pManRef->nNodesBeg = Abc_NtkNodeNum(pNtk);
|
||||
nNodes = Abc_NtkObjNumMax(pNtk);
|
||||
printf("nNodes: %d\n", nNodes);
|
||||
//printf("nNodes: %d\n", nNodes);
|
||||
if (pGain_ref) *pGain_ref = Vec_IntAlloc(1);
|
||||
|
||||
pProgress = Extra_ProgressBarStart( stdout, nNodes );
|
||||
|
|
@ -605,7 +605,7 @@ int Abc_NtkResubstitute3( Abc_Ntk_t * pNtk, Vec_Int_t **pGain_res, int nCutMax,
|
|||
// resynthesize each node once
|
||||
pManRes->nNodesBeg = Abc_NtkNodeNum(pNtk);
|
||||
nNodes = Abc_NtkObjNumMax(pNtk);
|
||||
printf("nNodes: %d\n", nNodes);
|
||||
//printf("nNodes: %d\n", nNodes);
|
||||
if (pGain_res) *pGain_res = Vec_IntAlloc(1);
|
||||
|
||||
pProgress = Extra_ProgressBarStart( stdout, nNodes );
|
||||
|
|
@ -2732,7 +2732,7 @@ Rwr_ManAddTimeCuts( pManRwr, Abc_Clock() - clk );
|
|||
pManRef->nNodesBeg = Abc_NtkNodeNum(pNtk);
|
||||
|
||||
nNodes = Abc_NtkObjNumMax(pNtk);
|
||||
printf("nNodes: %d\n", nNodes);
|
||||
//printf("nNodes: %d\n", nNodes);
|
||||
if (pGain_res) *pGain_res = Vec_IntAlloc(1);
|
||||
if (pGain_ref) *pGain_ref = Vec_IntAlloc(1);
|
||||
if (pGain_rwr) *pGain_rwr = Vec_IntAlloc(1);
|
||||
|
|
@ -5318,6 +5318,319 @@ s_ResubTime = Abc_Clock() - clkStart;
|
|||
return 1;
|
||||
}
|
||||
|
||||
// orchestration with sudo random decision list
|
||||
int Abc_NtkOrchRand( Abc_Ntk_t * pNtk, Vec_Int_t **pGain_rwr, Vec_Int_t **pGain_res,Vec_Int_t **pGain_ref, Vec_Int_t **DecisionMask, char * DecisionFile, int Rand_Seed, int fUseZeros_rwr, int fUseZeros_ref, int fPlaceEnable, int nCutMax, int nStepsMax, int nLevelsOdc, int fUpdateLevel, int fVerbose, int fVeryVerbose, int nNodeSizeMax, int nConeSizeMax, int fUseDcs )
|
||||
{
|
||||
extern int Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain );
|
||||
ProgressBar * pProgress;
|
||||
// For resub
|
||||
Abc_ManRes_t * pManRes;
|
||||
Abc_ManCut_t * pManCutRes;
|
||||
Odc_Man_t * pManOdc = NULL;
|
||||
Dec_Graph_t * pFFormRes;
|
||||
Vec_Ptr_t * vLeaves;
|
||||
// For rewrite
|
||||
Cut_Man_t * pManCutRwr;
|
||||
Rwr_Man_t * pManRwr;
|
||||
Dec_Graph_t * pGraph;
|
||||
// For refactor
|
||||
Abc_ManRef_t * pManRef;
|
||||
Abc_ManCut_t * pManCutRef;
|
||||
Dec_Graph_t * pFFormRef;
|
||||
Vec_Ptr_t * vFanins;
|
||||
|
||||
Abc_Obj_t * pNode;
|
||||
FILE *fpt;
|
||||
abctime clk, clkStart = Abc_Clock();
|
||||
int i, nNodes, nNodes_after, nGain, fCompl;
|
||||
int RetValue = 1;
|
||||
int ops_rwr = 0;
|
||||
int ops_res = 0;
|
||||
int ops_ref = 0;
|
||||
int ops_null = 0;
|
||||
int Valid_Len = 0;
|
||||
//Vec_Int_t *Valid_Ops;
|
||||
|
||||
//clock_t begin= clock();
|
||||
assert( Abc_NtkIsStrash(pNtk) );
|
||||
|
||||
// cleanup the AIG
|
||||
Abc_AigCleanup((Abc_Aig_t *)pNtk->pManFunc);
|
||||
|
||||
// start the managers resub
|
||||
pManCutRes = Abc_NtkManCutStart( nCutMax, 100000, 100000, 100000 );
|
||||
pManRes = Abc_ManResubStart( nCutMax, ABC_RS_DIV1_MAX );
|
||||
if ( nLevelsOdc > 0 )
|
||||
pManOdc = Abc_NtkDontCareAlloc( nCutMax, nLevelsOdc, fVerbose, fVeryVerbose );
|
||||
// start the managers refactor
|
||||
pManCutRef = Abc_NtkManCutStart( nNodeSizeMax, nConeSizeMax, 2, 1000 );
|
||||
pManRef = Abc_NtkManRefStart_1( nNodeSizeMax, nConeSizeMax, fUseDcs, fVerbose );
|
||||
pManRef->vLeaves = Abc_NtkManCutReadCutLarge( pManCutRef );
|
||||
// start the managers rewrite
|
||||
pManRwr = Rwr_ManStart( 0 );
|
||||
if ( pManRwr == NULL )
|
||||
return 0;
|
||||
|
||||
// compute the reverse levels if level update is requested
|
||||
if ( fUpdateLevel )
|
||||
Abc_NtkStartReverseLevels( pNtk, 0 );
|
||||
|
||||
// 'Resub only'
|
||||
|
||||
if ( Abc_NtkLatchNum(pNtk) ) {
|
||||
Abc_NtkForEachLatch(pNtk, pNode, i)
|
||||
pNode->pNext = (Abc_Obj_t *)pNode->pData;
|
||||
}
|
||||
|
||||
// cut manager for rewrite
|
||||
clk = Abc_Clock();
|
||||
pManCutRwr = Abc_NtkStartCutManForRewrite( pNtk );
|
||||
Rwr_ManAddTimeCuts( pManRwr, Abc_Clock() - clk );
|
||||
pNtk->pManCut = pManCutRwr;
|
||||
|
||||
if ( fVeryVerbose )
|
||||
Rwr_ScoresClean( pManRwr );
|
||||
|
||||
// resynthesize each node once
|
||||
// resub
|
||||
pManRes->nNodesBeg = Abc_NtkNodeNum(pNtk);
|
||||
// rewrite
|
||||
pManRwr->nNodesBeg = Abc_NtkNodeNum(pNtk);
|
||||
// refactor
|
||||
pManRef->nNodesBeg = Abc_NtkNodeNum(pNtk);
|
||||
|
||||
//clock_t resyn_end=clock();
|
||||
//double resyn_time_spent = (double)(resyn_end-begin)/CLOCKS_PER_SEC;
|
||||
//printf("time %f\n", resyn_time_spent);
|
||||
nNodes = Abc_NtkObjNumMax(pNtk);
|
||||
//printf("nNodes: %d\n", nNodes);
|
||||
//for(int i=0; i < nNodes; i++){printf("mask check: %d\n", (*DecisionMask)->pArray[i]);}
|
||||
//printf("mask size:%d", (**DecisionMask).nSize);
|
||||
if (pGain_res) *pGain_res = Vec_IntAlloc(1);
|
||||
if (pGain_ref) *pGain_ref = Vec_IntAlloc(1);
|
||||
if (pGain_rwr) *pGain_rwr = Vec_IntAlloc(1);
|
||||
Vec_Int_t *Valid_Ops = Vec_IntAlloc(1);
|
||||
|
||||
pProgress = Extra_ProgressBarStart( stdout, nNodes );
|
||||
fpt = fopen(DecisionFile, "w");
|
||||
|
||||
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||
{
|
||||
//printf("Ochestration id: %d\n", pNode->Id);
|
||||
int iterNode = pNode->Id;
|
||||
Extra_ProgressBarUpdate( pProgress, i, NULL );
|
||||
// skip the constant node
|
||||
// if ( Abc_NodeIsConst(pNode) )
|
||||
// continue;
|
||||
// stop if all nodes have been tried once
|
||||
if ( i >= nNodes )
|
||||
break;
|
||||
// skip persistant nodes
|
||||
if ( Abc_NodeIsPersistant(pNode) )
|
||||
{
|
||||
//fprintf(fpt, "%d, %s, %d\n", pNode->Id, "None" , -99);
|
||||
Vec_IntPush((*pGain_res), -99);
|
||||
Vec_IntPush((*pGain_ref), -99);
|
||||
Vec_IntPush((*pGain_rwr), -99);
|
||||
continue;
|
||||
}
|
||||
// skip the nodes with many fanouts
|
||||
if ( Abc_ObjFanoutNum(pNode) > 1000 )
|
||||
{
|
||||
//fprintf(fpt, "%d, %s, %d\n", pNode->Id,"None", -99);
|
||||
Vec_IntPush((*pGain_res), -99);
|
||||
Vec_IntPush((*pGain_ref), -99);
|
||||
Vec_IntPush((*pGain_rwr), -99);
|
||||
continue;
|
||||
}
|
||||
clk = Abc_Clock();
|
||||
|
||||
// Generate random operation
|
||||
// check transformability of all three operations
|
||||
Vec_IntPush( (Valid_Ops), -1);
|
||||
nGain = Rwr_NodeRewrite( pManRwr, pManCutRwr, pNode, fUpdateLevel, fUseZeros_rwr, fPlaceEnable );
|
||||
Vec_IntPush( (*pGain_rwr), nGain);
|
||||
if (nGain > 0 || (nGain == 0 && fUseZeros_rwr))
|
||||
{
|
||||
Vec_IntPush( (Valid_Ops), 0);
|
||||
}
|
||||
vLeaves = Abc_NodeFindCut( pManCutRes, pNode, 0 );
|
||||
pManRes->timeCut += Abc_Clock() - clk;
|
||||
if ( pManOdc )
|
||||
{
|
||||
clk = Abc_Clock();
|
||||
Abc_NtkDontCareClear( pManOdc );
|
||||
Abc_NtkDontCareCompute( pManOdc, pNode, vLeaves, pManRes->pCareSet );
|
||||
pManRes->timeTruth += Abc_Clock() - clk;
|
||||
}
|
||||
clk = Abc_Clock();
|
||||
pFFormRes = Abc_ManResubEval( pManRes, pNode, vLeaves, nStepsMax, fUpdateLevel, fVerbose );
|
||||
pManRes->timeRes += Abc_Clock() - clk;
|
||||
Vec_IntPush((*pGain_res), pManRes->nLastGain);
|
||||
if (pManRes->nLastGain > 0)
|
||||
{
|
||||
if ( pFFormRes != NULL ){
|
||||
Vec_IntPush( (Valid_Ops), 1);
|
||||
}
|
||||
}
|
||||
|
||||
vFanins = Abc_NodeFindCut( pManCutRef, pNode, fUseDcs );
|
||||
pManRef->timeCut += Abc_Clock() - clk;
|
||||
clk = Abc_Clock();
|
||||
pFFormRef = Abc_NodeRefactor_1( pManRef, pNode, vFanins, fUpdateLevel, fUseZeros_ref, fUseDcs, fVerbose );
|
||||
pManRef->timeRes += Abc_Clock() - clk;
|
||||
|
||||
Vec_IntPush((*pGain_ref), pManRef->nLastGain);
|
||||
if (pManRef->nLastGain > 0 || (pManRef->nLastGain ==0 && fUseZeros_ref))
|
||||
{
|
||||
if ( pFFormRef != NULL ){
|
||||
Vec_IntPush( (Valid_Ops), 2);
|
||||
}
|
||||
}
|
||||
Valid_Len = (Valid_Ops)->nSize;
|
||||
//printf("The length of valid operations: %d\n", Valid_Len);
|
||||
|
||||
//Pick a random operations from valid ones
|
||||
if (Rand_Seed == -1)
|
||||
{
|
||||
srand(time(NULL));
|
||||
}
|
||||
else
|
||||
{
|
||||
srand(Rand_Seed);
|
||||
}
|
||||
|
||||
int r = rand() % Valid_Len;
|
||||
|
||||
if ((Valid_Ops)->pArray[r] == -1){
|
||||
(*DecisionMask)->pArray[iterNode] = -1;
|
||||
ops_null++;
|
||||
Vec_IntZero(Valid_Ops); // reset updates
|
||||
continue;
|
||||
}
|
||||
else if ((Valid_Ops->pArray[r]) == 0){
|
||||
// apply rewrite
|
||||
pGraph = (Dec_Graph_t *)Rwr_ManReadDecs(pManRwr);
|
||||
fCompl = Rwr_ManReadCompl(pManRwr);
|
||||
if ( fPlaceEnable )
|
||||
Abc_AigUpdateReset( (Abc_Aig_t *)pNtk->pManFunc );
|
||||
if ( fCompl ) Dec_GraphComplement( pGraph );
|
||||
clk = Abc_Clock();
|
||||
Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain );
|
||||
Rwr_ManAddTimeUpdate( pManRwr, Abc_Clock() - clk );
|
||||
if ( fCompl ) Dec_GraphComplement( pGraph );
|
||||
(*DecisionMask)->pArray[iterNode] = 0;
|
||||
ops_rwr++;
|
||||
Vec_IntZero(Valid_Ops); // reset updates
|
||||
continue;
|
||||
}
|
||||
else if ((Valid_Ops->pArray[r] == 1)){
|
||||
// apply res
|
||||
pManRes->nTotalGain += pManRes->nLastGain;
|
||||
clk = Abc_Clock();
|
||||
Dec_GraphUpdateNetwork( pNode, pFFormRes, fUpdateLevel, pManRes->nLastGain );
|
||||
pManRes->timeNtk += Abc_Clock() - clk;
|
||||
Dec_GraphFree( pFFormRes );
|
||||
(*DecisionMask)->pArray[iterNode] = 1;
|
||||
ops_res++;
|
||||
Vec_IntZero(Valid_Ops); // reset updates
|
||||
continue;
|
||||
}
|
||||
else if ((Valid_Ops->pArray[r] == 2)){
|
||||
clk = Abc_Clock();
|
||||
if ( !Dec_GraphUpdateNetwork( pNode, pFFormRef, fUpdateLevel, pManRef->nLastGain ) )
|
||||
{
|
||||
Dec_GraphFree( pFFormRef );
|
||||
RetValue = -1;
|
||||
break;
|
||||
}
|
||||
pManRef->timeNtk += Abc_Clock() - clk;
|
||||
Dec_GraphFree( pFFormRef );
|
||||
(*DecisionMask)->pArray[iterNode] = 2;
|
||||
ops_ref++;
|
||||
Vec_IntZero(Valid_Ops); // reset updates
|
||||
continue;
|
||||
}
|
||||
}
|
||||
//fwrite((**DecisionMask).pArray, sizeof(int), sizeof((**DecisionMask).pArray), fpt);
|
||||
for (int i = 0; i < (nNodes); i++){
|
||||
fprintf(fpt, "%d\n", (*DecisionMask)->pArray[i]);}
|
||||
fclose(fpt);
|
||||
/*
|
||||
printf("size of vector %d\n", Valid_Len);
|
||||
printf("Nodes with rewrite: %d\n", ops_rwr);
|
||||
printf("Nodes with resub: %d\n", ops_res);
|
||||
printf("Nodes with refactor: %d\n", ops_ref);
|
||||
printf("Nodes without updates: %d\n", ops_null);
|
||||
*/
|
||||
Extra_ProgressBarStop( pProgress );
|
||||
// Rewrite
|
||||
Rwr_ManAddTimeTotal( pManRwr, Abc_Clock() - clkStart );
|
||||
pManRwr->nNodesEnd = Abc_NtkNodeNum(pNtk);
|
||||
|
||||
// Resub
|
||||
pManRes->timeTotal = Abc_Clock() - clkStart;
|
||||
pManRes->nNodesEnd = Abc_NtkNodeNum(pNtk);
|
||||
|
||||
// Refactor
|
||||
pManRef->timeTotal = Abc_Clock() - clkStart;
|
||||
pManRef->nNodesEnd = Abc_NtkNodeNum(pNtk);
|
||||
|
||||
// print statistics
|
||||
if ( fVerbose ){
|
||||
Abc_ManResubPrint( pManRes );
|
||||
Rwr_ManPrintStats( pManRwr );
|
||||
Abc_NtkManRefPrintStats_1( pManRef );
|
||||
}
|
||||
if ( fVeryVerbose )
|
||||
Rwr_ScoresReport( pManRwr );
|
||||
// delete the managers
|
||||
// resub
|
||||
Abc_ManResubStop( pManRes );
|
||||
Abc_NtkManCutStop( pManCutRes );
|
||||
// rewrite
|
||||
Rwr_ManStop( pManRwr );
|
||||
Cut_ManStop( pManCutRwr );
|
||||
pNtk->pManCut = NULL;
|
||||
// refactor
|
||||
Abc_NtkManCutStop( pManCutRef );
|
||||
Abc_NtkManRefStop_1( pManRef );
|
||||
|
||||
if ( pManOdc ) Abc_NtkDontCareFree( pManOdc );
|
||||
|
||||
// clean the data field
|
||||
Abc_NtkForEachObj( pNtk, pNode, i )
|
||||
pNode->pData = NULL;
|
||||
|
||||
if ( Abc_NtkLatchNum(pNtk) ) {
|
||||
Abc_NtkForEachLatch(pNtk, pNode, i)
|
||||
pNode->pData = pNode->pNext, pNode->pNext = NULL;
|
||||
}
|
||||
|
||||
// put the nodes into the DFS order and reassign their IDs
|
||||
Abc_NtkReassignIds( pNtk );
|
||||
// Abc_AigCheckFaninOrder( pNtk->pManFunc );
|
||||
|
||||
// fix the levels
|
||||
if ( fUpdateLevel )
|
||||
Abc_NtkStopReverseLevels( pNtk );
|
||||
else
|
||||
Abc_NtkLevel( pNtk );
|
||||
// check
|
||||
if ( !Abc_NtkCheck( pNtk ) )
|
||||
{
|
||||
printf( "Abc_NtkOchestraction: The network check has failed.\n" );
|
||||
return 0;
|
||||
}
|
||||
nNodes_after = Abc_NtkObjNumMax(pNtk);
|
||||
//printf("nNodes after optimization: %d\n", nNodes_after);
|
||||
//s_ResubTime = Abc_Clock() - clkStart;
|
||||
//clock_t end=clock();
|
||||
//double time_spent = (double)(end-begin)/CLOCKS_PER_SEC;
|
||||
//printf("time %f\n", time_spent);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
|
|
|
|||
|
|
@ -224,6 +224,37 @@ float Abc_NtkGetArea( Abc_Ntk_t * pNtk )
|
|||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
float Abc_NtkGetAreaSpecial( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Obj_t * pObj; int i, Count = 0;
|
||||
Abc_NtkForEachNode( pNtk, pObj, i )
|
||||
if ( !strncmp( Mio_GateReadName((Mio_Gate_t*)pObj->pData), "mm", 2 ) )
|
||||
Count++;
|
||||
return 1.0*Count/Abc_NtkNodeNum(pNtk);
|
||||
}
|
||||
float Abc_NtkGetAreaSpecial2( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Obj_t * pObj; int i;
|
||||
float Count = 0, CountAll = 0;
|
||||
Abc_NtkForEachNode( pNtk, pObj, i ) {
|
||||
if ( !strncmp( Mio_GateReadName((Mio_Gate_t*)pObj->pData), "mm", 2 ) )
|
||||
Count += Mio_GateReadArea((Mio_Gate_t*)pObj->pData);
|
||||
CountAll += Mio_GateReadArea((Mio_Gate_t*)pObj->pData);
|
||||
}
|
||||
return 1.0*Count/CountAll;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Print the vital stats of the network.]
|
||||
|
|
@ -360,7 +391,7 @@ void Abc_NtkPrintStats( Abc_Ntk_t * pNtk, int fFactored, int fSaveBest, int fDum
|
|||
if ( fPrintMem )
|
||||
Abc_Print( 1," mem =%5.2f MB", Abc_NtkMemory(pNtk)/(1<<20) );
|
||||
Abc_Print( 1,"\n" );
|
||||
|
||||
/*
|
||||
// print the statistic into a file
|
||||
if ( fDumpResult )
|
||||
{
|
||||
|
|
@ -374,6 +405,8 @@ void Abc_NtkPrintStats( Abc_Ntk_t * pNtk, int fFactored, int fSaveBest, int fDum
|
|||
fprintf( pTable, "\n" );
|
||||
fclose( pTable );
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
{
|
||||
FILE * pTable;
|
||||
|
|
@ -389,21 +422,6 @@ void Abc_NtkPrintStats( Abc_Ntk_t * pNtk, int fFactored, int fSaveBest, int fDum
|
|||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
// print the statistic into a file
|
||||
{
|
||||
FILE * pTable;
|
||||
pTable = fopen( "ucsb/stats.txt", "a+" );
|
||||
// fprintf( pTable, "%s ", pNtk->pSpec );
|
||||
fprintf( pTable, "%d ", Abc_NtkNodeNum(pNtk) );
|
||||
// fprintf( pTable, "%d ", Abc_NtkLevel(pNtk) );
|
||||
// fprintf( pTable, "%.0f ", Abc_NtkGetMappedArea(pNtk) );
|
||||
// fprintf( pTable, "%.2f ", Abc_NtkDelayTrace(pNtk) );
|
||||
fprintf( pTable, "\n" );
|
||||
fclose( pTable );
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
// print the statistic into a file
|
||||
{
|
||||
|
|
@ -1210,11 +1228,19 @@ char * Abc_NodeGetPrintName( Abc_Obj_t * pObj )
|
|||
}
|
||||
return Abc_ObjName(nPos == 1 ? pFanout : pObj);
|
||||
}
|
||||
void Abc_NtkPrintLevel( FILE * pFile, Abc_Ntk_t * pNtk, int fProfile, int fListNodes, int fVerbose )
|
||||
void Abc_NtkPrintLevel( FILE * pFile, Abc_Ntk_t * pNtk, int fProfile, int fListNodes, int fOutputs, int fVerbose )
|
||||
{
|
||||
Abc_Obj_t * pNode;
|
||||
int i, k, Length;
|
||||
|
||||
if ( fOutputs )
|
||||
{
|
||||
Abc_NtkLevel(pNtk);
|
||||
printf( "Outputs by level: " );
|
||||
Abc_NtkForEachCo( pNtk, pNode, k )
|
||||
printf( "%d=%d ", k, Abc_ObjFanin0(pNode)->Level );
|
||||
printf( "\n" );
|
||||
return;
|
||||
}
|
||||
if ( fListNodes )
|
||||
{
|
||||
int nLevels;
|
||||
|
|
|
|||
|
|
@ -421,8 +421,8 @@ Gia_Man_t * Acb_NtkGiaDeriveMiter( Gia_Man_t * pOne, Gia_Man_t * pTwo, int Type
|
|||
{
|
||||
for ( i = 0; i < Gia_ManCoNum(pOne); i += 2 )
|
||||
{
|
||||
int pLitsF[2] = { (int)Gia_ManCo(pOne, i)->Value, (int)Gia_ManCo(pOne, i+1)->Value };
|
||||
int pLitsS[2] = { (int)Gia_ManCo(pTwo, i)->Value, (int)Gia_ManCo(pTwo, i+1)->Value };
|
||||
unsigned pLitsF[2] = { Gia_ManCo(pOne, i)->Value, Gia_ManCo(pOne, i+1)->Value };
|
||||
unsigned pLitsS[2] = { Gia_ManCo(pTwo, i)->Value, Gia_ManCo(pTwo, i+1)->Value };
|
||||
Gia_ManAppendCo( pNew, pLitsF[0] );
|
||||
Gia_ManAppendCo( pNew, pLitsS[0] );
|
||||
}
|
||||
|
|
@ -431,8 +431,8 @@ Gia_Man_t * Acb_NtkGiaDeriveMiter( Gia_Man_t * pOne, Gia_Man_t * pTwo, int Type
|
|||
{
|
||||
for ( i = 0; i < Gia_ManCoNum(pOne); i += 2 )
|
||||
{
|
||||
int pLitsF[2] = { (int)Gia_ManCo(pOne, i)->Value, (int)Gia_ManCo(pOne, i+1)->Value };
|
||||
int pLitsS[2] = { (int)Gia_ManCo(pTwo, i)->Value, (int)Gia_ManCo(pTwo, i+1)->Value };
|
||||
unsigned pLitsF[2] = { Gia_ManCo(pOne, i)->Value, Gia_ManCo(pOne, i+1)->Value };
|
||||
unsigned pLitsS[2] = { Gia_ManCo(pTwo, i)->Value, Gia_ManCo(pTwo, i+1)->Value };
|
||||
Gia_ManAppendCo( pNew, pLitsF[1] );
|
||||
Gia_ManAppendCo( pNew, pLitsS[1] );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include <process.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
#include "base/abc/abc.h"
|
||||
|
|
@ -36,6 +37,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int CmdCommandTime ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int CmdCommandSleep ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int CmdCommandEcho ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int CmdCommandQuit ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int CmdCommandAbcrc ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
|
|
@ -54,8 +56,11 @@ static int CmdCommandScanDir ( Abc_Frame_t * pAbc, int argc, char ** argv
|
|||
static int CmdCommandRenameFiles ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int CmdCommandLs ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int CmdCommandScrGen ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
#else
|
||||
static int CmdCommandScrGenLinux ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
#endif
|
||||
static int CmdCommandVersion ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int CmdCommandSGen ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int CmdCommandSis ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int CmdCommandMvsis ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int CmdCommandCapo ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
|
|
@ -86,6 +91,7 @@ void Cmd_Init( Abc_Frame_t * pAbc )
|
|||
Cmd_HistoryRead( pAbc );
|
||||
|
||||
Cmd_CommandAdd( pAbc, "Basic", "time", CmdCommandTime, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Basic", "sleep", CmdCommandSleep, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Basic", "echo", CmdCommandEcho, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Basic", "quit", CmdCommandQuit, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Basic", "abcrc", CmdCommandAbcrc, 0 );
|
||||
|
|
@ -104,8 +110,11 @@ void Cmd_Init( Abc_Frame_t * pAbc )
|
|||
Cmd_CommandAdd( pAbc, "Basic", "renamefiles", CmdCommandRenameFiles, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Basic", "ls", CmdCommandLs, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Basic", "scrgen", CmdCommandScrGen, 0 );
|
||||
#else
|
||||
Cmd_CommandAdd( pAbc, "Basic", "scrgen", CmdCommandScrGenLinux, 0 );
|
||||
#endif
|
||||
Cmd_CommandAdd( pAbc, "Basic", "version", CmdCommandVersion, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Basic", "sgen", CmdCommandSGen, 0 );
|
||||
|
||||
Cmd_CommandAdd( pAbc, "Various", "sis", CmdCommandSis, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Various", "mvsis", CmdCommandMvsis, 1 );
|
||||
|
|
@ -221,6 +230,65 @@ int CmdCommandTime( Abc_Frame_t * pAbc, int argc, char **argv )
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**Function********************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
******************************************************************************/
|
||||
int CmdCommandSleep( Abc_Frame_t * pAbc, int argc, char **argv )
|
||||
{
|
||||
abctime clkStop;
|
||||
char * pFileName = NULL;
|
||||
int c, nSecs = 1;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "Nh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'N':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
nSecs = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( nSecs < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
|
||||
if ( argc == globalUtilOptind + 1 ) {
|
||||
FILE * pFile = NULL;
|
||||
pFileName = argv[globalUtilOptind];
|
||||
while ( (pFile = fopen(pFileName, "rb")) == NULL );
|
||||
if ( pFile != NULL )
|
||||
fclose( pFile );
|
||||
}
|
||||
|
||||
clkStop = Abc_Clock() + nSecs * CLOCKS_PER_SEC;
|
||||
while ( Abc_Clock() < clkStop );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pAbc->Err, "usage: sleep [-N <num>] [-h] <file_name>\n" );
|
||||
fprintf( pAbc->Err, "\t puts ABC to sleep for some time\n" );
|
||||
fprintf( pAbc->Err, "\t-N num : time duration in seconds [default = %d]\n", nSecs );
|
||||
fprintf( pAbc->Err, "\t-h : toggle printing the command usage\n" );
|
||||
fprintf( pAbc->Err, "\t<file_name> : (optional) waiting begins after the file is created\n" );
|
||||
return 1;
|
||||
}
|
||||
/**Function********************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -1628,11 +1696,11 @@ int CmdCommandScrGen( Abc_Frame_t * pAbc, int argc, char **argv )
|
|||
int nFileNameMax, nFileNameCur;
|
||||
int Counter = 0;
|
||||
int fUseCurrent;
|
||||
char c;
|
||||
int c;
|
||||
|
||||
fUseCurrent = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( (c = Extra_UtilGetopt(argc, argv, "FDCWch") ) != EOF )
|
||||
while ( (c = Extra_UtilGetopt(argc, argv, "FRCWch") ) != EOF )
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
|
|
@ -1645,7 +1713,7 @@ int CmdCommandScrGen( Abc_Frame_t * pAbc, int argc, char **argv )
|
|||
pFileStr = argv[globalUtilOptind];
|
||||
globalUtilOptind++;
|
||||
break;
|
||||
case 'D':
|
||||
case 'R':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
fprintf( pAbc->Err, "Command line switch \"-D\" should be followed by a string.\n" );
|
||||
|
|
@ -1795,7 +1863,7 @@ int CmdCommandScrGen( Abc_Frame_t * pAbc, int argc, char **argv )
|
|||
Line[c] = '/';
|
||||
fprintf( pFile, "%s", Line );
|
||||
}
|
||||
fprintf( pFile, "\n", Line );
|
||||
fprintf( pFile, "\n" );
|
||||
}
|
||||
while( _findnext( hFile, &c_file ) == 0 );
|
||||
_findclose( hFile );
|
||||
|
|
@ -1815,17 +1883,178 @@ int CmdCommandScrGen( Abc_Frame_t * pAbc, int argc, char **argv )
|
|||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pAbc->Err, "usage: scrgen -F <str> -D <str> -C <str> -W <str> -ch\n" );
|
||||
fprintf( pAbc->Err, "usage: scrgen -F <str> -R <str> -C <str> -W <str> -ch\n" );
|
||||
fprintf( pAbc->Err, "\t generates script for running ABC\n" );
|
||||
fprintf( pAbc->Err, "\t-F str : the name of the script file [default = \"test.s\"]\n" );
|
||||
fprintf( pAbc->Err, "\t-D str : the directory to read files from [default = current]\n" );
|
||||
fprintf( pAbc->Err, "\t-R str : the directory to read files from [default = current]\n" );
|
||||
fprintf( pAbc->Err, "\t-C str : the sequence of commands to run [default = \"ps\"]\n" );
|
||||
fprintf( pAbc->Err, "\t-W str : the directory to write the resulting files [default = no writing]\n" );
|
||||
fprintf( pAbc->Err, "\t-c : toggle placing file in current/target dir [default = %s]\n", fUseCurrent? "current": "target" );
|
||||
fprintf( pAbc->Err, "\t-h : print the command usage\n\n");
|
||||
fprintf( pAbc->Err, "\tExample : scrgen -F test1.s -D a/in -C \"ps; st; ps\" -W a/out\n" );
|
||||
fprintf( pAbc->Err, "\tExample : scrgen -F test1.s -R a/in -C \"ps; st; ps\" -W a/out\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
Vec_Ptr_t * CmdReturnFileNames( char * pDirStr )
|
||||
{
|
||||
Vec_Ptr_t * vRes = Vec_PtrAlloc( 100 );
|
||||
struct dirent **namelist;
|
||||
int num_files = scandir(pDirStr, &namelist, NULL, alphasort);
|
||||
if (num_files == -1) {
|
||||
printf("Error opening directory.\n");
|
||||
return NULL;
|
||||
}
|
||||
for (int i = 0; i < num_files; i++) {
|
||||
char * pExt = strstr(namelist[i]->d_name, ".");
|
||||
if ( !pExt || !strcmp(pExt, ".") || !strcmp(pExt, "..") || !strcmp(pExt, ".s") || !strcmp(pExt, ".txt") )
|
||||
continue;
|
||||
Vec_PtrPush( vRes, Abc_UtilStrsav(namelist[i]->d_name) );
|
||||
free(namelist[i]);
|
||||
}
|
||||
free(namelist);
|
||||
return vRes;
|
||||
}
|
||||
|
||||
int CmdCommandScrGenLinux( Abc_Frame_t * pAbc, int argc, char **argv )
|
||||
{
|
||||
Vec_Ptr_t * vNames = NULL;
|
||||
FILE * pFile = NULL;
|
||||
char * pFileStr = (char *)"test.s";
|
||||
char * pDirStr = (char *)".";
|
||||
char * pComStr = (char *)"ps";
|
||||
char * pWriteStr = NULL;
|
||||
char * pWriteExt = NULL;
|
||||
char Line[2000], * pName;
|
||||
int nFileNameMax;
|
||||
int fBatch = 0;
|
||||
int c, k;
|
||||
|
||||
Extra_UtilGetoptReset();
|
||||
while ( (c = Extra_UtilGetopt(argc, argv, "FRCWEbh") ) != EOF )
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'F':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
fprintf( pAbc->Err, "Command line switch \"-F\" should be followed by a string.\n" );
|
||||
goto usage;
|
||||
}
|
||||
pFileStr = argv[globalUtilOptind];
|
||||
globalUtilOptind++;
|
||||
break;
|
||||
case 'R':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
fprintf( pAbc->Err, "Command line switch \"-D\" should be followed by a string.\n" );
|
||||
goto usage;
|
||||
}
|
||||
pDirStr = argv[globalUtilOptind];
|
||||
globalUtilOptind++;
|
||||
break;
|
||||
case 'C':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
fprintf( pAbc->Err, "Command line switch \"-C\" should be followed by a string.\n" );
|
||||
goto usage;
|
||||
}
|
||||
pComStr = argv[globalUtilOptind];
|
||||
globalUtilOptind++;
|
||||
break;
|
||||
case 'W':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
fprintf( pAbc->Err, "Command line switch \"-W\" should be followed by a string.\n" );
|
||||
goto usage;
|
||||
}
|
||||
pWriteStr = argv[globalUtilOptind];
|
||||
globalUtilOptind++;
|
||||
break;
|
||||
case 'E':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
fprintf( pAbc->Err, "Command line switch \"-E\" should be followed by a string.\n" );
|
||||
goto usage;
|
||||
}
|
||||
pWriteExt = argv[globalUtilOptind];
|
||||
globalUtilOptind++;
|
||||
break;
|
||||
case 'b':
|
||||
fBatch ^= 1;
|
||||
break;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
pFile = fopen( pFileStr, "w" );
|
||||
if ( pFile == NULL )
|
||||
{
|
||||
printf( "Cannot open output file %s.\n", pFileStr );
|
||||
return 0;
|
||||
}
|
||||
vNames = CmdReturnFileNames( pDirStr );
|
||||
if ( !vNames || !Vec_PtrSize(vNames) )
|
||||
{
|
||||
if ( vNames )
|
||||
printf( "It looks like the directory \"%s\" does not contain any relevant files.\n", pDirStr );
|
||||
Vec_PtrFreeP(&vNames);
|
||||
return 0;
|
||||
}
|
||||
nFileNameMax = 0;
|
||||
Vec_PtrForEachEntry( char *, vNames, pName, k )
|
||||
if ( nFileNameMax < strlen(pName) )
|
||||
nFileNameMax = strlen(pName);
|
||||
{
|
||||
int fAndSpace = pComStr[0] == '&';
|
||||
fprintf( pFile, "# Script file produced by ABC on %s\n", Extra_TimeStamp() );
|
||||
fprintf( pFile, "# Command line was: scrgen -F %s -D %s -C \"%s\"%s%s%s%s\n",
|
||||
pFileStr, pDirStr, pComStr,
|
||||
pWriteStr?" -W ":"", pWriteStr?pWriteStr:"",
|
||||
pWriteExt?" -E ":"", pWriteExt?pWriteExt:"" );
|
||||
Vec_PtrForEachEntry( char *, vNames, pName, k ) {
|
||||
char * pExt = strstr(pName, ".");
|
||||
if ( !pExt || !strcmp(pExt, ".") || !strcmp(pExt, "..") || !strcmp(pExt, ".s") || !strcmp(pExt, ".txt") )
|
||||
continue;
|
||||
sprintf( Line, "%s%sread %s%s%-*s ; %s", fBatch ? "./abc -q \"":"", fAndSpace ? "&" : "", pDirStr?pDirStr:"", pDirStr?"/":"", nFileNameMax, pName, pComStr );
|
||||
for ( c = (int)strlen(Line)-1; c >= 0; c-- )
|
||||
if ( Line[c] == '\\' )
|
||||
Line[c] = '/';
|
||||
fprintf( pFile, "%s", Line );
|
||||
if ( pWriteStr )
|
||||
{
|
||||
char * pFNameOut = pWriteExt ? Extra_FileNameGenericAppend(pName, pWriteExt) : pName;
|
||||
sprintf( Line, " ; %swrite %s/%-*s", fAndSpace ? "&" : "", pWriteStr, nFileNameMax, pFNameOut );
|
||||
for ( c = (int)strlen(Line)-1; c >= 0; c-- )
|
||||
if ( Line[c] == '\\' )
|
||||
Line[c] = '/';
|
||||
fprintf( pFile, "%s", Line );
|
||||
}
|
||||
if ( fBatch )
|
||||
fprintf( pFile, "\"" );
|
||||
fprintf( pFile, "\n" );
|
||||
}
|
||||
}
|
||||
fclose( pFile );
|
||||
printf( "Script file \"%s\" with command lines for %d files.\n", pFileStr, Vec_PtrSize(vNames) );
|
||||
Vec_PtrFreeFree( vNames );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pAbc->Err, "usage: scrgen -F <str> -R <str> -C <str> -W <str> -E <str> -bh\n" );
|
||||
fprintf( pAbc->Err, "\t generates script for running ABC\n" );
|
||||
fprintf( pAbc->Err, "\t-F str : the name of the script file [default = \"test.s\"]\n" );
|
||||
fprintf( pAbc->Err, "\t-R str : the directory to read files from [default = current]\n" );
|
||||
fprintf( pAbc->Err, "\t-C str : the sequence of commands to run [default = \"ps\"]\n" );
|
||||
fprintf( pAbc->Err, "\t-W str : the directory to write the resulting files [default = no writing]\n" );
|
||||
fprintf( pAbc->Err, "\t-E str : the output files extension (with \".\") [default = the same as input files]\n" );
|
||||
fprintf( pAbc->Err, "\t-b : toggles adding batch mode support [default = %s]\n", fBatch? "yes": "no" );
|
||||
fprintf( pAbc->Err, "\t-h : print the command usage\n\n");
|
||||
fprintf( pAbc->Err, "\tExample : scrgen -F test1.s -R a/in -C \"ps; st; ps\" -W a/out -E .blif\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -2385,18 +2614,18 @@ usage:
|
|||
***********************************************************************/
|
||||
int CmdCommandStarter( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
extern void Cmd_RunStarter( char * pFileName, char * pBinary, char * pCommand, int nCores );
|
||||
extern void Cmd_RunStarter( char * pFileName, char * pBinary, char * pCommand, int nCores, int fVerbose );
|
||||
FILE * pFile;
|
||||
char * pFileName;
|
||||
char * pCommand = NULL;
|
||||
int c, nCores = 3;
|
||||
int fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "NCvh" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "PCvh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'N':
|
||||
case 'P':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" );
|
||||
|
|
@ -2443,13 +2672,13 @@ int CmdCommandStarter( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
}
|
||||
fclose( pFile );
|
||||
// run commands
|
||||
Cmd_RunStarter( pFileName, pAbc->sBinary, pCommand, nCores );
|
||||
Cmd_RunStarter( pFileName, pAbc->sBinary, pCommand, nCores, fVerbose );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
Abc_Print( -2, "usage: starter [-N num] [-C cmd] [-vh] <file>\n" );
|
||||
Abc_Print( -2, "usage: starter [-P num] [-C cmd] [-vh] <file>\n" );
|
||||
Abc_Print( -2, "\t runs command lines listed in <file> concurrently on <num> CPUs\n" );
|
||||
Abc_Print( -2, "\t-N num : the number of concurrent jobs including the controller [default = %d]\n", nCores );
|
||||
Abc_Print( -2, "\t-P num : the number of concurrent jobs including the controller [default = %d]\n", nCores );
|
||||
Abc_Print( -2, "\t-C cmd : (optional) ABC command line to execute on benchmarks in <file>\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");
|
||||
|
|
@ -2606,6 +2835,79 @@ usage:
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int CmdCommandSGen( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
extern void Cmd_CommandSGen( Abc_Frame_t * pAbc, int nParts, int nIters, int fVerbose );
|
||||
int c, nParts = 10;
|
||||
int nIters = 10;
|
||||
int fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "NIvh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'N':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
nParts = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( nParts < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'I':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-I\" should be followed by a string (possibly in quotes).\n" );
|
||||
goto usage;
|
||||
}
|
||||
nIters = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
break;
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
if ( Abc_FrameReadNtk(pAbc) == NULL )
|
||||
{
|
||||
Abc_Print( -2, "There is no current network.\n" );
|
||||
return 1;
|
||||
}
|
||||
if ( !Abc_NtkIsStrash(Abc_FrameReadNtk(pAbc)) )
|
||||
{
|
||||
Abc_Print( -2, "The current network is not an AIG.\n" );
|
||||
return 1;
|
||||
}
|
||||
Cmd_CommandSGen( pAbc, nParts, nIters, fVerbose );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
Abc_Print( -2, "usage: sgen [-N num] [-I num] [-vh]\n" );
|
||||
Abc_Print( -2, "\t experiment with script generation\n" );
|
||||
Abc_Print( -2, "\t-N num : the number of commands to use [default = %d]\n", nParts );
|
||||
Abc_Print( -2, "\t-I num : the number of iterations to perform [default = %d]\n", nIters );
|
||||
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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
|
||||
#ifndef ABC_USE_PTHREADS
|
||||
|
||||
void Cmd_RunStarter( char * pFileName, char * pBinary, char * pCommand, int nCores ) {}
|
||||
void Cmd_RunStarter( char * pFileName, char * pBinary, char * pCommand, int nCores, int fVerbose ) {}
|
||||
|
||||
#else // pthreads are used
|
||||
|
||||
|
|
@ -104,7 +104,7 @@ void * Abc_RunThread( void * pCommand )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cmd_RunStarter( char * pFileName, char * pBinary, char * pCommand, int nCores )
|
||||
void Cmd_RunStarter( char * pFileName, char * pBinary, char * pCommand, int nCores, int fVerbose )
|
||||
{
|
||||
FILE * pFile, * pFileTemp;
|
||||
pthread_t * pThreadIds;
|
||||
|
|
@ -204,8 +204,10 @@ void Cmd_RunStarter( char * pFileName, char * pBinary, char * pCommand, int nCor
|
|||
}
|
||||
else
|
||||
BufferCopy = Abc_UtilStrsav( Buffer );
|
||||
fprintf( stdout, "Calling: %s\n", (char *)BufferCopy );
|
||||
fflush( stdout );
|
||||
if ( fVerbose ) {
|
||||
fprintf( stdout, "Calling: %s\n", (char *)BufferCopy );
|
||||
fflush( stdout );
|
||||
}
|
||||
|
||||
// wait till there is an empty thread
|
||||
while ( 1 )
|
||||
|
|
|
|||
|
|
@ -836,6 +836,70 @@ void Gia_ManKissatCall( Abc_Frame_t * pAbc, char * pFileName, char * pArgs, int
|
|||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
char * Cmd_GenScript( char ** pComms, int nComms, int nParts )
|
||||
{
|
||||
static char pScript[1000]; int c;
|
||||
pScript[0] = 0;
|
||||
for ( c = 0; c < nParts; c++ ) {
|
||||
strcat( pScript, pComms[rand() % nComms] );
|
||||
strcat( pScript, "; " );
|
||||
}
|
||||
strcat( pScript, "print_stats" );
|
||||
return pScript;
|
||||
}
|
||||
void Cmd_CommandSGen( Abc_Frame_t * pAbc, int nParts, int nIters, int fVerbose )
|
||||
{
|
||||
Abc_Ntk_t * pCopy = Abc_NtkDup( Abc_FrameReadNtk(pAbc) );
|
||||
Abc_Ntk_t * pBest = Abc_NtkDup( Abc_FrameReadNtk(pAbc) );
|
||||
Abc_Ntk_t * pCur = NULL; int i;
|
||||
char * pComms[6] = { "balance", "rewrite", "rewrite -z", "refactor", "refactor -z", "resub" };
|
||||
srand( time(NULL) );
|
||||
for ( i = 0; i < nIters; i++ )
|
||||
{
|
||||
char * pScript = Cmd_GenScript( pComms, 6, nParts );
|
||||
Abc_FrameSetCurrentNetwork( pAbc, Abc_NtkDup(pCopy) );
|
||||
if ( Abc_FrameIsBatchMode() )
|
||||
{
|
||||
if ( Cmd_CommandExecute(pAbc, pScript) )
|
||||
{
|
||||
Abc_Print( 1, "Something did not work out with the command \"%s\".\n", pScript );
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Abc_FrameSetBatchMode( 1 );
|
||||
if ( Cmd_CommandExecute(pAbc, pScript) )
|
||||
{
|
||||
Abc_Print( 1, "Something did not work out with the command \"%s\".\n", pScript );
|
||||
Abc_FrameSetBatchMode( 0 );
|
||||
return;
|
||||
}
|
||||
Abc_FrameSetBatchMode( 0 );
|
||||
}
|
||||
pCur = Abc_FrameReadNtk(pAbc);
|
||||
if ( Abc_NtkNodeNum(pCur) < Abc_NtkNodeNum(pBest) ) {
|
||||
Abc_Obj_t * pObj; int k;
|
||||
Abc_NtkForEachObj( pBest, pObj, k )
|
||||
pObj->fMarkA = pObj->fMarkB = pObj->fMarkC = 0;
|
||||
Abc_NtkDelete( pBest );
|
||||
pBest = Abc_NtkDup( pCur );
|
||||
}
|
||||
}
|
||||
Abc_FrameSetCurrentNetwork( pAbc, pBest );
|
||||
Abc_NtkDelete( pCopy );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ static int IoCommandReadInit ( Abc_Frame_t * pAbc, int argc, char **argv );
|
|||
static int IoCommandReadPla ( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
static int IoCommandReadPlaMo ( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
static int IoCommandReadTruth ( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
static int IoCommandReadCnf ( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
static int IoCommandReadVerilog ( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
static int IoCommandReadStatus ( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
static int IoCommandReadGig ( Abc_Frame_t * pAbc, int argc, char **argv );
|
||||
|
|
@ -126,6 +127,7 @@ void Io_Init( Abc_Frame_t * pAbc )
|
|||
Cmd_CommandAdd( pAbc, "I/O", "read_pla", IoCommandReadPla, 1 );
|
||||
Cmd_CommandAdd( pAbc, "I/O", "read_plamo", IoCommandReadPlaMo, 1 );
|
||||
Cmd_CommandAdd( pAbc, "I/O", "read_truth", IoCommandReadTruth, 1 );
|
||||
Cmd_CommandAdd( pAbc, "I/O", "read_cnf", IoCommandReadCnf, 1 );
|
||||
Cmd_CommandAdd( pAbc, "I/O", "read_verilog", IoCommandReadVerilog, 1 );
|
||||
Cmd_CommandAdd( pAbc, "I/O", "read_status", IoCommandReadStatus, 0 );
|
||||
Cmd_CommandAdd( pAbc, "I/O", "&read_gig", IoCommandReadGig, 0 );
|
||||
|
|
@ -278,6 +280,18 @@ int IoCommandRead( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
return 0;
|
||||
}
|
||||
// read the file using the corresponding file reader
|
||||
if ( strstr(pFileName, ".") && !strcmp(strstr(pFileName, "."), ".s") )
|
||||
{
|
||||
char Command[1000];
|
||||
assert( strlen(pFileName) < 980 );
|
||||
sprintf( Command, "source -x %s", pFileName );
|
||||
if ( Cmd_CommandExecute( pAbc, Command ) )
|
||||
{
|
||||
fprintf( stdout, "Cannot execute command \"%s\".\n", Command );
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
pNtk = Io_Read( pFileName, Io_ReadFileType(pFileName), fCheck, fBarBufs );
|
||||
if ( pNtk == NULL )
|
||||
return 0;
|
||||
|
|
@ -1524,6 +1538,80 @@ usage:
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int IoCommandReadCnf( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
extern Vec_Ptr_t * Io_FileReadCnf( char * pFileName, int fMulti );
|
||||
FILE * pFile;
|
||||
Abc_Ntk_t * pNtk;
|
||||
Vec_Ptr_t * vSops;
|
||||
int fMulti = 0;
|
||||
int c;
|
||||
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "mh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'm':
|
||||
fMulti ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
|
||||
if ( argc != globalUtilOptind + 1 )
|
||||
goto usage;
|
||||
|
||||
pFile = fopen( argv[globalUtilOptind], "rb" );
|
||||
if ( pFile == NULL )
|
||||
{
|
||||
printf( "The file \"%s\" cannot be found.\n", argv[globalUtilOptind] );
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
fclose( pFile );
|
||||
vSops = Io_FileReadCnf( argv[globalUtilOptind], fMulti );
|
||||
if ( Vec_PtrSize(vSops) == 0 )
|
||||
{
|
||||
Vec_PtrFreeFree( vSops );
|
||||
fprintf( pAbc->Err, "Reading CNF file has failed.\n" );
|
||||
return 1;
|
||||
}
|
||||
pNtk = Abc_NtkCreateWithNodes( vSops );
|
||||
Vec_PtrFreeFree( vSops );
|
||||
if ( pNtk == NULL )
|
||||
{
|
||||
fprintf( pAbc->Err, "Deriving the network has failed.\n" );
|
||||
return 1;
|
||||
}
|
||||
// replace the current network
|
||||
Abc_FrameReplaceCurrentNetwork( pAbc, pNtk );
|
||||
Abc_FrameClearVerifStatus( pAbc );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pAbc->Err, "usage: read_cnf [-mh] <file>\n" );
|
||||
fprintf( pAbc->Err, "\t creates network with one node\n" );
|
||||
fprintf( pAbc->Err, "\t-m : toggles generating multi-output network [default = %s]\n", fMulti? "yes":"no" );
|
||||
fprintf( pAbc->Err, "\t-h : prints the command summary\n" );
|
||||
fprintf( pAbc->Err, "\tfile : file name with the truth table\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
|
|||
|
|
@ -920,6 +920,116 @@ void Io_TransformSF2PLA( char * pNameIn, char * pNameOut )
|
|||
ABC_FREE( pBuffer );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Reads CNF from file.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Ptr_t * Io_ConvertNumsToSop( Vec_Wec_t * vNums, int nVars )
|
||||
{
|
||||
Vec_Ptr_t * vSops = Vec_PtrAlloc(1);
|
||||
Vec_Int_t * vLevel; int i, k, Num;
|
||||
int nSize = (nVars + 3)*Vec_WecSize(vNums);
|
||||
char * pStr = ABC_ALLOC( char, nSize+1 );
|
||||
memset( pStr, '-', nSize );
|
||||
pStr[nSize] = 0;
|
||||
Vec_WecForEachLevel( vNums, vLevel, i )
|
||||
{
|
||||
char * pCube = pStr + (nVars + 3)*i;
|
||||
Vec_IntForEachEntry( vLevel, Num, k )
|
||||
pCube[Abc_Lit2Var(Num)] = '0' + Abc_LitIsCompl(Num);
|
||||
pCube[nVars+0] = ' ';
|
||||
pCube[nVars+1] = '0';
|
||||
pCube[nVars+2] = '\n';
|
||||
}
|
||||
Vec_PtrPush( vSops, pStr );
|
||||
return vSops;
|
||||
}
|
||||
Vec_Ptr_t * Io_ConvertNumsToSopMulti( Vec_Wec_t * vNums, int nVars )
|
||||
{
|
||||
Vec_Ptr_t * vSops = Vec_PtrAlloc( Vec_WecSize(vNums) );
|
||||
Vec_Int_t * vLevel; int i, k, Num;
|
||||
Vec_WecForEachLevel( vNums, vLevel, i )
|
||||
{
|
||||
char * pCube = ABC_ALLOC( char, nVars + 4 );
|
||||
memset( pCube, '-', nVars );
|
||||
Vec_IntForEachEntry( vLevel, Num, k )
|
||||
pCube[Abc_Lit2Var(Num)] = '0' + Abc_LitIsCompl(Num);
|
||||
pCube[nVars+0] = ' ';
|
||||
pCube[nVars+1] = '0';
|
||||
pCube[nVars+2] = '\n';
|
||||
pCube[nVars+3] = '\0';
|
||||
Vec_PtrPush( vSops, pCube );
|
||||
}
|
||||
return vSops;
|
||||
}
|
||||
Vec_Ptr_t * Io_FileReadCnf( char * pFileName, int fMulti )
|
||||
{
|
||||
Vec_Ptr_t * vSops = NULL;
|
||||
Vec_Wec_t * vNums = Vec_WecAlloc( 100 );
|
||||
Vec_Int_t * vLevel;
|
||||
char * pThis, pLine[10000];
|
||||
int nVars = -1, nClas = -1;
|
||||
FILE * pFile = fopen( pFileName, "rb" );
|
||||
if ( pFile == NULL ) {
|
||||
printf( "Cannot open file \"%s\" for reading.\n", pFileName );
|
||||
return NULL;
|
||||
}
|
||||
while ( fgets( pLine, 10000, pFile ) )
|
||||
{
|
||||
if ( pLine[0] == 'c' )
|
||||
continue;
|
||||
if ( pLine[0] == 'p' )
|
||||
{
|
||||
pThis = strtok(pLine+1, " \t\n\r");
|
||||
if ( strcmp(pThis, "cnf") )
|
||||
{
|
||||
Vec_PtrFree( vSops );
|
||||
Vec_WecFree( vNums );
|
||||
fclose( pFile );
|
||||
printf( "Wrong file format.\n" );
|
||||
return NULL;
|
||||
}
|
||||
pThis = strtok(NULL, " \t\n\r");
|
||||
nVars = atoi(pThis);
|
||||
pThis = strtok(NULL, " \t\n\r");
|
||||
nClas = atoi(pThis);
|
||||
continue;
|
||||
}
|
||||
pThis = strtok(pLine, " \t\n\r");
|
||||
if ( pThis == NULL )
|
||||
continue;
|
||||
vLevel = Vec_WecPushLevel( vNums );
|
||||
while ( pThis ) {
|
||||
int fComp, Temp = atoi(pThis);
|
||||
if ( Temp == 0 )
|
||||
break;
|
||||
fComp = Temp < 0;
|
||||
Temp = Temp < 0 ? -Temp : Temp;
|
||||
Temp -= 1;
|
||||
assert( Temp < nVars );
|
||||
Vec_IntPush( vLevel, Abc_Var2Lit(Temp, fComp) );
|
||||
pThis = strtok(NULL, " \t\n\r");
|
||||
}
|
||||
}
|
||||
fclose( pFile );
|
||||
if ( nClas != Vec_WecSize(vNums) )
|
||||
printf( "Warning: The number of clauses (%d) listed is different from the actual number (%d).\n", nClas, Vec_WecSize(vNums) );
|
||||
//Vec_WecPrint( vNums, 0 );
|
||||
if ( fMulti )
|
||||
vSops = Io_ConvertNumsToSopMulti(vNums, nVars);
|
||||
else
|
||||
vSops = Io_ConvertNumsToSop(vNums, nVars);
|
||||
Vec_WecFree( vNums );
|
||||
return vSops;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -106,6 +106,9 @@ extern ABC_DLL int * Abc_FrameReadBoxes( Abc_Frame_t * pAbc );
|
|||
extern ABC_DLL int Abc_FrameReadProbStatus( Abc_Frame_t * pAbc );
|
||||
extern ABC_DLL void * Abc_FrameReadCex( Abc_Frame_t * pAbc );
|
||||
|
||||
// procedure to set retiming data
|
||||
extern ABC_DLL void Abc_FrameSetRetimingData( Abc_Frame_t * pAbc, int * pRst, int * pSet, int * pEna, int nRegs );
|
||||
|
||||
// procedure to return sequential equivalences
|
||||
extern ABC_DLL int * Abc_FrameReadMiniAigEquivClasses( Abc_Frame_t * pAbc );
|
||||
|
||||
|
|
|
|||
|
|
@ -677,7 +677,7 @@ Gia_Man_t * Wlc_ManGenTree( int nInputs, int Value, int nBits, int fVerbose )
|
|||
***********************************************************************/
|
||||
Gia_Man_t * Wlc_ManGenProd( int nInputs, int fVerbose )
|
||||
{
|
||||
extern void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla, Vec_Wec_t ** pvProds );
|
||||
extern void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla, Vec_Wec_t ** pvProds, int fVerbose );
|
||||
extern void Wlc_BlastMultiplier3( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla, Vec_Wec_t ** pvProds );
|
||||
Vec_Int_t * vIns = Vec_IntAlloc( 2*nInputs );
|
||||
Gia_Man_t * pTemp, * pNew;
|
||||
|
|
@ -693,7 +693,7 @@ Gia_Man_t * Wlc_ManGenProd( int nInputs, int fVerbose )
|
|||
// Vec_IntPush( vIns, Vec_IntEntry(vIns, i) );
|
||||
|
||||
Gia_ManHashAlloc( pNew );
|
||||
Wlc_BlastBooth( pNew, Vec_IntArray(vIns), Vec_IntArray(vIns)+nInputs, nInputs, nInputs, NULL, 0, 0, &vProds );
|
||||
Wlc_BlastBooth( pNew, Vec_IntArray(vIns), Vec_IntArray(vIns)+nInputs, nInputs, nInputs, NULL, 0, 0, &vProds, 0 );
|
||||
//Wlc_BlastMultiplier3( pNew, Vec_IntArray(vIns), Vec_IntArray(vIns)+nInputs, nInputs, nInputs, NULL, 0, 0, &vProds );
|
||||
//Vec_WecPrint( vProds, 0 );
|
||||
Wlc_ManGenTreeOne( pNew, vProds, 1, fVerbose );
|
||||
|
|
|
|||
|
|
@ -448,7 +448,7 @@ extern void Wlc_NtkDeleteSim( Vec_Ptr_t * p );
|
|||
extern int Wlc_StdinProcessSmt( Abc_Frame_t * pAbc, char * pCmd );
|
||||
/*=== wlcReadVer.c ========================================================*/
|
||||
extern char * Wlc_PrsConvertInitValues( Wlc_Ntk_t * p );
|
||||
extern Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr );
|
||||
extern Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr, int fInter );
|
||||
/*=== wlcUif.c ========================================================*/
|
||||
extern Vec_Int_t * Wlc_NtkCollectAddMult( Wlc_Ntk_t * p, Wlc_BstPar_t * pPar, int * pCountA, int * CountM );
|
||||
extern int Wlc_NtkPairIsUifable( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Wlc_Obj_t * pObj2 );
|
||||
|
|
|
|||
|
|
@ -1050,7 +1050,7 @@ void Wlc_BlastReduceMatrix2( Gia_Man_t * pNew, Vec_Wec_t * vProds, Vec_Int_t * v
|
|||
}
|
||||
|
||||
|
||||
void Wlc_BlastMultiplier3( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla, Vec_Wec_t ** pvProds )
|
||||
void Wlc_BlastMultiplier3( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla, Vec_Wec_t ** pvProds, int fVerbose )
|
||||
{
|
||||
Vec_Wec_t * vProds = Vec_WecStart( nArgA + nArgB );
|
||||
Vec_Wec_t * vLevels = Vec_WecStart( nArgA + nArgB );
|
||||
|
|
@ -1064,13 +1064,17 @@ void Wlc_BlastMultiplier3( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA
|
|||
}
|
||||
if ( fSigned )
|
||||
{
|
||||
Vec_WecPush( vProds, nArgA, 1 );
|
||||
Vec_WecPush( vLevels, nArgA, 0 );
|
||||
Vec_WecPush( vProds, nArgB-1, 1 );
|
||||
Vec_WecPush( vLevels, nArgB-1, 0 );
|
||||
|
||||
Vec_WecPush( vProds, nArgA-1, 1 );
|
||||
Vec_WecPush( vLevels, nArgA-1, 0 );
|
||||
|
||||
Vec_WecPush( vProds, nArgA+nArgB-1, 1 );
|
||||
Vec_WecPush( vLevels, nArgA+nArgB-1, 0 );
|
||||
}
|
||||
|
||||
if ( fVerbose )
|
||||
Vec_WecPrint( vProds, 0 );
|
||||
if ( pvProds )
|
||||
*pvProds = Vec_WecDup(vProds);
|
||||
else
|
||||
|
|
@ -1117,7 +1121,7 @@ void Wlc_BlastDecoder( Gia_Man_t * pNew, int * pNum, int nNum, Vec_Int_t * vTmp,
|
|||
Vec_IntPush( vRes, iMint );
|
||||
}
|
||||
}
|
||||
void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla, Vec_Wec_t ** pvProds )
|
||||
void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla, Vec_Wec_t ** pvProds, int fVerbose )
|
||||
{
|
||||
Vec_Wec_t * vProds = Vec_WecStart( nArgA + nArgB + 3 );
|
||||
Vec_Wec_t * vLevels = Vec_WecStart( nArgA + nArgB + 3 );
|
||||
|
|
@ -1194,7 +1198,10 @@ void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int
|
|||
Vec_WecPush( vProds, k, Neg );
|
||||
Vec_WecPush( vLevels, k, 0 );
|
||||
}
|
||||
//Vec_WecPrint( vProds, 0 );
|
||||
//Vec_WecShrink( vProds, nArgA + nArgB );
|
||||
//Vec_WecShrink( vLevels, nArgA + nArgB );
|
||||
if ( fVerbose )
|
||||
Vec_WecPrint( vProds, 0 );
|
||||
//Wlc_BlastPrintMatrix( pNew, vProds, 1 );
|
||||
//printf( "Cutoff ID for partial products = %d.\n", Gia_ManObjNum(pNew) );
|
||||
if ( pvProds )
|
||||
|
|
@ -1832,9 +1839,9 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn )
|
|||
if ( Wlc_NtkCountConstBits(pArg0, nRangeMax) < Wlc_NtkCountConstBits(pArg1, nRangeMax) )
|
||||
ABC_SWAP( int *, pArg0, pArg1 );
|
||||
if ( pPar->fBooth )
|
||||
Wlc_BlastBooth( pNew, pArg0, pArg1, nRange0, nRange1, vRes, fSigned, pPar->fCla, NULL );
|
||||
Wlc_BlastBooth( pNew, pArg0, pArg1, nRange0, nRange1, vRes, fSigned, pPar->fCla, NULL, pParIn->fVerbose );
|
||||
else if ( pPar->fCla )
|
||||
Wlc_BlastMultiplier3( pNew, pArg0, pArg1, nRange0, nRange1, vRes, Wlc_ObjIsSignedFanin01(p, pObj), pPar->fCla, NULL );
|
||||
Wlc_BlastMultiplier3( pNew, pArg0, pArg1, nRange0, nRange1, vRes, Wlc_ObjIsSignedFanin01(p, pObj), pPar->fCla, NULL, pParIn->fVerbose );
|
||||
else
|
||||
Wlc_BlastMultiplier( pNew, pArg0, pArg1, nRangeMax, nRangeMax, vTemp2, vRes, fSigned );
|
||||
//Wlc_BlastMultiplierC( pNew, pArg0, pArg1, nRangeMax, nRangeMax, vTemp2, vRes, fSigned );
|
||||
|
|
@ -2667,6 +2674,71 @@ Vec_Int_t * Wlc_ComputePerm( Wlc_Ntk_t * pNtk, int nPis )
|
|||
return vPerm;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Wlc_TransferPioNames( Wlc_Ntk_t * p, Gia_Man_t * pNew )
|
||||
{
|
||||
int fSkipBitRange = 0;
|
||||
Wlc_Obj_t * pObj; int i, k;
|
||||
Vec_PtrFreeP( &pNew->vNamesIn );
|
||||
Vec_PtrFreeP( &pNew->vNamesOut );
|
||||
pNew->vNamesIn = Vec_PtrAlloc( Gia_ManPiNum(pNew) );
|
||||
pNew->vNamesOut = Vec_PtrAlloc( Gia_ManPoNum(pNew) );
|
||||
// create input names
|
||||
Wlc_NtkForEachCi( p, pObj, i )
|
||||
if ( Wlc_ObjIsPi(pObj) )
|
||||
{
|
||||
char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
|
||||
int nRange = Wlc_ObjRange( pObj );
|
||||
if ( fSkipBitRange && nRange == 1 )
|
||||
Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(pName) );
|
||||
else
|
||||
for ( k = 0; k < nRange; k++ )
|
||||
{
|
||||
char Buffer[1000];
|
||||
sprintf( Buffer, "%s[%d]", pName, pObj->Beg < pObj->End ? pObj->Beg+k : pObj->Beg-k );
|
||||
Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(Buffer) );
|
||||
//printf( "Writing %s\n", Buffer );
|
||||
}
|
||||
}
|
||||
// add real primary outputs
|
||||
Wlc_NtkForEachCo( p, pObj, i )
|
||||
if ( Wlc_ObjIsPo(pObj) )
|
||||
{
|
||||
char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
|
||||
int nRange = Wlc_ObjRange( pObj );
|
||||
if ( fSkipBitRange && nRange == 1 )
|
||||
Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(pName) );
|
||||
else
|
||||
for ( k = 0; k < nRange; k++ )
|
||||
{
|
||||
char Buffer[1000];
|
||||
sprintf( Buffer, "%s[%d]", pName, pObj->Beg < pObj->End ? pObj->Beg+k : pObj->Beg-k );
|
||||
Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(Buffer) );
|
||||
}
|
||||
}
|
||||
if ( Vec_PtrSize(pNew->vNamesIn) != Gia_ManPiNum(pNew) )
|
||||
printf( "The number of input bits (%d) does not match the number of primary inputs (%d) in the current AIG.\n", Vec_PtrSize(pNew->vNamesIn), Gia_ManPiNum(pNew) );
|
||||
if ( Vec_PtrSize(pNew->vNamesOut) != Gia_ManPoNum(pNew) )
|
||||
printf( "The number of output bits (%d) does not match the number of primary inputs (%d) in the current AIG.\n", Vec_PtrSize(pNew->vNamesOut), Gia_ManPoNum(pNew) );
|
||||
if ( Vec_PtrSize(pNew->vNamesIn) != Gia_ManPiNum(pNew) || Vec_PtrSize(pNew->vNamesOut) != Gia_ManPoNum(pNew) )
|
||||
{
|
||||
Vec_PtrFreeP( &pNew->vNamesIn );
|
||||
Vec_PtrFreeP( &pNew->vNamesOut );
|
||||
}
|
||||
else
|
||||
printf( "Successfully transferred the primary input/output names from the word-level design to the current AIG.\n" );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -149,14 +149,16 @@ void Wlc_SetNtk( Abc_Frame_t * pAbc, Wlc_Ntk_t * pNtk )
|
|||
******************************************************************************/
|
||||
int Abc_CommandReadWlc( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
extern void Wlc_TransferPioNames( Wlc_Ntk_t * p, Gia_Man_t * pNew );
|
||||
FILE * pFile;
|
||||
Wlc_Ntk_t * pNtk = NULL;
|
||||
char * pFileName = NULL;
|
||||
int fOldParser = 0;
|
||||
int fPrintTree = 0;
|
||||
int fInter = 0;
|
||||
int c, fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "opvh" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "opivh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
|
|
@ -166,6 +168,9 @@ int Abc_CommandReadWlc( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
case 'p':
|
||||
fPrintTree ^= 1;
|
||||
break;
|
||||
case 'i':
|
||||
fInter ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
|
|
@ -193,8 +198,12 @@ int Abc_CommandReadWlc( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
fclose( pFile );
|
||||
|
||||
// perform reading
|
||||
if ( !strcmp( Extra_FileNameExtension(pFileName), "v" ) )
|
||||
pNtk = Wlc_ReadVer( pFileName, NULL );
|
||||
if ( !strcmp( Extra_FileNameExtension(pFileName), "v" ) )
|
||||
{
|
||||
pNtk = Wlc_ReadVer( pFileName, NULL, fInter );
|
||||
if ( fInter && pAbc->pGia )
|
||||
Wlc_TransferPioNames( pNtk, pAbc->pGia );
|
||||
}
|
||||
else if ( !strcmp( Extra_FileNameExtension(pFileName), "smt" ) || !strcmp( Extra_FileNameExtension(pFileName), "smt2" ) )
|
||||
pNtk = Wlc_ReadSmt( pFileName, fOldParser, fPrintTree );
|
||||
else if ( !strcmp( Extra_FileNameExtension(pFileName), "ndr" ) )
|
||||
|
|
@ -207,10 +216,11 @@ int Abc_CommandReadWlc( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
Wlc_AbcUpdateNtk( pAbc, pNtk );
|
||||
return 0;
|
||||
usage:
|
||||
Abc_Print( -2, "usage: %%read [-opvh] <file_name>\n" );
|
||||
Abc_Print( -2, "usage: %%read [-opivh] <file_name>\n" );
|
||||
Abc_Print( -2, "\t reads word-level design from Verilog file\n" );
|
||||
Abc_Print( -2, "\t-o : toggle using old SMT-LIB parser [default = %s]\n", fOldParser? "yes": "no" );
|
||||
Abc_Print( -2, "\t-p : toggle printing parse SMT-LIB tree [default = %s]\n", fPrintTree? "yes": "no" );
|
||||
Abc_Print( -2, "\t-i : toggle reading interface only [default = %s]\n", fInter? "yes": "no" );
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -951,7 +951,7 @@ int Wlc_PrsReadDeclaration( Wlc_Prs_t * p, char * pStart )
|
|||
}
|
||||
return 1;
|
||||
}
|
||||
int Wlc_PrsDerive( Wlc_Prs_t * p )
|
||||
int Wlc_PrsDerive( Wlc_Prs_t * p, int fInter )
|
||||
{
|
||||
Wlc_Obj_t * pObj;
|
||||
char * pStart, * pName;
|
||||
|
|
@ -1031,6 +1031,8 @@ startword:
|
|||
while ( (pName = Wlc_PrsStrtok( NULL, "(,)" )) )
|
||||
{
|
||||
pName = Wlc_PrsSkipSpaces( pName );
|
||||
if ( fInter && Wlc_PrsStrCmp( pName, "wire" ) )
|
||||
return 0;
|
||||
if ( Wlc_PrsStrCmp( pName, "input" ) || Wlc_PrsStrCmp( pName, "output" ) || Wlc_PrsStrCmp( pName, "wire" ) )
|
||||
{
|
||||
if ( !Wlc_PrsReadDeclaration( p, pName ) )
|
||||
|
|
@ -1095,12 +1097,16 @@ startword:
|
|||
// these are read as part of the interface
|
||||
else if ( Wlc_PrsStrCmp( pStart, "input" ) || Wlc_PrsStrCmp( pStart, "output" ) || Wlc_PrsStrCmp( pStart, "wire" ) || Wlc_PrsStrCmp( pStart, "reg" ) )
|
||||
{
|
||||
if ( fInter && (Wlc_PrsStrCmp( pStart, "wire" ) || Wlc_PrsStrCmp( pStart, "reg" )) )
|
||||
return 0;
|
||||
if ( !Wlc_PrsReadDeclaration( p, pStart ) )
|
||||
return 0;
|
||||
}
|
||||
else if ( Wlc_PrsStrCmp( pStart, "assign" ) )
|
||||
{
|
||||
int Type, NameId, fFound, XValue = 0;
|
||||
if ( fInter )
|
||||
return 0;
|
||||
pStart += strlen("assign");
|
||||
// read name
|
||||
pStart = Wlc_PrsFindName( pStart, &pName );
|
||||
|
|
@ -1159,6 +1165,8 @@ startword:
|
|||
{
|
||||
// THIS IS A HACK to detect always statement representing combinational MUX
|
||||
int NameId, NameIdOut = -1, fFound, nValues, fDefaultFound = 0;
|
||||
if ( fInter )
|
||||
return 0;
|
||||
// find control
|
||||
pStart = Wlc_PrsFindWord( pStart, "case", &fFound );
|
||||
if ( pStart == NULL )
|
||||
|
|
@ -1682,7 +1690,7 @@ startword:
|
|||
}
|
||||
return 1;
|
||||
}
|
||||
Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr )
|
||||
Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr, int fInter )
|
||||
{
|
||||
Wlc_Prs_t * p;
|
||||
Wlc_Ntk_t * pNtk = NULL;
|
||||
|
|
@ -1696,8 +1704,23 @@ Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr )
|
|||
if ( !Wlc_PrsPrepare( p ) )
|
||||
goto finish;
|
||||
// parse models
|
||||
if ( !Wlc_PrsDerive( p ) )
|
||||
if ( !Wlc_PrsDerive( p, fInter ) )
|
||||
{
|
||||
if ( fInter )
|
||||
{
|
||||
printf( "Finished deriving interface for module \"%s\".\n", p->pNtk->pName );
|
||||
pNtk = p->pNtk; p->pNtk = NULL;
|
||||
pNtk->pSpec = Abc_UtilStrsav( pFileName );
|
||||
if ( Vec_IntSize(&pNtk->vNameIds) == 0 )
|
||||
{
|
||||
Vec_Int_t * vTemp = Vec_IntStartNatural( Wlc_NtkObjNumMax(pNtk) );
|
||||
pNtk->vNameIds = *vTemp, Vec_IntZero(vTemp);
|
||||
Vec_IntFree( vTemp );
|
||||
}
|
||||
return pNtk;
|
||||
}
|
||||
goto finish;
|
||||
}
|
||||
// derive topological order
|
||||
if ( p->pNtk )
|
||||
{
|
||||
|
|
@ -1728,7 +1751,7 @@ finish:
|
|||
void Io_ReadWordTest( char * pFileName )
|
||||
{
|
||||
Gia_Man_t * pNew;
|
||||
Wlc_Ntk_t * pNtk = Wlc_ReadVer( pFileName, NULL );
|
||||
Wlc_Ntk_t * pNtk = Wlc_ReadVer( pFileName, NULL, 0 );
|
||||
if ( pNtk == NULL )
|
||||
return;
|
||||
Wlc_WriteVer( pNtk, "test.v", 0, 0 );
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ void Rtl_NtkBlastNode( Gia_Man_t * pNew, int Type, int nIns, Vec_Int_t * vDatas,
|
|||
extern int Wlc_BlastAdder( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int Carry ); // result is in pAdd0
|
||||
extern void Wlc_BlastSubtract( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int Carry ); // result is in pAdd0
|
||||
extern int Wlc_NtkCountConstBits( int * pArray, int nSize );
|
||||
extern void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla, Vec_Wec_t ** pvProds );
|
||||
extern void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla, Vec_Wec_t ** pvProds, int fVerbose );
|
||||
extern void Wlc_BlastMultiplier3( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla, Vec_Wec_t ** pvProds );
|
||||
extern void Wlc_BlastZeroCondition( Gia_Man_t * pNew, int * pDiv, int nDiv, Vec_Int_t * vRes );
|
||||
extern void Wlc_BlastDividerTop( Gia_Man_t * pNew, int * pNum, int nNum, int * pDiv, int nDiv, int fQuo, Vec_Int_t * vRes, int fNonRest );
|
||||
|
|
@ -303,7 +303,7 @@ void Rtl_NtkBlastNode( Gia_Man_t * pNew, int Type, int nIns, Vec_Int_t * vDatas,
|
|||
if ( Wlc_NtkCountConstBits(Vec_IntArray(vArg0), Vec_IntSize(vArg0)) < Wlc_NtkCountConstBits(Vec_IntArray(vArg1), Vec_IntSize(vArg1)) )
|
||||
ABC_SWAP( Vec_Int_t, *vArg0, *vArg1 )
|
||||
if ( fBooth )
|
||||
Wlc_BlastBooth( pNew, Vec_IntArray(vArg0), Vec_IntArray(vArg1), Vec_IntSize(vArg0), Vec_IntSize(vArg1), vRes, fSigned, fCla, NULL );
|
||||
Wlc_BlastBooth( pNew, Vec_IntArray(vArg0), Vec_IntArray(vArg1), Vec_IntSize(vArg0), Vec_IntSize(vArg1), vRes, fSigned, fCla, NULL, 0 );
|
||||
else
|
||||
Wlc_BlastMultiplier3( pNew, Vec_IntArray(vArg0), Vec_IntArray(vArg1), Vec_IntSize(vArg0), Vec_IntSize(vArg1), vRes, fSigned, fCla, NULL );
|
||||
if ( nRange > Vec_IntSize(vRes) )
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ void Wln_End( Abc_Frame_t * pAbc )
|
|||
******************************************************************************/
|
||||
int Abc_CommandYosys( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
extern Gia_Man_t * Wln_BlastSystemVerilog( char * pFileName, char * pTopModule, char * pDefines, int fSkipStrash, int fInvert, int fTechMap, int fVerbose );
|
||||
extern Gia_Man_t * Wln_BlastSystemVerilog( char * pFileName, char * pTopModule, char * pDefines, int fSkipStrash, int fInvert, int fTechMap, int fLibInDir, int fVerbose );
|
||||
extern Rtl_Lib_t * Wln_ReadSystemVerilog( char * pFileName, char * pTopModule, char * pDefines, int fCollapse, int fVerbose );
|
||||
|
||||
FILE * pFile;
|
||||
|
|
@ -102,11 +102,12 @@ int Abc_CommandYosys( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
int fBlast = 0;
|
||||
int fInvert = 0;
|
||||
int fTechMap = 1;
|
||||
int fLibInDir = 0;
|
||||
int fSkipStrash = 0;
|
||||
int fCollapse = 0;
|
||||
int c, fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "TDbismcvh" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "TDbismlcvh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
|
|
@ -140,6 +141,9 @@ int Abc_CommandYosys( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
case 'm':
|
||||
fTechMap ^= 1;
|
||||
break;
|
||||
case 'l':
|
||||
fLibInDir ^= 1;
|
||||
break;
|
||||
case 'c':
|
||||
fCollapse ^= 1;
|
||||
break;
|
||||
|
|
@ -174,11 +178,11 @@ int Abc_CommandYosys( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
{
|
||||
Gia_Man_t * pNew = NULL;
|
||||
if ( !strcmp( Extra_FileNameExtension(pFileName), "v" ) )
|
||||
pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, pDefines, fSkipStrash, fInvert, fTechMap, fVerbose );
|
||||
pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, pDefines, fSkipStrash, fInvert, fTechMap, fLibInDir, fVerbose );
|
||||
else if ( !strcmp( Extra_FileNameExtension(pFileName), "sv" ) )
|
||||
pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, pDefines, fSkipStrash, fInvert, fTechMap, fVerbose );
|
||||
pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, pDefines, fSkipStrash, fInvert, fTechMap, fLibInDir, fVerbose );
|
||||
else if ( !strcmp( Extra_FileNameExtension(pFileName), "rtlil" ) )
|
||||
pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, pDefines, fSkipStrash, fInvert, fTechMap, fVerbose );
|
||||
pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, pDefines, fSkipStrash, fInvert, fTechMap, fLibInDir, fVerbose );
|
||||
else
|
||||
{
|
||||
printf( "Abc_CommandYosys(): Unknown file extension.\n" );
|
||||
|
|
@ -204,7 +208,7 @@ int Abc_CommandYosys( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
}
|
||||
return 0;
|
||||
usage:
|
||||
Abc_Print( -2, "usage: %%yosys [-T <module>] [-D <defines>] [-bismcvh] <file_name>\n" );
|
||||
Abc_Print( -2, "usage: %%yosys [-T <module>] [-D <defines>] [-bismlcvh] <file_name>\n" );
|
||||
Abc_Print( -2, "\t reads Verilog or SystemVerilog using Yosys\n" );
|
||||
Abc_Print( -2, "\t-T : specify the top module name (default uses \"-auto-top\")\n" );
|
||||
Abc_Print( -2, "\t-D : specify defines to be used by Yosys (default \"not used\")\n" );
|
||||
|
|
@ -212,6 +216,7 @@ usage:
|
|||
Abc_Print( -2, "\t-i : toggle inverting the outputs (useful for miters) [default = %s]\n", fInvert? "yes": "no" );
|
||||
Abc_Print( -2, "\t-s : toggle no structural hashing during bit-blasting [default = %s]\n", fSkipStrash? "no strash": "strash" );
|
||||
Abc_Print( -2, "\t-m : toggle using \"techmap\" to blast operators [default = %s]\n", fTechMap? "yes": "no" );
|
||||
Abc_Print( -2, "\t-l : toggle looking for \"techmap.v\" in the current directory [default = %s]\n", fLibInDir? "yes": "no" );
|
||||
Abc_Print( -2, "\t-c : toggle collapsing design hierarchy using Yosys [default = %s]\n", fCollapse? "yes": "no" );
|
||||
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");
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ Rtl_Lib_t * Wln_ReadSystemVerilog( char * pFileName, char * pTopModule, char * p
|
|||
unlink( pFileTemp );
|
||||
return pNtk;
|
||||
}
|
||||
Gia_Man_t * Wln_BlastSystemVerilog( char * pFileName, char * pTopModule, char * pDefines, int fSkipStrash, int fInvert, int fTechMap, int fVerbose )
|
||||
Gia_Man_t * Wln_BlastSystemVerilog( char * pFileName, char * pTopModule, char * pDefines, int fSkipStrash, int fInvert, int fTechMap, int fLibInDir, int fVerbose )
|
||||
{
|
||||
Gia_Man_t * pGia = NULL;
|
||||
char Command[1000];
|
||||
|
|
@ -187,7 +187,7 @@ Gia_Man_t * Wln_BlastSystemVerilog( char * pFileName, char * pTopModule, char *
|
|||
pFileName,
|
||||
pTopModule ? "-top " : "-auto-top",
|
||||
pTopModule ? pTopModule : "",
|
||||
fTechMap ? "techmap; setundef -zero; " : "", pFileTemp );
|
||||
fTechMap ? (fLibInDir ? "techmap -map techmap.v; setundef -zero; " : "techmap; setundef -zero; ") : "", pFileTemp );
|
||||
if ( fVerbose )
|
||||
printf( "%s\n", Command );
|
||||
if ( !Wln_ConvertToRtl(Command, pFileTemp) )
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,168 @@
|
|||
/**C++File**************************************************************
|
||||
|
||||
FileName [ac_wrapper.cpp]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Ashenhurst-Curtis decomposition.]
|
||||
|
||||
Synopsis [Interface with the FPGA mapping package.]
|
||||
|
||||
Author [Alessandro Tempia Calvino]
|
||||
|
||||
Affiliation [EPFL]
|
||||
|
||||
Date [Ver. 1.0. Started - November 20, 2023.]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "ac_wrapper.h"
|
||||
#include "ac_decomposition.hpp"
|
||||
#include "acd66.hpp"
|
||||
#include "acdXX.hpp"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
int acd_evaluate( word * pTruth, unsigned nVars, int lutSize, unsigned *pdelay, unsigned *cost, int try_no_late_arrival )
|
||||
{
|
||||
using namespace acd;
|
||||
|
||||
ac_decomposition_params ps;
|
||||
ps.lut_size = lutSize;
|
||||
ps.use_first = false;
|
||||
ps.try_no_late_arrival = static_cast<bool>( try_no_late_arrival );
|
||||
ac_decomposition_stats st;
|
||||
|
||||
ac_decomposition_impl acd( nVars, ps, &st );
|
||||
int val = acd.run( pTruth, *pdelay );
|
||||
|
||||
if ( val < 0 )
|
||||
{
|
||||
*pdelay = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
*pdelay = acd.get_profile();
|
||||
*cost = st.num_luts;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
int acd_decompose( word * pTruth, unsigned nVars, int lutSize, unsigned *pdelay, unsigned char *decomposition )
|
||||
{
|
||||
using namespace acd;
|
||||
|
||||
ac_decomposition_params ps;
|
||||
ps.lut_size = lutSize;
|
||||
ps.use_first = true;
|
||||
ac_decomposition_stats st;
|
||||
|
||||
ac_decomposition_impl acd( nVars, ps, &st );
|
||||
acd.run( pTruth, *pdelay );
|
||||
int val = acd.compute_decomposition();
|
||||
|
||||
if ( val < 0 )
|
||||
{
|
||||
*pdelay = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
*pdelay = acd.get_profile();
|
||||
acd.get_decomposition( decomposition );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int acd2_evaluate( word * pTruth, unsigned nVars, int lutSize, unsigned *pdelay, unsigned *cost, int try_no_late_arrival )
|
||||
{
|
||||
using namespace acd;
|
||||
|
||||
acdXX_params ps;
|
||||
ps.lut_size = lutSize;
|
||||
ps.max_shared_vars = lutSize - 2;
|
||||
acdXX_impl acd( nVars, ps );
|
||||
int val = acd.run( pTruth, *pdelay );
|
||||
|
||||
if ( val == 0 )
|
||||
{
|
||||
*pdelay = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
acd.compute_decomposition();
|
||||
*pdelay = acd.get_profile();
|
||||
*cost = 2;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
int acd2_decompose( word * pTruth, unsigned nVars, int lutSize, unsigned *pdelay, unsigned char *decomposition )
|
||||
{
|
||||
using namespace acd;
|
||||
|
||||
acdXX_params ps;
|
||||
ps.lut_size = lutSize;
|
||||
ps.max_shared_vars = lutSize - 2;
|
||||
acdXX_impl acd( nVars, ps );
|
||||
acd.run( pTruth, *pdelay );
|
||||
int val = acd.compute_decomposition();
|
||||
|
||||
if ( val != 0 )
|
||||
{
|
||||
*pdelay = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
*pdelay = acd.get_profile();
|
||||
|
||||
acd.get_decomposition( decomposition );
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int acd66_decompose( word * pTruth, unsigned nVars, unsigned char *decomposition )
|
||||
{
|
||||
using namespace acd;
|
||||
acd66_impl acd( nVars, true, false );
|
||||
|
||||
if ( acd.run( pTruth ) == 0 )
|
||||
return 0;
|
||||
if ( decomposition == NULL )
|
||||
return 1;
|
||||
int val = acd.compute_decomposition();
|
||||
if ( val != 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
acd.get_decomposition( decomposition );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int acdXX_decompose( word * pTruth, unsigned lutSize, unsigned nVars, unsigned char *decomposition )
|
||||
{
|
||||
using namespace acd;
|
||||
|
||||
if ( lutSize == 6 )
|
||||
{
|
||||
return acd66_decompose( pTruth, nVars, decomposition );
|
||||
}
|
||||
|
||||
acdXX_params ps;
|
||||
ps.lut_size = lutSize;
|
||||
ps.max_shared_vars = lutSize - 2;
|
||||
acdXX_impl acd( nVars, ps );
|
||||
|
||||
if ( acd.run( pTruth ) == 0 )
|
||||
return 0;
|
||||
if ( decomposition == NULL )
|
||||
return 1;
|
||||
int val = acd.compute_decomposition();
|
||||
if ( val != 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
acd.get_decomposition( decomposition );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/**C++File**************************************************************
|
||||
|
||||
FileName [ac_wrapper.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Ashenhurst-Curtis decomposition.]
|
||||
|
||||
Synopsis [Interface with the FPGA mapping package.]
|
||||
|
||||
Author [Alessandro Tempia Calvino]
|
||||
|
||||
Affiliation [EPFL]
|
||||
|
||||
Date [Ver. 1.0. Started - November 20, 2023.]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#pragma once
|
||||
#ifndef __ACD_WRAPPER_H_
|
||||
#define __ACD_WRAPPER_H_
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# include <intrin.h>
|
||||
# define __builtin_popcount __popcnt
|
||||
//# define __builtin_popcountl __popcnt64 // the compiler does not find __popcnt64
|
||||
# define __builtin_popcountl __popcnt
|
||||
#endif
|
||||
|
||||
#include "misc/util/abc_global.h"
|
||||
#include "map/if/if.h"
|
||||
|
||||
ABC_NAMESPACE_HEADER_START
|
||||
|
||||
int acd_evaluate( word * pTruth, unsigned nVars, int lutSize, unsigned *pdelay, unsigned *cost, int try_no_late_arrival );
|
||||
int acd_decompose( word * pTruth, unsigned nVars, int lutSize, unsigned *pdelay, unsigned char *decomposition );
|
||||
int acd2_evaluate( word * pTruth, unsigned nVars, int lutSize, unsigned *pdelay, unsigned *cost, int try_no_late_arrival );
|
||||
int acd2_decompose( word * pTruth, unsigned nVars, int lutSize, unsigned *pdelay, unsigned char *decomposition );
|
||||
|
||||
int acdXX_decompose( word * pTruth, unsigned lutSize, unsigned nVars, unsigned char *decomposition );
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,123 @@
|
|||
#ifndef _KITTY_ALGORITHM_H_
|
||||
#define _KITTY_ALGORITHM_H_
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
|
||||
#include "kitty_constants.hpp"
|
||||
#include "kitty_dynamic_tt.hpp"
|
||||
#include "kitty_static_tt.hpp"
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
namespace kitty
|
||||
{
|
||||
|
||||
/*! \brief Perform bitwise unary operation on truth table
|
||||
|
||||
\param tt Truth table
|
||||
\param op Unary operation that takes as input a word (`uint64_t`) and returns a word
|
||||
|
||||
\return new constructed truth table of same type and dimensions
|
||||
*/
|
||||
template<typename TT, typename Fn>
|
||||
TT unary_operation( const TT& tt, Fn&& op )
|
||||
{
|
||||
TT result = tt.construct();
|
||||
std::transform( tt.cbegin(), tt.cend(), result.begin(), op );
|
||||
result.mask_bits();
|
||||
return result;
|
||||
}
|
||||
|
||||
/*! \brief Perform bitwise binary operation on two truth tables
|
||||
|
||||
The dimensions of `first` and `second` must match. This is ensured
|
||||
at compile-time for static truth tables, but at run-time for dynamic
|
||||
truth tables.
|
||||
|
||||
\param first First truth table
|
||||
\param second Second truth table
|
||||
\param op Binary operation that takes as input two words (`uint64_t`) and returns a word
|
||||
|
||||
\return new constructed truth table of same type and dimensions
|
||||
*/
|
||||
template<typename TT, typename Fn>
|
||||
TT binary_operation( const TT& first, const TT& second, Fn&& op )
|
||||
{
|
||||
assert( first.num_vars() == second.num_vars() );
|
||||
|
||||
TT result = first.construct();
|
||||
std::transform( first.cbegin(), first.cend(), second.cbegin(), result.begin(), op );
|
||||
result.mask_bits();
|
||||
return result;
|
||||
}
|
||||
|
||||
/*! \brief Computes a predicate based on two truth tables
|
||||
|
||||
The dimensions of `first` and `second` must match. This is ensured
|
||||
at compile-time for static truth tables, but at run-time for dynamic
|
||||
truth tables.
|
||||
|
||||
\param first First truth table
|
||||
\param second Second truth table
|
||||
\param op Binary operation that takes as input two words (`uint64_t`) and returns a Boolean
|
||||
|
||||
\return true or false based on the predicate
|
||||
*/
|
||||
template<typename TT, typename Fn>
|
||||
bool binary_predicate( const TT& first, const TT& second, Fn&& op )
|
||||
{
|
||||
assert( first.num_vars() == second.num_vars() );
|
||||
|
||||
return std::equal( first.begin(), first.end(), second.begin(), op );
|
||||
}
|
||||
|
||||
/*! \brief Assign computed values to bits
|
||||
|
||||
The functor `op` computes bits which are assigned to the bits of the
|
||||
truth table.
|
||||
|
||||
\param tt Truth table
|
||||
\param op Unary operation that takes no input and returns a word (`uint64_t`)
|
||||
*/
|
||||
template<typename TT, typename Fn>
|
||||
void assign_operation( TT& tt, Fn&& op )
|
||||
{
|
||||
std::generate( tt.begin(), tt.end(), op );
|
||||
tt.mask_bits();
|
||||
}
|
||||
|
||||
/*! \brief Iterates through each block of a truth table
|
||||
|
||||
The functor `op` is called for every block of the truth table.
|
||||
|
||||
\param tt Truth table
|
||||
\param op Unary operation that takes as input a word (`uint64_t`) and returns void
|
||||
*/
|
||||
template<typename TT, typename Fn>
|
||||
void for_each_block( const TT& tt, Fn&& op )
|
||||
{
|
||||
std::for_each( tt.cbegin(), tt.cend(), op );
|
||||
}
|
||||
|
||||
/*! \brief Iterates through each block of a truth table in reverse
|
||||
order
|
||||
|
||||
The functor `op` is called for every block of the truth table in
|
||||
reverse order.
|
||||
|
||||
\param tt Truth table
|
||||
\param op Unary operation that takes as input a word (`uint64_t`) and returns void
|
||||
*/
|
||||
template<typename TT, typename Fn>
|
||||
void for_each_block_reversed( const TT& tt, Fn&& op )
|
||||
{
|
||||
std::for_each( tt.crbegin(), tt.crend(), op );
|
||||
}
|
||||
|
||||
} // namespace kitty
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_END
|
||||
|
||||
#endif // _KITTY_ALGORITHM_H_
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
#ifndef _KITTY_CONSTANTS_H_
|
||||
#define _KITTY_CONSTANTS_H_
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <numeric> // std::iota
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
namespace kitty
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
static constexpr uint64_t projections[] = {
|
||||
UINT64_C( 0xaaaaaaaaaaaaaaaa ),
|
||||
UINT64_C( 0xcccccccccccccccc ),
|
||||
UINT64_C( 0xf0f0f0f0f0f0f0f0 ),
|
||||
UINT64_C( 0xff00ff00ff00ff00 ),
|
||||
UINT64_C( 0xffff0000ffff0000 ),
|
||||
UINT64_C( 0xffffffff00000000 ) };
|
||||
|
||||
static constexpr uint64_t projections_neg[] = {
|
||||
UINT64_C( 0x5555555555555555 ),
|
||||
UINT64_C( 0x3333333333333333 ),
|
||||
UINT64_C( 0x0f0f0f0f0f0f0f0f ),
|
||||
UINT64_C( 0x00ff00ff00ff00ff ),
|
||||
UINT64_C( 0x0000ffff0000ffff ),
|
||||
UINT64_C( 0x00000000ffffffff ) };
|
||||
|
||||
static constexpr uint64_t masks[] = {
|
||||
UINT64_C( 0x0000000000000001 ),
|
||||
UINT64_C( 0x0000000000000003 ),
|
||||
UINT64_C( 0x000000000000000f ),
|
||||
UINT64_C( 0x00000000000000ff ),
|
||||
UINT64_C( 0x000000000000ffff ),
|
||||
UINT64_C( 0x00000000ffffffff ),
|
||||
UINT64_C( 0xffffffffffffffff ) };
|
||||
|
||||
static constexpr uint64_t permutation_masks[][3] = {
|
||||
{ UINT64_C( 0x9999999999999999 ), UINT64_C( 0x2222222222222222 ), UINT64_C( 0x4444444444444444 ) },
|
||||
{ UINT64_C( 0xc3c3c3c3c3c3c3c3 ), UINT64_C( 0x0c0c0c0c0c0c0c0c ), UINT64_C( 0x3030303030303030 ) },
|
||||
{ UINT64_C( 0xf00ff00ff00ff00f ), UINT64_C( 0x00f000f000f000f0 ), UINT64_C( 0x0f000f000f000f00 ) },
|
||||
{ UINT64_C( 0xff0000ffff0000ff ), UINT64_C( 0x0000ff000000ff00 ), UINT64_C( 0x00ff000000ff0000 ) },
|
||||
{ UINT64_C( 0xffff00000000ffff ), UINT64_C( 0x00000000ffff0000 ), UINT64_C( 0x0000ffff00000000 ) } };
|
||||
|
||||
static constexpr uint64_t ppermutation_masks[][6][3] = {
|
||||
{ { UINT64_C( 0x0000000000000000 ), UINT64_C( 0x0000000000000000 ), UINT64_C( 0x0000000000000000 ) },
|
||||
{ UINT64_C( 0x9999999999999999 ), UINT64_C( 0x2222222222222222 ), UINT64_C( 0x4444444444444444 ) },
|
||||
{ UINT64_C( 0xa5a5a5a5a5a5a5a5 ), UINT64_C( 0x0a0a0a0a0a0a0a0a ), UINT64_C( 0x5050505050505050 ) },
|
||||
{ UINT64_C( 0xaa55aa55aa55aa55 ), UINT64_C( 0x00aa00aa00aa00aa ), UINT64_C( 0x5500550055005500 ) },
|
||||
{ UINT64_C( 0xaaaa5555aaaa5555 ), UINT64_C( 0x0000aaaa0000aaaa ), UINT64_C( 0x5555000055550000 ) },
|
||||
{ UINT64_C( 0xaaaaaaaa55555555 ), UINT64_C( 0x00000000aaaaaaaa ), UINT64_C( 0x5555555500000000 ) } },
|
||||
{ { UINT64_C( 0x0000000000000000 ), UINT64_C( 0x0000000000000000 ), UINT64_C( 0x0000000000000000 ) },
|
||||
{ UINT64_C( 0x0000000000000000 ), UINT64_C( 0x0000000000000000 ), UINT64_C( 0x0000000000000000 ) },
|
||||
{ UINT64_C( 0xc3c3c3c3c3c3c3c3 ), UINT64_C( 0x0c0c0c0c0c0c0c0c ), UINT64_C( 0x3030303030303030 ) },
|
||||
{ UINT64_C( 0xcc33cc33cc33cc33 ), UINT64_C( 0x00cc00cc00cc00cc ), UINT64_C( 0x3300330033003300 ) },
|
||||
{ UINT64_C( 0xcccc3333cccc3333 ), UINT64_C( 0x0000cccc0000cccc ), UINT64_C( 0x3333000033330000 ) },
|
||||
{ UINT64_C( 0xcccccccc33333333 ), UINT64_C( 0x00000000cccccccc ), UINT64_C( 0x3333333300000000 ) } },
|
||||
{ { UINT64_C( 0x0000000000000000 ), UINT64_C( 0x0000000000000000 ), UINT64_C( 0x0000000000000000 ) },
|
||||
{ UINT64_C( 0x0000000000000000 ), UINT64_C( 0x0000000000000000 ), UINT64_C( 0x0000000000000000 ) },
|
||||
{ UINT64_C( 0x0000000000000000 ), UINT64_C( 0x0000000000000000 ), UINT64_C( 0x0000000000000000 ) },
|
||||
{ UINT64_C( 0xf00ff00ff00ff00f ), UINT64_C( 0x00f000f000f000f0 ), UINT64_C( 0x0f000f000f000f00 ) },
|
||||
{ UINT64_C( 0xf0f00f0ff0f00f0f ), UINT64_C( 0x0000f0f00000f0f0 ), UINT64_C( 0x0f0f00000f0f0000 ) },
|
||||
{ UINT64_C( 0xf0f0f0f00f0f0f0f ), UINT64_C( 0x00000000f0f0f0f0 ), UINT64_C( 0x0f0f0f0f00000000 ) } },
|
||||
{ { UINT64_C( 0x0000000000000000 ), UINT64_C( 0x0000000000000000 ), UINT64_C( 0x0000000000000000 ) },
|
||||
{ UINT64_C( 0x0000000000000000 ), UINT64_C( 0x0000000000000000 ), UINT64_C( 0x0000000000000000 ) },
|
||||
{ UINT64_C( 0x0000000000000000 ), UINT64_C( 0x0000000000000000 ), UINT64_C( 0x0000000000000000 ) },
|
||||
{ UINT64_C( 0x0000000000000000 ), UINT64_C( 0x0000000000000000 ), UINT64_C( 0x0000000000000000 ) },
|
||||
{ UINT64_C( 0xff0000ffff0000ff ), UINT64_C( 0x0000ff000000ff00 ), UINT64_C( 0x00ff000000ff0000 ) },
|
||||
{ UINT64_C( 0xff00ff0000ff00ff ), UINT64_C( 0x00000000ff00ff00 ), UINT64_C( 0x00ff00ff00000000 ) } },
|
||||
{ { UINT64_C( 0x0000000000000000 ), UINT64_C( 0x0000000000000000 ), UINT64_C( 0x0000000000000000 ) },
|
||||
{ UINT64_C( 0x0000000000000000 ), UINT64_C( 0x0000000000000000 ), UINT64_C( 0x0000000000000000 ) },
|
||||
{ UINT64_C( 0x0000000000000000 ), UINT64_C( 0x0000000000000000 ), UINT64_C( 0x0000000000000000 ) },
|
||||
{ UINT64_C( 0x0000000000000000 ), UINT64_C( 0x0000000000000000 ), UINT64_C( 0x0000000000000000 ) },
|
||||
{ UINT64_C( 0x0000000000000000 ), UINT64_C( 0x0000000000000000 ), UINT64_C( 0x0000000000000000 ) },
|
||||
{ UINT64_C( 0xffff00000000ffff ), UINT64_C( 0x00000000ffff0000 ), UINT64_C( 0x0000ffff00000000 ) } } };
|
||||
|
||||
static constexpr int32_t hex_to_int[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
|
||||
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace kitty
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_END
|
||||
|
||||
#endif //_KITTY_CONSTANTS_H_
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
#ifndef _KITTY_CONSTRUCT_TT_H_
|
||||
#define _KITTY_CONSTRUCT_TT_H_
|
||||
#pragma once
|
||||
|
||||
#include <cctype>
|
||||
#include <chrono>
|
||||
#include <istream>
|
||||
#include <random>
|
||||
#include <stack>
|
||||
|
||||
#include "kitty_constants.hpp"
|
||||
#include "kitty_dynamic_tt.hpp"
|
||||
#include "kitty_static_tt.hpp"
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
namespace kitty
|
||||
{
|
||||
|
||||
/*! \brief Creates truth table with number of variables
|
||||
|
||||
If some truth table instance is given, one can create a truth table with the
|
||||
same type by calling the `construct()` method on it. This function helps if
|
||||
only the number of variables is known and the base type and uniforms the
|
||||
creation of static and dynamic truth tables. Note, however, that for static
|
||||
truth tables `num_vars` must be consistent to the number of variables in the
|
||||
truth table type.
|
||||
|
||||
\param num_vars Number of variables
|
||||
*/
|
||||
template<typename TT>
|
||||
inline TT create( unsigned num_vars )
|
||||
{
|
||||
(void)num_vars;
|
||||
TT tt;
|
||||
assert( tt.num_vars() == num_vars );
|
||||
return tt;
|
||||
}
|
||||
|
||||
/*! \cond PRIVATE */
|
||||
template<>
|
||||
inline dynamic_truth_table create<dynamic_truth_table>( unsigned num_vars )
|
||||
{
|
||||
return dynamic_truth_table( num_vars );
|
||||
}
|
||||
/*! \endcond */
|
||||
|
||||
/*! \brief Constructs projections (single-variable functions)
|
||||
|
||||
\param tt Truth table
|
||||
\param var_index Index of the variable, must be smaller than the truth table's number of variables
|
||||
\param complement If true, realize inverse projection
|
||||
*/
|
||||
template<typename TT>
|
||||
void create_nth_var( TT& tt, uint8_t var_index, bool complement = false )
|
||||
{
|
||||
if ( tt.num_vars() <= 6 )
|
||||
{
|
||||
/* assign from precomputed table */
|
||||
tt._bits[0] = complement ? ~detail::projections[var_index] : detail::projections[var_index];
|
||||
|
||||
/* mask if truth table does not require all bits */
|
||||
tt.mask_bits();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( var_index < 6 )
|
||||
{
|
||||
std::fill( std::begin( tt._bits ), std::end( tt._bits ), complement ? ~detail::projections[var_index] : detail::projections[var_index] );
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto c = 1 << ( var_index - 6 );
|
||||
const auto zero = uint64_t( 0 );
|
||||
const auto one = ~zero;
|
||||
auto block = uint64_t( 0u );
|
||||
|
||||
while ( block < tt.num_blocks() )
|
||||
{
|
||||
for ( auto i = 0; i < c; ++i )
|
||||
{
|
||||
tt._bits[block++] = complement ? one : zero;
|
||||
}
|
||||
for ( auto i = 0; i < c; ++i )
|
||||
{
|
||||
tt._bits[block++] = complement ? zero : one;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace kitty
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_END
|
||||
|
||||
#endif // _KITTY_CONSTRUCT_TT_H_
|
||||
|
|
@ -0,0 +1,151 @@
|
|||
#ifndef _KITTY_DYNAMIC_TT_H_
|
||||
#define _KITTY_DYNAMIC_TT_H_
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
#include "kitty_constants.hpp"
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
namespace kitty
|
||||
{
|
||||
|
||||
/*! Truth table in which number of variables is known at runtime.
|
||||
*/
|
||||
struct dynamic_truth_table
|
||||
{
|
||||
/*! Standard constructor.
|
||||
|
||||
The number of variables provided to the truth table can be
|
||||
computed at runtime. However, once the truth table is constructed
|
||||
its number of variables cannot change anymore.
|
||||
|
||||
The constructor computes the number of blocks and resizes the
|
||||
vector accordingly.
|
||||
|
||||
\param num_vars Number of variables
|
||||
*/
|
||||
explicit dynamic_truth_table( uint32_t num_vars )
|
||||
: _bits( ( num_vars <= 6 ) ? 1u : ( 1u << ( num_vars - 6 ) ) ),
|
||||
_num_vars( num_vars )
|
||||
{
|
||||
}
|
||||
|
||||
/*! Empty constructor.
|
||||
|
||||
Creates an empty truth table. It has 0 variables, but no bits, i.e., it is
|
||||
different from a truth table for the constant function. This constructor is
|
||||
only used for convenience, if algorithms require the existence of default
|
||||
constructable classes.
|
||||
*/
|
||||
dynamic_truth_table() : _num_vars( 0 ) {}
|
||||
|
||||
/*! Constructs a new dynamic truth table instance with the same number of variables. */
|
||||
inline dynamic_truth_table construct() const
|
||||
{
|
||||
return dynamic_truth_table( _num_vars );
|
||||
}
|
||||
|
||||
/*! Returns number of variables.
|
||||
*/
|
||||
inline uint32_t num_vars() const noexcept { return _num_vars; }
|
||||
|
||||
/*! Returns number of blocks.
|
||||
*/
|
||||
inline uint32_t num_blocks() const noexcept { return _bits.size(); }
|
||||
|
||||
/*! Returns number of bits.
|
||||
*/
|
||||
inline uint32_t num_bits() const noexcept { return uint64_t( 1 ) << _num_vars; }
|
||||
|
||||
/*! \brief Begin iterator to bits.
|
||||
*/
|
||||
inline std::vector<uint64_t>::iterator begin() noexcept { return _bits.begin(); }
|
||||
|
||||
/*! \brief End iterator to bits.
|
||||
*/
|
||||
inline std::vector<uint64_t>::iterator end() noexcept { return _bits.end(); }
|
||||
|
||||
/*! \brief Begin iterator to bits.
|
||||
*/
|
||||
inline std::vector<uint64_t>::const_iterator begin() const noexcept { return _bits.begin(); }
|
||||
|
||||
/*! \brief End iterator to bits.
|
||||
*/
|
||||
inline std::vector<uint64_t>::const_iterator end() const noexcept { return _bits.end(); }
|
||||
|
||||
/*! \brief Reverse begin iterator to bits.
|
||||
*/
|
||||
inline std::vector<uint64_t>::reverse_iterator rbegin() noexcept { return _bits.rbegin(); }
|
||||
|
||||
/*! \brief Reverse end iterator to bits.
|
||||
*/
|
||||
inline std::vector<uint64_t>::reverse_iterator rend() noexcept { return _bits.rend(); }
|
||||
|
||||
/*! \brief Constant begin iterator to bits.
|
||||
*/
|
||||
inline std::vector<uint64_t>::const_iterator cbegin() const noexcept { return _bits.cbegin(); }
|
||||
|
||||
/*! \brief Constant end iterator to bits.
|
||||
*/
|
||||
inline std::vector<uint64_t>::const_iterator cend() const noexcept { return _bits.cend(); }
|
||||
|
||||
/*! \brief Constant reverse begin iterator to bits.
|
||||
*/
|
||||
inline std::vector<uint64_t>::const_reverse_iterator crbegin() const noexcept { return _bits.crbegin(); }
|
||||
|
||||
/*! \brief Constant teverse end iterator to bits.
|
||||
*/
|
||||
inline std::vector<uint64_t>::const_reverse_iterator crend() const noexcept { return _bits.crend(); }
|
||||
|
||||
/*! \brief Assign other truth table.
|
||||
|
||||
This replaces the current truth table with another truth table. The truth
|
||||
table type has to be complete. The vector of bits is resized accordingly.
|
||||
|
||||
\param other Other truth table
|
||||
*/
|
||||
template<class TT>
|
||||
dynamic_truth_table& operator=( const TT& other )
|
||||
{
|
||||
_bits.resize( other.num_blocks() );
|
||||
std::copy( other.begin(), other.end(), begin() );
|
||||
_num_vars = other.num_vars();
|
||||
|
||||
if ( _num_vars < 6 )
|
||||
{
|
||||
mask_bits();
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*! Masks the number of valid truth table bits.
|
||||
|
||||
If the truth table has less than 6 variables, it may not use all
|
||||
the bits. This operation makes sure to zero out all non-valid
|
||||
bits.
|
||||
*/
|
||||
inline void mask_bits() noexcept
|
||||
{
|
||||
if ( _num_vars < 6 )
|
||||
{
|
||||
_bits[0u] &= detail::masks[_num_vars];
|
||||
}
|
||||
}
|
||||
|
||||
/*! \cond PRIVATE */
|
||||
public: /* fields */
|
||||
std::vector<uint64_t> _bits;
|
||||
uint32_t _num_vars;
|
||||
/*! \endcond */
|
||||
};
|
||||
|
||||
} //namespace kitty
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_END
|
||||
|
||||
#endif // _KITTY_DYNAMIC_TT_H_
|
||||
|
|
@ -0,0 +1,355 @@
|
|||
#ifndef _KITTY_OPERATIONS_TT_H_
|
||||
#define _KITTY_OPERATIONS_TT_H_
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <optional>
|
||||
#include <iostream>
|
||||
|
||||
#include "kitty_algorithm.hpp"
|
||||
#include "kitty_constants.hpp"
|
||||
#include "kitty_dynamic_tt.hpp"
|
||||
#include "kitty_static_tt.hpp"
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
namespace kitty
|
||||
{
|
||||
|
||||
/*! Inverts all bits in a truth table, based on a condition */
|
||||
template<typename TT>
|
||||
inline TT unary_not_if( const TT& tt, bool cond )
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable : 4146 )
|
||||
#endif
|
||||
const auto mask = -static_cast<uint64_t>( cond );
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning( pop )
|
||||
#endif
|
||||
return unary_operation( tt, [mask]( uint64_t a )
|
||||
{ return a ^ mask; } );
|
||||
}
|
||||
|
||||
/*! \brief Inverts all bits in a truth table */
|
||||
template<typename TT>
|
||||
inline TT unary_not( const TT& tt )
|
||||
{
|
||||
return unary_operation( tt, []( uint64_t a )
|
||||
{ return ~a; } );
|
||||
}
|
||||
|
||||
/*! \brief Bitwise AND of two truth tables */
|
||||
template<typename TT>
|
||||
|
||||
inline TT binary_and( const TT& first, const TT& second )
|
||||
{
|
||||
return binary_operation( first, second, std::bit_and<uint64_t>() );
|
||||
}
|
||||
|
||||
/*! \brief Bitwise OR of two truth tables */
|
||||
template<typename TT>
|
||||
inline TT binary_or( const TT& first, const TT& second )
|
||||
{
|
||||
return binary_operation( first, second, std::bit_or<uint64_t>() );
|
||||
}
|
||||
|
||||
/*! \brief Swaps two variables in a truth table
|
||||
|
||||
The function swaps variable `var_index1` with `var_index2`. The
|
||||
function will change `tt` in-place. If `tt` should not be changed,
|
||||
one can use `swap` instead.
|
||||
|
||||
\param tt Truth table
|
||||
\param var_index1 First variable
|
||||
\param var_index2 Second variable
|
||||
*/
|
||||
template<typename TT>
|
||||
void swap_inplace( TT& tt, uint8_t var_index1, uint8_t var_index2 )
|
||||
{
|
||||
if ( var_index1 == var_index2 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( var_index1 > var_index2 )
|
||||
{
|
||||
std::swap( var_index1, var_index2 );
|
||||
}
|
||||
|
||||
if ( tt.num_vars() <= 6 )
|
||||
{
|
||||
const auto& pmask = detail::ppermutation_masks[var_index1][var_index2];
|
||||
const auto shift = ( 1 << var_index2 ) - ( 1 << var_index1 );
|
||||
tt._bits[0] = ( tt._bits[0] & pmask[0] ) | ( ( tt._bits[0] & pmask[1] ) << shift ) | ( ( tt._bits[0] & pmask[2] ) >> shift );
|
||||
}
|
||||
else if ( var_index2 <= 5 )
|
||||
{
|
||||
const auto& pmask = detail::ppermutation_masks[var_index1][var_index2];
|
||||
const auto shift = ( 1 << var_index2 ) - ( 1 << var_index1 );
|
||||
std::transform( std::begin( tt._bits ), std::end( tt._bits ), std::begin( tt._bits ),
|
||||
[shift, &pmask]( uint64_t word )
|
||||
{
|
||||
return ( word & pmask[0] ) | ( ( word & pmask[1] ) << shift ) | ( ( word & pmask[2] ) >> shift );
|
||||
} );
|
||||
}
|
||||
else if ( var_index1 <= 5 ) /* in this case, var_index2 > 5 */
|
||||
{
|
||||
const auto step = 1 << ( var_index2 - 6 );
|
||||
const auto shift = 1 << var_index1;
|
||||
auto it = std::begin( tt._bits );
|
||||
while ( it != std::end( tt._bits ) )
|
||||
{
|
||||
for ( auto i = decltype( step ){ 0 }; i < step; ++i )
|
||||
{
|
||||
const auto low_to_high = ( *( it + i ) & detail::projections[var_index1] ) >> shift;
|
||||
const auto high_to_low = ( *( it + i + step ) << shift ) & detail::projections[var_index1];
|
||||
*( it + i ) = ( *( it + i ) & ~detail::projections[var_index1] ) | high_to_low;
|
||||
*( it + i + step ) = ( *( it + i + step ) & detail::projections[var_index1] ) | low_to_high;
|
||||
}
|
||||
it += 2 * step;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto step1 = 1 << ( var_index1 - 6 );
|
||||
const auto step2 = 1 << ( var_index2 - 6 );
|
||||
auto it = std::begin( tt._bits );
|
||||
while ( it != std::end( tt._bits ) )
|
||||
{
|
||||
for ( auto i = 0; i < step2; i += 2 * step1 )
|
||||
{
|
||||
for ( auto j = 0; j < step1; ++j )
|
||||
{
|
||||
std::swap( *( it + i + j + step1 ), *( it + i + j + step2 ) );
|
||||
}
|
||||
}
|
||||
it += 2 * step2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<uint32_t NumVars>
|
||||
inline void swap_inplace( static_truth_table<NumVars, true>& tt, uint8_t var_index1, uint8_t var_index2 )
|
||||
{
|
||||
if ( var_index1 == var_index2 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( var_index1 > var_index2 )
|
||||
{
|
||||
std::swap( var_index1, var_index2 );
|
||||
}
|
||||
|
||||
const auto& pmask = detail::ppermutation_masks[var_index1][var_index2];
|
||||
const auto shift = ( 1 << var_index2 ) - ( 1 << var_index1 );
|
||||
tt._bits = ( tt._bits & pmask[0] ) | ( ( tt._bits & pmask[1] ) << shift ) | ( ( tt._bits & pmask[2] ) >> shift );
|
||||
}
|
||||
|
||||
/*! \brief Extends smaller truth table to larger one
|
||||
|
||||
The most significant variables will not be in the functional support of the
|
||||
resulting truth table, but the method is helpful to align a truth table when
|
||||
being used with another one.
|
||||
|
||||
\param tt Larger truth table to create
|
||||
\param from Smaller truth table to copy from
|
||||
*/
|
||||
template<typename TT, typename TTFrom>
|
||||
void extend_to_inplace( TT& tt, const TTFrom& from )
|
||||
{
|
||||
assert( tt.num_vars() >= from.num_vars() );
|
||||
|
||||
if ( from.num_vars() < 6 )
|
||||
{
|
||||
auto mask = *from.begin();
|
||||
|
||||
for ( auto i = from.num_vars(); i < std::min<uint8_t>( 6, tt.num_vars() ); ++i )
|
||||
{
|
||||
mask |= ( mask << ( 1 << i ) );
|
||||
}
|
||||
|
||||
std::fill( tt.begin(), tt.end(), mask );
|
||||
}
|
||||
else
|
||||
{
|
||||
auto it = tt.begin();
|
||||
while ( it != tt.end() )
|
||||
{
|
||||
it = std::copy( from.cbegin(), from.cend(), it );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*! \brief Extends smaller truth table to larger static one
|
||||
|
||||
This is an out-of-place version of `extend_to_inplace` that has the truth
|
||||
table as a return value. It only works for creating static truth tables. The
|
||||
template parameter `NumVars` must be equal or larger to the number of
|
||||
variables in `from`.
|
||||
|
||||
\param from Smaller truth table to copy from
|
||||
*/
|
||||
template<uint32_t NumVars, typename TTFrom>
|
||||
inline static_truth_table<NumVars> extend_to( const TTFrom& from )
|
||||
{
|
||||
static_truth_table<NumVars> tt;
|
||||
extend_to_inplace( tt, from );
|
||||
return tt;
|
||||
}
|
||||
|
||||
/*! \brief Checks whether truth table depends on given variable index
|
||||
|
||||
\param tt Truth table
|
||||
\param var_index Variable index
|
||||
*/
|
||||
template<typename TT>
|
||||
bool has_var( const TT& tt, uint8_t var_index )
|
||||
{
|
||||
assert( var_index < tt.num_vars() );
|
||||
|
||||
if ( tt.num_vars() <= 6 || var_index < 6 )
|
||||
{
|
||||
return std::any_of( std::begin( tt._bits ), std::end( tt._bits ),
|
||||
[var_index]( uint64_t word )
|
||||
{ return ( ( word >> ( uint64_t( 1 ) << var_index ) ) & detail::projections_neg[var_index] ) !=
|
||||
( word & detail::projections_neg[var_index] ); } );
|
||||
}
|
||||
|
||||
const auto step = 1 << ( var_index - 6 );
|
||||
for ( auto i = 0u; i < static_cast<uint32_t>( tt.num_blocks() ); i += 2 * step )
|
||||
{
|
||||
for ( auto j = 0; j < step; ++j )
|
||||
{
|
||||
if ( tt._bits[i + j] != tt._bits[i + j + step] )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*! \brief Checks whether truth table depends on given variable index
|
||||
|
||||
\param tt Truth table
|
||||
\param care Care set
|
||||
\param var_index Variable index
|
||||
*/
|
||||
template<typename TT>
|
||||
bool has_var( const TT& tt, const TT& care, uint8_t var_index )
|
||||
{
|
||||
assert( var_index < tt.num_vars() );
|
||||
assert( tt.num_vars() == care.num_vars() );
|
||||
|
||||
if ( tt.num_vars() <= 6 || var_index < 6 )
|
||||
{
|
||||
auto it_tt = std::begin( tt._bits );
|
||||
auto it_care = std::begin( care._bits );
|
||||
while ( it_tt != std::end( tt._bits ) )
|
||||
{
|
||||
if ( ( ( ( *it_tt >> ( uint64_t( 1 ) << var_index ) ) ^ *it_tt ) & detail::projections_neg[var_index]
|
||||
& ( *it_care >> ( uint64_t( 1 ) << var_index ) ) & *it_care ) != 0 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
++it_tt;
|
||||
++it_care;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto step = 1 << ( var_index - 6 );
|
||||
for ( auto i = 0u; i < static_cast<uint32_t>( tt.num_blocks() ); i += 2 * step )
|
||||
{
|
||||
for ( auto j = 0; j < step; ++j )
|
||||
{
|
||||
if ( ( ( tt._bits[i + j] ^ tt._bits[i + j + step] ) & care._bits[i + j] & care._bits[i + j + step] ) != 0 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*! \brief Shrinks larger truth table to smaller one
|
||||
|
||||
The function expects that the most significant bits, which are cut off, are
|
||||
not in the functional support of the original function. Only then it is
|
||||
ensured that the resulting function is equivalent.
|
||||
|
||||
\param tt Smaller truth table to create
|
||||
\param from Larger truth table to copy from
|
||||
*/
|
||||
template<typename TT, typename TTFrom>
|
||||
void shrink_to_inplace( TT& tt, const TTFrom& from )
|
||||
{
|
||||
assert( tt.num_vars() <= from.num_vars() );
|
||||
|
||||
std::copy( from.begin(), from.begin() + tt.num_blocks(), tt.begin() );
|
||||
|
||||
if ( tt.num_vars() < 6 )
|
||||
{
|
||||
tt.mask_bits();
|
||||
}
|
||||
}
|
||||
|
||||
/*! \brief Shrinks larger truth table to smaller dynamic one
|
||||
|
||||
This is an out-of-place version of `shrink_to` that has the truth table as a
|
||||
return value. It only works for creating dynamic tables. The parameter
|
||||
`num_vars` must be equal or smaller to the number of variables in `from`.
|
||||
|
||||
\param from Smaller truth table to copy from
|
||||
*/
|
||||
template<typename TTFrom>
|
||||
inline dynamic_truth_table shrink_to( const TTFrom& from, unsigned num_vars )
|
||||
{
|
||||
auto tt = create<dynamic_truth_table>( num_vars );
|
||||
shrink_to_inplace( tt, from );
|
||||
return tt;
|
||||
}
|
||||
|
||||
/*! \brief Prints truth table in hexadecimal representation
|
||||
|
||||
The most-significant bit will be the first character of the string.
|
||||
|
||||
\param tt Truth table
|
||||
\param os Output stream
|
||||
*/
|
||||
template<typename TT>
|
||||
void print_hex( const TT& tt, std::ostream& os = std::cout )
|
||||
{
|
||||
auto const chunk_size =
|
||||
std::min<uint64_t>( tt.num_vars() <= 1 ? 1 : ( tt.num_bits() >> 2 ), 16 );
|
||||
|
||||
for_each_block_reversed( tt, [&os, chunk_size]( uint64_t word )
|
||||
{
|
||||
std::string chunk( chunk_size, '0' );
|
||||
|
||||
auto it = chunk.rbegin();
|
||||
while (word && it != chunk.rend()) {
|
||||
auto hex = word & 0xf;
|
||||
if (hex < 10) {
|
||||
*it = '0' + static_cast<char>(hex);
|
||||
} else {
|
||||
*it = 'a' + static_cast<char>(hex - 10);
|
||||
}
|
||||
++it;
|
||||
word >>= 4;
|
||||
}
|
||||
os << chunk; } );
|
||||
}
|
||||
|
||||
} //namespace kitty
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_END
|
||||
|
||||
#endif // _KITTY_OPERATIONS_TT_H_
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
#ifndef _KITTY_OPERATORS_TT_H_
|
||||
#define _KITTY_OPERATORS_TT_H_
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <optional>
|
||||
|
||||
#include "kitty_constants.hpp"
|
||||
#include "kitty_dynamic_tt.hpp"
|
||||
#include "kitty_static_tt.hpp"
|
||||
#include "kitty_operations.hpp"
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
namespace kitty
|
||||
{
|
||||
|
||||
/*! \brief Operator for unary_not */
|
||||
inline dynamic_truth_table operator~( const dynamic_truth_table& tt )
|
||||
{
|
||||
return unary_not( tt );
|
||||
}
|
||||
|
||||
/*! \brief Operator for unary_not */
|
||||
template<uint32_t NumVars>
|
||||
inline static_truth_table<NumVars> operator~( const static_truth_table<NumVars>& tt )
|
||||
{
|
||||
return unary_not( tt );
|
||||
}
|
||||
|
||||
/*! \brief Operator for binary_and */
|
||||
inline dynamic_truth_table operator&( const dynamic_truth_table& first, const dynamic_truth_table& second )
|
||||
{
|
||||
return binary_and( first, second );
|
||||
}
|
||||
|
||||
/*! \brief Operator for binary_and */
|
||||
template<uint32_t NumVars>
|
||||
inline static_truth_table<NumVars> operator&( const static_truth_table<NumVars>& first, const static_truth_table<NumVars>& second )
|
||||
{
|
||||
return binary_and( first, second );
|
||||
}
|
||||
|
||||
/*! \brief Operator for binary_and and assign */
|
||||
inline void operator&=( dynamic_truth_table& first, const dynamic_truth_table& second )
|
||||
{
|
||||
first = binary_and( first, second );
|
||||
}
|
||||
|
||||
/*! \brief Operator for binary_and and assign */
|
||||
template<uint32_t NumVars>
|
||||
inline void operator&=( static_truth_table<NumVars>& first, const static_truth_table<NumVars>& second )
|
||||
{
|
||||
first = binary_and( first, second );
|
||||
}
|
||||
|
||||
/*! \brief Operator for binary_or */
|
||||
inline dynamic_truth_table operator|( const dynamic_truth_table& first, const dynamic_truth_table& second )
|
||||
{
|
||||
return binary_or( first, second );
|
||||
}
|
||||
|
||||
/*! \brief Operator for binary_or */
|
||||
template<uint32_t NumVars>
|
||||
inline static_truth_table<NumVars> operator|( const static_truth_table<NumVars>& first, const static_truth_table<NumVars>& second )
|
||||
{
|
||||
return binary_or( first, second );
|
||||
}
|
||||
|
||||
/*! \brief Operator for binary_or and assign */
|
||||
inline void operator|=( dynamic_truth_table& first, const dynamic_truth_table& second )
|
||||
{
|
||||
first = binary_or( first, second );
|
||||
}
|
||||
|
||||
/*! \brief Operator for binary_or and assign */
|
||||
template<uint32_t NumVars>
|
||||
inline void operator|=( static_truth_table<NumVars, true>& first, const static_truth_table<NumVars, true>& second )
|
||||
{
|
||||
// first = binary_or( first, second );
|
||||
/* runtime improved version */
|
||||
first._bits |= second._bits;
|
||||
first.mask_bits();
|
||||
}
|
||||
|
||||
/*! \brief Operator for binary_or and assign */
|
||||
template<uint32_t NumVars>
|
||||
inline void operator|=( static_truth_table<NumVars, false>& first, const static_truth_table<NumVars, false>& second )
|
||||
{
|
||||
// first = binary_or( first, second );
|
||||
/* runtime improved version */
|
||||
if ( NumVars == 7 )
|
||||
{
|
||||
first._bits[0] |= second._bits[0];
|
||||
first._bits[1] |= second._bits[1];
|
||||
}
|
||||
else if ( NumVars == 8 )
|
||||
{
|
||||
first._bits[0] |= second._bits[0];
|
||||
first._bits[1] |= second._bits[1];
|
||||
first._bits[2] |= second._bits[2];
|
||||
first._bits[3] |= second._bits[3];
|
||||
}
|
||||
else if ( NumVars == 9 )
|
||||
{
|
||||
first._bits[0] |= second._bits[0];
|
||||
first._bits[1] |= second._bits[1];
|
||||
first._bits[2] |= second._bits[2];
|
||||
first._bits[3] |= second._bits[3];
|
||||
first._bits[4] |= second._bits[4];
|
||||
first._bits[5] |= second._bits[5];
|
||||
first._bits[6] |= second._bits[6];
|
||||
first._bits[7] |= second._bits[7];
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( uint32_t i = 0; i < first.num_blocks(); ++i )
|
||||
{
|
||||
first._bits[i] |= second._bits[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace kitty
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_END
|
||||
|
||||
#endif // _KITTY_OPERATORS_TT_H_
|
||||
|
|
@ -0,0 +1,243 @@
|
|||
#ifndef _KITTY_STATIC_TT_H_
|
||||
#define _KITTY_STATIC_TT_H_
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
||||
#include "kitty_constants.hpp"
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
namespace kitty
|
||||
{
|
||||
|
||||
template<uint32_t NumVars, bool = ( NumVars <= 6 )>
|
||||
struct static_truth_table;
|
||||
|
||||
/*! Truth table (for up to 6 variables) in which number of variables is known at compile time.
|
||||
*/
|
||||
template<uint32_t NumVars>
|
||||
struct static_truth_table<NumVars, true>
|
||||
{
|
||||
/*! \cond PRIVATE */
|
||||
enum
|
||||
{
|
||||
NumBits = uint64_t( 1 ) << NumVars
|
||||
};
|
||||
/*! \endcond */
|
||||
|
||||
/*! Constructs a new static truth table instance with the same number of variables. */
|
||||
inline static_truth_table<NumVars> construct() const
|
||||
{
|
||||
return static_truth_table<NumVars>();
|
||||
}
|
||||
|
||||
/*! Returns number of variables.
|
||||
*/
|
||||
inline uint32_t num_vars() const noexcept { return NumVars; }
|
||||
|
||||
/*! Returns number of blocks.
|
||||
*/
|
||||
inline uint32_t num_blocks() const noexcept { return 1u; }
|
||||
|
||||
/*! Returns number of bits.
|
||||
*/
|
||||
inline uint32_t num_bits() const noexcept { return NumBits; }
|
||||
|
||||
/*! \brief Begin iterator to bits.
|
||||
*/
|
||||
inline uint64_t * begin() noexcept { return &_bits; }
|
||||
|
||||
/*! \brief End iterator to bits.
|
||||
*/
|
||||
inline uint64_t * end() noexcept { return ( &_bits ) + 1; }
|
||||
|
||||
/*! \brief Begin iterator to bits.
|
||||
*/
|
||||
inline const uint64_t * begin() const noexcept { return &_bits; }
|
||||
|
||||
/*! \brief End iterator to bits.
|
||||
*/
|
||||
inline const uint64_t * end() const noexcept { return ( &_bits ) + 1; }
|
||||
|
||||
/*! \brief Reverse begin iterator to bits.
|
||||
*/
|
||||
inline uint64_t * rbegin() noexcept { return &_bits; }
|
||||
|
||||
/*! \brief Reverse end iterator to bits.
|
||||
*/
|
||||
inline uint64_t * rend() noexcept { return ( &_bits ) + 1; }
|
||||
|
||||
/*! \brief Constant begin iterator to bits.
|
||||
*/
|
||||
inline const uint64_t * cbegin() const noexcept { return &_bits; }
|
||||
|
||||
/*! \brief Constant end iterator to bits.
|
||||
*/
|
||||
inline const uint64_t * cend() const noexcept { return ( &_bits ) + 1; }
|
||||
|
||||
/*! \brief Constant reverse begin iterator to bits.
|
||||
*/
|
||||
inline const uint64_t * crbegin() const noexcept { return &_bits; }
|
||||
|
||||
/*! \brief Constant everse end iterator to bits.
|
||||
*/
|
||||
inline const uint64_t * crend() const noexcept { return ( &_bits ) + 1; }
|
||||
|
||||
/*! \brief Assign other truth table if number of variables match.
|
||||
|
||||
This replaces the current truth table with another truth table, if `other`
|
||||
has the same number of variables. Otherwise, the truth table is not
|
||||
changed.
|
||||
|
||||
\param other Other truth table
|
||||
*/
|
||||
template<class TT>
|
||||
static_truth_table<NumVars>& operator=( const TT& other )
|
||||
{
|
||||
if ( other.num_vars() == num_vars() )
|
||||
{
|
||||
std::copy( other.begin(), other.end(), begin() );
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*! Masks the number of valid truth table bits.
|
||||
|
||||
If the truth table has less than 6 variables, it may not use all
|
||||
the bits. This operation makes sure to zero out all non-valid
|
||||
bits.
|
||||
*/
|
||||
inline void mask_bits() noexcept { _bits &= detail::masks[NumVars]; }
|
||||
|
||||
/*! \cond PRIVATE */
|
||||
public: /* fields */
|
||||
uint64_t _bits = 0;
|
||||
/*! \endcond */
|
||||
};
|
||||
|
||||
/*! Truth table (more than 6 variables) in which number of variables is known at compile time.
|
||||
*/
|
||||
template<uint32_t NumVars>
|
||||
struct static_truth_table<NumVars, false>
|
||||
{
|
||||
/*! \cond PRIVATE */
|
||||
enum
|
||||
{
|
||||
NumBlocks = ( NumVars <= 6 ) ? 1u : ( 1u << ( NumVars - 6 ) )
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
NumBits = uint64_t( 1 ) << NumVars
|
||||
};
|
||||
/*! \endcond */
|
||||
|
||||
/*! Standard constructor.
|
||||
|
||||
The number of variables provided to the truth table must be known
|
||||
at runtime. The number of blocks will be computed as a compile
|
||||
time constant.
|
||||
*/
|
||||
static_truth_table()
|
||||
{
|
||||
_bits.fill( 0 );
|
||||
}
|
||||
|
||||
/*! Constructs a new static truth table instance with the same number of variables. */
|
||||
inline static_truth_table<NumVars> construct() const
|
||||
{
|
||||
return static_truth_table<NumVars>();
|
||||
}
|
||||
|
||||
/*! Returns number of variables.
|
||||
*/
|
||||
inline uint32_t num_vars() const noexcept { return NumVars; }
|
||||
|
||||
/*! Returns number of blocks.
|
||||
*/
|
||||
inline uint32_t num_blocks() const noexcept { return NumBlocks; }
|
||||
|
||||
/*! Returns number of bits.
|
||||
*/
|
||||
inline uint32_t num_bits() const noexcept { return NumBits; }
|
||||
|
||||
/*! \brief Begin iterator to bits.
|
||||
*/
|
||||
inline typename std::array<uint64_t, NumBlocks>::iterator begin() noexcept { return _bits.begin(); }
|
||||
|
||||
/*! \brief End iterator to bits.
|
||||
*/
|
||||
inline typename std::array<uint64_t, NumBlocks>::iterator end() noexcept { return _bits.end(); }
|
||||
|
||||
/*! \brief Begin iterator to bits.
|
||||
*/
|
||||
inline typename std::array<uint64_t, NumBlocks>::const_iterator begin() const noexcept { return _bits.begin(); }
|
||||
|
||||
/*! \brief End iterator to bits.
|
||||
*/
|
||||
inline typename std::array<uint64_t, NumBlocks>::const_iterator end() const noexcept { return _bits.end(); }
|
||||
|
||||
/*! \brief Reverse begin iterator to bits.
|
||||
*/
|
||||
inline typename std::array<uint64_t, NumBlocks>::reverse_iterator rbegin() noexcept { return _bits.rbegin(); }
|
||||
|
||||
/*! \brief Reverse end iterator to bits.
|
||||
*/
|
||||
inline typename std::array<uint64_t, NumBlocks>::reverse_iterator rend() noexcept { return _bits.rend(); }
|
||||
|
||||
/*! \brief Constant begin iterator to bits.
|
||||
*/
|
||||
inline typename std::array<uint64_t, NumBlocks>::const_iterator cbegin() const noexcept { return _bits.cbegin(); }
|
||||
|
||||
/*! \brief Constant end iterator to bits.
|
||||
*/
|
||||
inline typename std::array<uint64_t, NumBlocks>::const_iterator cend() const noexcept { return _bits.cend(); }
|
||||
|
||||
/*! \brief Constant reverse begin iterator to bits.
|
||||
*/
|
||||
inline typename std::array<uint64_t, NumBlocks>::const_reverse_iterator crbegin() const noexcept { return _bits.crbegin(); }
|
||||
|
||||
/*! \brief Constant teverse end iterator to bits.
|
||||
*/
|
||||
inline typename std::array<uint64_t, NumBlocks>::const_reverse_iterator crend() const noexcept { return _bits.crend(); }
|
||||
|
||||
/*! \brief Assign other truth table if number of variables match.
|
||||
|
||||
This replaces the current truth table with another truth table, if `other`
|
||||
has the same number of variables. Otherwise, the truth table is not
|
||||
changed.
|
||||
|
||||
\param other Other truth table
|
||||
*/
|
||||
template<class TT>
|
||||
static_truth_table<NumVars>& operator=( const TT& other )
|
||||
{
|
||||
if ( other.num_bits() == num_bits() )
|
||||
{
|
||||
std::copy( other.begin(), other.end(), begin() );
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*! Masks the number of valid truth table bits.
|
||||
|
||||
We know that we will have at least 7 variables in this data
|
||||
structure.
|
||||
*/
|
||||
inline void mask_bits() noexcept {}
|
||||
|
||||
/*! \cond PRIVATE */
|
||||
public: /* fields */
|
||||
std::array<uint64_t, NumBlocks> _bits;
|
||||
/*! \endcond */
|
||||
};
|
||||
|
||||
} //namespace kitty
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_END
|
||||
|
||||
#endif // _KITTY_STATIC_TT_H_
|
||||
|
|
@ -0,0 +1 @@
|
|||
SRC += src/map/if/acd/ac_wrapper.cpp
|
||||
|
|
@ -40,6 +40,7 @@
|
|||
#include "opt/dau/dau.h"
|
||||
#include "misc/vec/vecHash.h"
|
||||
#include "misc/vec/vecWec.h"
|
||||
#include "map/if/acd/ac_wrapper.h"
|
||||
|
||||
ABC_NAMESPACE_HEADER_START
|
||||
|
||||
|
|
@ -112,6 +113,7 @@ struct If_Par_t_
|
|||
int nStructType; // type of the structure
|
||||
int nAndDelay; // delay of AND-gate in LUT library units
|
||||
int nAndArea; // area of AND-gate in LUT library units
|
||||
int nLutDecSize; // the LUT size for decomposition
|
||||
int fPreprocess; // preprossing
|
||||
int fArea; // area-oriented mapping
|
||||
int fFancy; // a fancy feature
|
||||
|
|
@ -145,9 +147,12 @@ struct If_Par_t_
|
|||
int fDeriveLuts; // enables deriving LUT structures
|
||||
int fDoAverage; // optimize average rather than maximum level
|
||||
int fHashMapping; // perform AIG hashing after mapping
|
||||
int fUserLutDec; // perform Boolean decomposition during mapping
|
||||
int fUserLut2D; // perform Boolean decomposition during mapping
|
||||
int fVerbose; // the verbosity flag
|
||||
int fVerboseTrace; // the verbosity flag
|
||||
char * pLutStruct; // LUT structure
|
||||
int fEnableStructN;// LUT structure using a new method
|
||||
float WireDelay; // wire delay
|
||||
// internal parameters
|
||||
int fSkipCutFilter;// skip cut filter
|
||||
|
|
@ -309,6 +314,7 @@ struct If_Cut_t_
|
|||
unsigned fAndCut : 1; // matched with AND gate
|
||||
unsigned nLimit : 8; // the maximum number of leaves
|
||||
unsigned nLeaves : 8; // the number of leaves
|
||||
unsigned decDelay: 16; // pin-to-pin decomposition delay
|
||||
int pLeaves[0];
|
||||
};
|
||||
|
||||
|
|
@ -547,10 +553,12 @@ extern int If_CutPerformCheck07( If_Man_t * p, unsigned * pTruth, in
|
|||
extern int If_CutPerformCheck08( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr );
|
||||
extern int If_CutPerformCheck10( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr );
|
||||
extern int If_CutPerformCheck16( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr );
|
||||
extern int If_CutPerformCheckXX( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr );
|
||||
extern int If_CutPerformCheck45( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr );
|
||||
extern int If_CutPerformCheck54( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr );
|
||||
extern int If_CutPerformCheck75( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr );
|
||||
extern float If_CutDelayLutStruct( If_Man_t * p, If_Cut_t * pCut, char * pStr, float WireDelay );
|
||||
// extern int If_CutPerformAcd( If_Man_t * p, unsigned nVars, int lutSize, unsigned * pdelay, int use_late_arrival, unsigned * cost );
|
||||
extern int If_CluCheckExt( void * p, word * pTruth, int nVars, int nLutLeaf, int nLutRoot,
|
||||
char * pLut0, char * pLut1, word * pFunc0, word * pFunc1 );
|
||||
extern int If_CluCheckExt3( void * p, word * pTruth, int nVars, int nLutLeaf, int nLutLeaf2, int nLutRoot,
|
||||
|
|
@ -565,6 +573,10 @@ extern int If_CutSopBalancePinDelaysInt( Vec_Int_t * vCover, int * p
|
|||
extern int If_CutSopBalancePinDelays( If_Man_t * p, If_Cut_t * pCut, char * pPerm );
|
||||
extern int If_CutLutBalanceEval( If_Man_t * p, If_Cut_t * pCut );
|
||||
extern int If_CutLutBalancePinDelays( If_Man_t * p, If_Cut_t * pCut, char * pPerm );
|
||||
extern int If_LutDecEval( If_Man_t * p, If_Cut_t * pCut, If_Obj_t * pObj, int optDelay, int fFirst );
|
||||
extern int If_Lut2DecEval( If_Man_t * p, If_Cut_t * pCut, If_Obj_t * pObj, int optDelay, int fFirst );
|
||||
extern int If_LutDecReEval( If_Man_t * p, If_Cut_t * pCut );
|
||||
extern float If_LutDecPinRequired( If_Man_t * p, If_Cut_t * pCut, int i, float required );
|
||||
/*=== ifDsd.c =============================================================*/
|
||||
extern If_DsdMan_t * If_DsdManAlloc( int nVars, int nLutSize );
|
||||
extern void If_DsdManAllocIsops( If_DsdMan_t * p, int nLutSize );
|
||||
|
|
@ -692,6 +704,10 @@ extern int If_ManCountSpecialPos( If_Man_t * p );
|
|||
extern void If_CutTraverse( If_Man_t * p, If_Obj_t * pRoot, If_Cut_t * pCut, Vec_Ptr_t * vNodes );
|
||||
extern void If_ObjPrint( If_Obj_t * pObj );
|
||||
|
||||
extern int acd_evaluate( word * pTruth, unsigned nVars, int lutSize, unsigned *pdelay, unsigned *cost, int try_no_late_arrival );
|
||||
extern int acd_decompose( word * pTruth, unsigned nVars, int lutSize, unsigned *pdelay, unsigned char *decomposition );
|
||||
extern int acd2_evaluate( word * pTruth, unsigned nVars, int lutSize, unsigned *pdelay, unsigned *cost, int try_no_late_arrival );
|
||||
extern int acd2_decompose( word * pTruth, unsigned nVars, int lutSize, unsigned *pdelay, unsigned char *decomposition );
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
||||
|
|
|
|||
|
|
@ -62,6 +62,8 @@ void If_ManSetDefaultPars( If_Par_t * pPars )
|
|||
pPars->fPower = 0;
|
||||
pPars->fCutMin = 0;
|
||||
pPars->fBidec = 0;
|
||||
pPars->fUserLutDec = 0;
|
||||
pPars->fUserLut2D = 0;
|
||||
pPars->fVerbose = 0;
|
||||
}
|
||||
|
||||
|
|
@ -106,6 +108,7 @@ int If_ManPerformMappingComb( If_Man_t * p )
|
|||
If_Obj_t * pObj;
|
||||
abctime clkTotal = Abc_Clock();
|
||||
int i;
|
||||
|
||||
//p->vVisited2 = Vec_IntAlloc( 100 );
|
||||
//p->vMarks = Vec_StrStart( If_ManObjNum(p) );
|
||||
|
||||
|
|
@ -121,6 +124,7 @@ int If_ManPerformMappingComb( If_Man_t * p )
|
|||
{
|
||||
// map for delay
|
||||
If_ManPerformMappingRound( p, p->pPars->nCutsMax, 0, 1, 1, "Delay" );
|
||||
|
||||
// map for delay second option
|
||||
p->pPars->fFancy = 1;
|
||||
If_ManResetOriginalRefs( p );
|
||||
|
|
|
|||
|
|
@ -604,10 +604,6 @@ static inline int If_ManSortCompare( If_Man_t * p, If_Cut_t * pC0, If_Cut_t * pC
|
|||
return -1;
|
||||
if ( pC0->nLeaves > pC1->nLeaves )
|
||||
return 1;
|
||||
if ( pC0->Delay < pC1->Delay - p->fEpsilon )
|
||||
return -1;
|
||||
if ( pC0->Delay > pC1->Delay + p->fEpsilon )
|
||||
return 1;
|
||||
if ( pC0->fUseless < pC1->fUseless )
|
||||
return -1;
|
||||
if ( pC0->fUseless > pC1->fUseless )
|
||||
|
|
@ -765,7 +761,7 @@ void If_CutSort( If_Man_t * p, If_Set_t * pCutSet, If_Cut_t * pCut )
|
|||
|
||||
if ( !pCut->fUseless &&
|
||||
(p->pPars->fUseDsd || p->pPars->pFuncCell2 || p->pPars->fUseBat ||
|
||||
p->pPars->pLutStruct || p->pPars->fUserRecLib || p->pPars->fUserSesLib ||
|
||||
p->pPars->pLutStruct || p->pPars->fUserRecLib || p->pPars->fUserSesLib || p->pPars->fUserLutDec || p->pPars->fUserLut2D ||
|
||||
p->pPars->fEnableCheck07 || p->pPars->fUseCofVars || p->pPars->fUseAndVars || p->pPars->fUse34Spec ||
|
||||
p->pPars->fUseDsdTune || p->pPars->fEnableCheck75 || p->pPars->fEnableCheck75u || p->pPars->fUseCheck1 || p->pPars->fUseCheck2) )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,335 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [ifDec66.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [FPGA mapping based on priority cuts.]
|
||||
|
||||
Synopsis [Fast checking procedures.]
|
||||
|
||||
Author [Alessandro Tempia Calvino]
|
||||
|
||||
Affiliation [EPFL]
|
||||
|
||||
Date [Ver. 1.0. Started - Feb 8, 2024.]
|
||||
|
||||
Revision [$Id: ifDec66.c,v 1.00 2008/02/08 00:00:00 tempia Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "if.h"
|
||||
#include "bool/kit/kit.h"
|
||||
#include "misc/vec/vecMem.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
#define CLU_VAR_MAX 11
|
||||
#define CLU_MEM_MAX 1000 // 1 GB
|
||||
#define CLU_UNUSED 0xff
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// decomposition
|
||||
typedef struct If_Grp_t_ If_Grp_t;
|
||||
struct If_Grp_t_
|
||||
{
|
||||
char nVars;
|
||||
char nMyu;
|
||||
char pVars[CLU_VAR_MAX];
|
||||
};
|
||||
|
||||
// hash table entry
|
||||
typedef struct If_Hte_t_ If_Hte_t;
|
||||
struct If_Hte_t_
|
||||
{
|
||||
If_Hte_t * pNext;
|
||||
unsigned Group;
|
||||
unsigned Counter;
|
||||
word pTruth[1];
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline unsigned If_CluGrp2Uns2( If_Grp_t * pG )
|
||||
{
|
||||
char * pChar = (char *)pG;
|
||||
unsigned Res = 0;
|
||||
int i;
|
||||
for ( i = 0; i < 8; i++ )
|
||||
Res |= ((pChar[i] & 15) << (i << 2));
|
||||
return Res;
|
||||
}
|
||||
|
||||
static inline void If_CluUns2Grp2( unsigned Group, If_Grp_t * pG )
|
||||
{
|
||||
char * pChar = (char *)pG;
|
||||
int i;
|
||||
for ( i = 0; i < 8; i++ )
|
||||
pChar[i] = ((Group >> (i << 2)) & 15);
|
||||
}
|
||||
|
||||
unsigned int If_CluPrimeCudd2( unsigned int p )
|
||||
{
|
||||
int i,pn;
|
||||
|
||||
p--;
|
||||
do {
|
||||
p++;
|
||||
if (p&1) {
|
||||
pn = 1;
|
||||
i = 3;
|
||||
while ((unsigned) (i * i) <= p) {
|
||||
if (p % i == 0) {
|
||||
pn = 0;
|
||||
break;
|
||||
}
|
||||
i += 2;
|
||||
}
|
||||
} else {
|
||||
pn = 0;
|
||||
}
|
||||
} while (!pn);
|
||||
return(p);
|
||||
|
||||
} /* end of Cudd_Prime */
|
||||
|
||||
// hash table
|
||||
static inline int If_CluWordNum2( int nVars )
|
||||
{
|
||||
return nVars <= 6 ? 1 : 1 << (nVars-6);
|
||||
}
|
||||
|
||||
int If_CluHashFindMedian2( If_Man_t * p, int t )
|
||||
{
|
||||
If_Hte_t * pEntry;
|
||||
Vec_Int_t * vCounters;
|
||||
int i, Max = 0, Total = 0, Half = 0;
|
||||
vCounters = Vec_IntStart( 1000 );
|
||||
for ( i = 0; i < p->nTableSize[t]; i++ )
|
||||
{
|
||||
for ( pEntry = ((If_Hte_t **)p->pHashTable[t])[i]; pEntry; pEntry = pEntry->pNext )
|
||||
{
|
||||
if ( Max < (int)pEntry->Counter )
|
||||
{
|
||||
Max = pEntry->Counter;
|
||||
Vec_IntSetEntry( vCounters, pEntry->Counter, 0 );
|
||||
}
|
||||
Vec_IntAddToEntry( vCounters, pEntry->Counter, 1 );
|
||||
Total++;
|
||||
}
|
||||
}
|
||||
for ( i = Max; i > 0; i-- )
|
||||
{
|
||||
Half += Vec_IntEntry( vCounters, i );
|
||||
if ( Half > Total/2 )
|
||||
break;
|
||||
}
|
||||
/*
|
||||
printf( "total = %d ", Total );
|
||||
printf( "half = %d ", Half );
|
||||
printf( "i = %d ", i );
|
||||
printf( "Max = %d.\n", Max );
|
||||
*/
|
||||
Vec_IntFree( vCounters );
|
||||
return Abc_MaxInt( i, 1 );
|
||||
}
|
||||
|
||||
int If_CluHashKey2( word * pTruth, int nWords, int Size )
|
||||
{
|
||||
static unsigned BigPrimes[8] = {12582917, 25165843, 50331653, 100663319, 201326611, 402653189, 805306457, 1610612741};
|
||||
unsigned Value = 0;
|
||||
int i;
|
||||
if ( nWords < 4 )
|
||||
{
|
||||
unsigned char * s = (unsigned char *)pTruth;
|
||||
for ( i = 0; i < 8 * nWords; i++ )
|
||||
Value ^= BigPrimes[i % 7] * s[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned * s = (unsigned *)pTruth;
|
||||
for ( i = 0; i < 2 * nWords; i++ )
|
||||
Value ^= BigPrimes[i % 7] * s[i];
|
||||
}
|
||||
return Value % Size;
|
||||
}
|
||||
|
||||
unsigned * If_CluHashLookup2( If_Man_t * p, word * pTruth, int t )
|
||||
{
|
||||
If_Hte_t * pEntry, * pPrev;
|
||||
int nWords, HashKey;
|
||||
if ( p == NULL )
|
||||
return NULL;
|
||||
nWords = If_CluWordNum2(p->pPars->nLutSize);
|
||||
if ( p->pMemEntries == NULL )
|
||||
p->pMemEntries = Mem_FixedStart( sizeof(If_Hte_t) + sizeof(word) * (If_CluWordNum2(p->pPars->nLutSize) - 1) );
|
||||
if ( p->pHashTable[t] == NULL )
|
||||
{
|
||||
// decide how large should be the table
|
||||
int nEntriesMax1 = 4 * If_CluPrimeCudd2( Vec_PtrSize(p->vObjs) * p->pPars->nCutsMax );
|
||||
int nEntriesMax2 = (int)(((double)CLU_MEM_MAX * (1 << 20)) / If_CluWordNum2(p->pPars->nLutSize) / 8);
|
||||
// int nEntriesMax2 = 10000;
|
||||
// create table
|
||||
p->nTableSize[t] = If_CluPrimeCudd2( Abc_MinInt(nEntriesMax1, nEntriesMax2)/2 );
|
||||
p->pHashTable[t] = ABC_CALLOC( void *, p->nTableSize[t] );
|
||||
}
|
||||
// check if this entry exists
|
||||
HashKey = If_CluHashKey2( pTruth, nWords, p->nTableSize[t] );
|
||||
for ( pEntry = ((If_Hte_t **)p->pHashTable[t])[HashKey]; pEntry; pEntry = pEntry->pNext )
|
||||
if ( memcmp(pEntry->pTruth, pTruth, sizeof(word) * nWords) == 0 )
|
||||
{
|
||||
pEntry->Counter++;
|
||||
return &pEntry->Group;
|
||||
}
|
||||
// resize the hash table
|
||||
if ( p->nTableEntries[t] >= 2 * p->nTableSize[t] )
|
||||
{
|
||||
// collect useful entries
|
||||
If_Hte_t * pPrev;
|
||||
Vec_Ptr_t * vUseful = Vec_PtrAlloc( p->nTableEntries[t] );
|
||||
int i, Median = If_CluHashFindMedian2( p, t );
|
||||
for ( i = 0; i < p->nTableSize[t]; i++ )
|
||||
{
|
||||
for ( pEntry = ((If_Hte_t **)p->pHashTable[t])[i]; pEntry; )
|
||||
{
|
||||
if ( (int)pEntry->Counter > Median )
|
||||
{
|
||||
Vec_PtrPush( vUseful, pEntry );
|
||||
pEntry = pEntry->pNext;
|
||||
}
|
||||
else
|
||||
{
|
||||
pPrev = pEntry->pNext;
|
||||
Mem_FixedEntryRecycle( p->pMemEntries, (char *)pEntry );
|
||||
pEntry = pPrev;
|
||||
}
|
||||
}
|
||||
}
|
||||
// add useful entries
|
||||
memset( p->pHashTable[t], 0, sizeof(void *) * p->nTableSize[t] );
|
||||
Vec_PtrForEachEntry( If_Hte_t *, vUseful, pEntry, i )
|
||||
{
|
||||
HashKey = If_CluHashKey2( pEntry->pTruth, nWords, p->nTableSize[t] );
|
||||
pPrev = ((If_Hte_t **)p->pHashTable[t])[HashKey];
|
||||
if ( pPrev == NULL || pEntry->Counter >= pPrev->Counter )
|
||||
{
|
||||
pEntry->pNext = pPrev;
|
||||
((If_Hte_t **)p->pHashTable[t])[HashKey] = pEntry;
|
||||
}
|
||||
else
|
||||
{
|
||||
while ( pPrev->pNext && pEntry->Counter < pPrev->pNext->Counter )
|
||||
pPrev = pPrev->pNext;
|
||||
pEntry->pNext = pPrev->pNext;
|
||||
pPrev->pNext = pEntry;
|
||||
}
|
||||
}
|
||||
p->nTableEntries[t] = Vec_PtrSize( vUseful );
|
||||
Vec_PtrFree( vUseful );
|
||||
}
|
||||
// create entry
|
||||
p->nTableEntries[t]++;
|
||||
pEntry = (If_Hte_t *)Mem_FixedEntryFetch( p->pMemEntries );
|
||||
memcpy( pEntry->pTruth, pTruth, sizeof(word) * nWords );
|
||||
pEntry->Group = CLU_UNUSED;
|
||||
pEntry->Counter = 1;
|
||||
// insert at the beginning
|
||||
// pEntry->pNext = ((If_Hte_t **)p->pHashTable[t])[HashKey];
|
||||
// ((If_Hte_t **)p->pHashTable[t])[HashKey] = pEntry;
|
||||
// insert at the end
|
||||
pEntry->pNext = NULL;
|
||||
for ( pPrev = ((If_Hte_t **)p->pHashTable[t])[HashKey]; pPrev && pPrev->pNext; pPrev = pPrev->pNext );
|
||||
if ( pPrev == NULL )
|
||||
((If_Hte_t **)p->pHashTable[t])[HashKey] = pEntry;
|
||||
else
|
||||
pPrev->pNext = pEntry;
|
||||
return &pEntry->Group;
|
||||
}
|
||||
|
||||
// returns if successful
|
||||
int If_CluCheckXX( If_Man_t * p, word * pTruth0, int lutSize, int nVars, int fHashing )
|
||||
{
|
||||
If_Grp_t G1 = {0};
|
||||
unsigned * pHashed = NULL;
|
||||
|
||||
if ( p && fHashing )
|
||||
{
|
||||
pHashed = If_CluHashLookup2( p, pTruth0, 0 );
|
||||
if ( pHashed && *pHashed != CLU_UNUSED )
|
||||
If_CluUns2Grp2( *pHashed, &G1 );
|
||||
}
|
||||
|
||||
/* new entry */
|
||||
if ( G1.nVars == 0 )
|
||||
{
|
||||
G1.nVars = acdXX_decompose( pTruth0, lutSize, nVars, NULL );
|
||||
}
|
||||
|
||||
if ( pHashed )
|
||||
*pHashed = If_CluGrp2Uns2( &G1 );
|
||||
|
||||
return G1.nVars;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs ACD into 66 cascade.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int If_CutPerformCheckXX( If_Man_t * p, unsigned * pTruth0, int nVars, int nLeaves, char * pStr )
|
||||
{
|
||||
unsigned pTruth[IF_MAX_FUNC_LUTSIZE > 5 ? 1 << (IF_MAX_FUNC_LUTSIZE - 5) : 1];
|
||||
int Length;
|
||||
// stretch the truth table
|
||||
memcpy( pTruth, pTruth0, sizeof(word) * Abc_TtWordNum(nVars) );
|
||||
Abc_TtStretch6( (word *)pTruth, nLeaves, p->pPars->nLutSize );
|
||||
|
||||
// if cutmin is disabled, minimize the function
|
||||
if ( !p->pPars->fCutMin )
|
||||
nLeaves = Abc_TtMinBase( (word *)pTruth, NULL, nLeaves, nVars );
|
||||
|
||||
// quit if parameters are wrong
|
||||
Length = strlen(pStr);
|
||||
if ( Length != 2 )
|
||||
{
|
||||
printf( "Wrong LUT struct (%s)\n", pStr );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lutSize = pStr[0] - '0';
|
||||
if ( lutSize < 3 || lutSize > 6 )
|
||||
{
|
||||
printf( "The LUT size (%d) should belong to {3,4,5,6}.\n", lutSize );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( nLeaves >= 2 * lutSize )
|
||||
{
|
||||
printf( "The cut size (%d) is too large for the LUT structure %s.\n", nLeaves, pStr );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// consider trivial case
|
||||
if ( nLeaves <= lutSize )
|
||||
return 1;
|
||||
|
||||
return If_CluCheckXX(p, (word*)pTruth, lutSize, nVars, 1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
|
@ -411,6 +411,233 @@ int If_CutLutBalanceEval( If_Man_t * p, If_Cut_t * pCut )
|
|||
return DelayMax + 2;
|
||||
}
|
||||
}
|
||||
|
||||
int If_LutDecEval( If_Man_t * p, If_Cut_t * pCut, If_Obj_t * pObj, int optDelay, int fFirst )
|
||||
{
|
||||
pCut->fUser = 1;
|
||||
pCut->Cost = pCut->nLeaves > 1 ? 1 : 0;
|
||||
pCut->decDelay = 0;
|
||||
if ( pCut->nLeaves == 0 ) // const
|
||||
{
|
||||
assert( Abc_Lit2Var(If_CutTruthLit(pCut)) == 0 );
|
||||
return 0;
|
||||
}
|
||||
if ( pCut->nLeaves == 1 ) // variable
|
||||
{
|
||||
assert( Abc_Lit2Var(If_CutTruthLit(pCut)) == 1 );
|
||||
return (int)If_ObjCutBest(If_CutLeaf(p, pCut, 0))->Delay;
|
||||
}
|
||||
|
||||
int LutSize = p->pPars->nLutDecSize;
|
||||
int i, leaf_delay;
|
||||
int DelayMax = -1, nLeafMax = 0;
|
||||
unsigned uLeafMask = 0;
|
||||
for ( i = 0; i < If_CutLeaveNum(pCut); i++ )
|
||||
{
|
||||
leaf_delay = If_ObjCutBest(If_CutLeaf(p, pCut, i))->Delay;
|
||||
|
||||
if ( DelayMax < leaf_delay )
|
||||
{
|
||||
DelayMax = leaf_delay;
|
||||
nLeafMax = 1;
|
||||
uLeafMask = (1 << i);
|
||||
}
|
||||
else if ( DelayMax == leaf_delay )
|
||||
{
|
||||
nLeafMax++;
|
||||
uLeafMask |= (1 << i);
|
||||
}
|
||||
}
|
||||
if ( If_CutLeaveNum(pCut) <= LutSize )
|
||||
{
|
||||
pCut->decDelay = ( 1 << LutSize ) - 1;
|
||||
return DelayMax + 1;
|
||||
}
|
||||
|
||||
/* compute the decomposition */
|
||||
int use_late_arrival = 0;
|
||||
unsigned cost = 1;
|
||||
|
||||
if ( !fFirst )
|
||||
{
|
||||
if ( optDelay )
|
||||
{
|
||||
/* checks based on delay: must be better than the previous best cut */
|
||||
use_late_arrival = DelayMax + 2 >= If_ObjCutBest(pObj)->Delay;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* checks based on delay: look at the required time */
|
||||
use_late_arrival = DelayMax + 2 > pObj->Required + p->fEpsilon;
|
||||
}
|
||||
}
|
||||
|
||||
/* Too many late-arriving signals */
|
||||
if ( nLeafMax == LutSize )
|
||||
{
|
||||
if ( use_late_arrival )
|
||||
{
|
||||
/* unfeasible decomposition */
|
||||
pCut->Cost = IF_COST_MAX;
|
||||
return ABC_INFINITY;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* remove critical signals as not needed */
|
||||
uLeafMask = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* returns the delay of the decomposition */
|
||||
word *pTruth = If_CutTruthW( p, pCut );
|
||||
int val = acd_evaluate( pTruth, pCut->nLeaves, LutSize, &uLeafMask, &cost, !use_late_arrival );
|
||||
|
||||
/* not feasible decomposition */
|
||||
pCut->decDelay = uLeafMask;
|
||||
if ( val < 0 )
|
||||
{
|
||||
pCut->Cost = IF_COST_MAX;
|
||||
return ABC_INFINITY;
|
||||
}
|
||||
|
||||
pCut->Cost = cost;
|
||||
|
||||
return DelayMax + val;
|
||||
}
|
||||
|
||||
int If_Lut2DecEval( If_Man_t * p, If_Cut_t * pCut, If_Obj_t * pObj, int optDelay, int fFirst )
|
||||
{
|
||||
pCut->fUser = 1;
|
||||
pCut->Cost = pCut->nLeaves > 1 ? 1 : 0;
|
||||
pCut->decDelay = 0;
|
||||
if ( pCut->nLeaves == 0 ) // const
|
||||
{
|
||||
assert( Abc_Lit2Var(If_CutTruthLit(pCut)) == 0 );
|
||||
return 0;
|
||||
}
|
||||
if ( pCut->nLeaves == 1 ) // variable
|
||||
{
|
||||
assert( Abc_Lit2Var(If_CutTruthLit(pCut)) == 1 );
|
||||
return (int)If_ObjCutBest(If_CutLeaf(p, pCut, 0))->Delay;
|
||||
}
|
||||
|
||||
int LutSize = p->pPars->nLutDecSize;
|
||||
int i, leaf_delay;
|
||||
int DelayMax = -1, nLeafMax = 0;
|
||||
unsigned uLeafMask = 0;
|
||||
for ( i = 0; i < If_CutLeaveNum(pCut); i++ )
|
||||
{
|
||||
leaf_delay = If_ObjCutBest(If_CutLeaf(p, pCut, i))->Delay;
|
||||
|
||||
if ( DelayMax < leaf_delay )
|
||||
{
|
||||
DelayMax = leaf_delay;
|
||||
nLeafMax = 1;
|
||||
uLeafMask = (1 << i);
|
||||
}
|
||||
else if ( DelayMax == leaf_delay )
|
||||
{
|
||||
nLeafMax++;
|
||||
uLeafMask |= (1 << i);
|
||||
}
|
||||
}
|
||||
if ( If_CutLeaveNum(pCut) <= LutSize )
|
||||
{
|
||||
pCut->decDelay = ( 1 << LutSize ) - 1;
|
||||
return DelayMax + 1;
|
||||
}
|
||||
|
||||
/* compute the decomposition */
|
||||
int use_late_arrival = 0;
|
||||
unsigned cost = 1;
|
||||
|
||||
if ( !fFirst )
|
||||
{
|
||||
if ( optDelay )
|
||||
{
|
||||
/* checks based on delay: must be better than the previous best cut */
|
||||
use_late_arrival = DelayMax + 2 >= If_ObjCutBest(pObj)->Delay;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* checks based on delay: look at the required time */
|
||||
use_late_arrival = DelayMax + 2 > pObj->Required + p->fEpsilon;
|
||||
}
|
||||
}
|
||||
|
||||
/* Too many late-arriving signals */
|
||||
if ( nLeafMax == LutSize && use_late_arrival )
|
||||
{
|
||||
/* unfeasible decomposition */
|
||||
pCut->Cost = IF_COST_MAX;
|
||||
return ABC_INFINITY;
|
||||
}
|
||||
|
||||
if ( !use_late_arrival )
|
||||
{
|
||||
uLeafMask = 0;
|
||||
}
|
||||
|
||||
/* returns the delay of the decomposition */
|
||||
word *pTruth = If_CutTruthW( p, pCut );
|
||||
int val = acd2_evaluate( pTruth, pCut->nLeaves, LutSize, &uLeafMask, &cost, !use_late_arrival );
|
||||
|
||||
/* not feasible decomposition */
|
||||
pCut->decDelay = uLeafMask;
|
||||
if ( val < 0 )
|
||||
{
|
||||
pCut->Cost = IF_COST_MAX;
|
||||
return ABC_INFINITY;
|
||||
}
|
||||
|
||||
pCut->Cost = 2;
|
||||
return DelayMax + val;
|
||||
}
|
||||
|
||||
int If_LutDecReEval( If_Man_t * p, If_Cut_t * pCut )
|
||||
{
|
||||
// pCut->fUser = 1;
|
||||
|
||||
if ( pCut->nLeaves == 0 ) // const
|
||||
{
|
||||
assert( Abc_Lit2Var(If_CutTruthLit(pCut)) == 0 );
|
||||
return 0;
|
||||
}
|
||||
if ( pCut->nLeaves == 1 ) // variable
|
||||
{
|
||||
assert( Abc_Lit2Var(If_CutTruthLit(pCut)) == 1 );
|
||||
return (int)If_ObjCutBest(If_CutLeaf(p, pCut, 0))->Delay;
|
||||
}
|
||||
|
||||
// int LutSize = p->pPars->pLutStruct[0] - '0';
|
||||
int i, leaf_delay;
|
||||
int DelayMax = -1;
|
||||
for ( i = 0; i < If_CutLeaveNum(pCut); i++ )
|
||||
{
|
||||
leaf_delay = If_ObjCutBest(If_CutLeaf(p, pCut, i))->Delay;
|
||||
leaf_delay += ( ( pCut->decDelay >> i ) & 1 ) == 0 ? 2 : 1;
|
||||
DelayMax = Abc_MaxInt( leaf_delay, DelayMax );
|
||||
}
|
||||
|
||||
return DelayMax;
|
||||
}
|
||||
|
||||
float If_LutDecPinRequired( If_Man_t * p, If_Cut_t * pCut, int i, float required )
|
||||
{
|
||||
if ( pCut->nLeaves == 0 ) // const
|
||||
{
|
||||
assert( Abc_Lit2Var(If_CutTruthLit(pCut)) == 0 );
|
||||
return required;
|
||||
}
|
||||
if ( pCut->nLeaves == 1 ) // variable
|
||||
{
|
||||
assert( Abc_Lit2Var(If_CutTruthLit(pCut)) == 1 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ( ( pCut->decDelay >> i ) & 1 ) == 0 ? 2 : 1;
|
||||
}
|
||||
|
||||
/*
|
||||
int If_CutLutBalanceEval( If_Man_t * p, If_Cut_t * pCut )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ void If_ObjPerformMappingAnd( If_Man_t * p, If_Obj_t * pObj, int Mode, int fPrep
|
|||
If_Cut_t * pCut0R, * pCut1R;
|
||||
int fFunc0R, fFunc1R;
|
||||
int i, k, v, iCutDsd, fChange;
|
||||
int fSave0 = p->pPars->fDelayOpt || p->pPars->fDelayOptLut || p->pPars->fDsdBalance || p->pPars->fUserRecLib || p->pPars->fUserSesLib ||
|
||||
int fSave0 = p->pPars->fDelayOpt || p->pPars->fDelayOptLut || p->pPars->fDsdBalance || p->pPars->fUserRecLib || p->pPars->fUserSesLib || p->pPars->fUserLutDec || p->pPars->fUserLut2D ||
|
||||
p->pPars->fUseDsdTune || p->pPars->fUseCofVars || p->pPars->fUseAndVars || p->pPars->fUse34Spec || p->pPars->pLutStruct || p->pPars->pFuncCell2 || p->pPars->fUseCheck1 || p->pPars->fUseCheck2;
|
||||
int fUseAndCut = (p->pPars->nAndDelay > 0) || (p->pPars->nAndArea > 0);
|
||||
assert( !If_ObjIsAnd(pObj->pFanin0) || pObj->pFanin0->pCutSet->nCuts > 0 );
|
||||
|
|
@ -208,6 +208,10 @@ void If_ObjPerformMappingAnd( If_Man_t * p, If_Obj_t * pObj, int Mode, int fPrep
|
|||
pCut->fUseless = 1;
|
||||
}
|
||||
}
|
||||
else if ( p->pPars->fUserLutDec || p->pPars->fUserLut2D )
|
||||
{
|
||||
pCut->Delay = If_LutDecReEval( p, pCut );
|
||||
}
|
||||
else if ( p->pPars->fDelayOptLut )
|
||||
pCut->Delay = If_CutLutBalanceEval( p, pCut );
|
||||
else if( p->pPars->nGateSize > 0 )
|
||||
|
|
@ -264,6 +268,8 @@ void If_ObjPerformMappingAnd( If_Man_t * p, If_Obj_t * pObj, int Mode, int fPrep
|
|||
if ( !If_CutMergeOrdered( p, pCut0, pCut1, pCut ) )
|
||||
continue;
|
||||
}
|
||||
if ( p->pPars->fUserLutDec && !fFirst && pCut->nLeaves > p->pPars->nLutDecSize )
|
||||
continue;
|
||||
if ( pObj->fSpec && pCut->nLeaves == (unsigned)p->pPars->nLutSize )
|
||||
continue;
|
||||
p->nCutsMerged++;
|
||||
|
|
@ -422,7 +428,17 @@ void If_ObjPerformMappingAnd( If_Man_t * p, If_Obj_t * pObj, int Mode, int fPrep
|
|||
else if ( p->pPars->fDsdBalance )
|
||||
pCut->Delay = If_CutDsdBalanceEval( p, pCut, NULL );
|
||||
else if ( p->pPars->fUserRecLib )
|
||||
pCut->Delay = If_CutDelayRecCost3( p, pCut, pObj );
|
||||
pCut->Delay = If_CutDelayRecCost3( p, pCut, pObj );
|
||||
else if ( p->pPars->fUserLutDec )
|
||||
{
|
||||
pCut->Delay = If_LutDecEval( p, pCut, pObj, Mode == 0, fFirst );
|
||||
pCut->fUseless = pCut->Delay == ABC_INFINITY;
|
||||
}
|
||||
else if ( p->pPars->fUserLut2D )
|
||||
{
|
||||
pCut->Delay = If_Lut2DecEval( p, pCut, pObj, Mode == 0, fFirst );
|
||||
pCut->fUseless = pCut->Delay == ABC_INFINITY;
|
||||
}
|
||||
else if ( p->pPars->fUserSesLib )
|
||||
{
|
||||
int Cost = 0;
|
||||
|
|
@ -507,7 +523,7 @@ void If_ObjPerformMappingChoice( If_Man_t * p, If_Obj_t * pObj, int Mode, int fP
|
|||
If_Set_t * pCutSet;
|
||||
If_Obj_t * pTemp;
|
||||
If_Cut_t * pCutTemp, * pCut;
|
||||
int i, fSave0 = p->pPars->fDelayOpt || p->pPars->fDelayOptLut || p->pPars->fDsdBalance || p->pPars->fUserRecLib || p->pPars->fUserSesLib || p->pPars->fUse34Spec;
|
||||
int i, fSave0 = p->pPars->fDelayOpt || p->pPars->fDelayOptLut || p->pPars->fDsdBalance || p->pPars->fUserRecLib || p->pPars->fUserSesLib || p->pPars->fUse34Spec || p->pPars->fUserLutDec || p->pPars->fUserLut2D;
|
||||
assert( pObj->pEquiv != NULL );
|
||||
|
||||
// prepare
|
||||
|
|
|
|||
|
|
@ -211,6 +211,12 @@ void If_CutPropagateRequired( If_Man_t * p, If_Obj_t * pObj, If_Cut_t * pCut, fl
|
|||
pLeaf->Required = IF_MIN( pLeaf->Required, Required - pLutDelays[0] );
|
||||
}
|
||||
}
|
||||
else if ( p->pPars->fUserLutDec || p->pPars->fUserLut2D )
|
||||
{
|
||||
Required = ObjRequired;
|
||||
If_CutForEachLeaf( p, pCut, pLeaf, i )
|
||||
pLeaf->Required = IF_MIN( pLeaf->Required, Required - If_LutDecPinRequired( p, pCut, i, ObjRequired ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( pCut->fUser )
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ SRC += src/map/if/ifCom.c \
|
|||
src/map/if/ifDec08.c \
|
||||
src/map/if/ifDec10.c \
|
||||
src/map/if/ifDec16.c \
|
||||
src/map/if/ifDec66.c \
|
||||
src/map/if/ifDec75.c \
|
||||
src/map/if/ifDelay.c \
|
||||
src/map/if/ifDsd.c \
|
||||
|
|
|
|||
|
|
@ -183,13 +183,15 @@ int Scl_CommandReadLib( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
int fUnit = 0;
|
||||
int fVerbose = 1;
|
||||
int fVeryVerbose = 0;
|
||||
int fMerge = 0;
|
||||
int fUsePrefix = 0;
|
||||
|
||||
SC_DontUse dont_use = {0};
|
||||
dont_use.dont_use_list = ABC_ALLOC(char *, argc);
|
||||
dont_use.size = 0;
|
||||
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "SGMXdnuvwh" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "SGMXdnuvwmph" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
|
|
@ -251,6 +253,12 @@ int Scl_CommandReadLib( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
case 'w':
|
||||
fVeryVerbose ^= 1;
|
||||
break;
|
||||
case 'm':
|
||||
fMerge ^= 1;
|
||||
break;
|
||||
case 'p':
|
||||
fUsePrefix ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
|
|
@ -266,12 +274,20 @@ int Scl_CommandReadLib( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
if (pLib2) Abc_SclLibFree(pLib2);
|
||||
return 1;
|
||||
}
|
||||
pLib = Abc_SclMergeLibraries( pLib1, pLib2 );
|
||||
pLib = Abc_SclMergeLibraries( pLib1, pLib2, fUsePrefix );
|
||||
Abc_SclLibFree(pLib1);
|
||||
Abc_SclLibFree(pLib2);
|
||||
}
|
||||
else if ( argc == globalUtilOptind + 1 ) { // expecting one file
|
||||
pLib = Scl_ReadLibraryFile( pAbc, argv[globalUtilOptind], fVerbose, fVeryVerbose, dont_use );
|
||||
SC_Lib * pLib1 = Scl_ReadLibraryFile( pAbc, argv[globalUtilOptind], fVerbose, fVeryVerbose, dont_use );
|
||||
|
||||
SC_Lib * pLib_ext = (SC_Lib *)pAbc->pLibScl;
|
||||
if ( fMerge && pLib_ext != NULL && pLib1 != NULL ) {
|
||||
pLib = Abc_SclMergeLibraries( pLib_ext, pLib1, fUsePrefix );
|
||||
if (pLib1) Abc_SclLibFree(pLib1);
|
||||
} else {
|
||||
pLib = pLib1;
|
||||
}
|
||||
ABC_FREE(dont_use.dont_use_list);
|
||||
}
|
||||
else {
|
||||
|
|
@ -308,7 +324,7 @@ int Scl_CommandReadLib( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pAbc->Err, "usage: read_lib [-SG float] [-M num] [-dnuvwh] [-X cell_name] <file> <file2>\n" );
|
||||
fprintf( pAbc->Err, "usage: read_lib [-SG float] [-M num] [-dnuvwmph] [-X cell_name] <file> <file2>\n" );
|
||||
fprintf( pAbc->Err, "\t reads Liberty library from file\n" );
|
||||
fprintf( pAbc->Err, "\t-S float : the slew parameter used to generate the library [default = %.2f]\n", Slew );
|
||||
fprintf( pAbc->Err, "\t-G float : the gain parameter used to generate the library [default = %.2f]\n", Gain );
|
||||
|
|
@ -319,6 +335,8 @@ usage:
|
|||
fprintf( pAbc->Err, "\t-u : toggle setting unit area for all cells [default = %s]\n", fUnit? "yes": "no" );
|
||||
fprintf( pAbc->Err, "\t-v : toggle writing verbose information [default = %s]\n", fVerbose? "yes": "no" );
|
||||
fprintf( pAbc->Err, "\t-w : toggle writing information about skipped gates [default = %s]\n", fVeryVerbose? "yes": "no" );
|
||||
fprintf( pAbc->Err, "\t-m : toggle merging library with exisiting library [default = %s]\n", fMerge? "yes": "no" );
|
||||
fprintf( pAbc->Err, "\t-p : toggle using prefix for the cell names [default = %s]\n", fUsePrefix? "yes": "no" );
|
||||
fprintf( pAbc->Err, "\t-h : prints the command summary\n" );
|
||||
fprintf( pAbc->Err, "\t<file> : the name of a file to read\n" );
|
||||
fprintf( pAbc->Err, "\t<file2> : the name of a file to read (optional)\n" );
|
||||
|
|
@ -1136,9 +1154,9 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
|
||||
usage:
|
||||
fprintf( pAbc->Err, "usage: buffer [-GSN num] [-sbpcvwh]\n" );
|
||||
fprintf( pAbc->Err, "\t performs buffering and sizing and mapped network\n" );
|
||||
fprintf( pAbc->Err, "\t performs buffering and sizing on mapped network\n" );
|
||||
fprintf( pAbc->Err, "\t-G <num> : target gain percentage [default = %d]\n", pPars->GainRatio );
|
||||
fprintf( pAbc->Err, "\t-S <num> : target slew in pisoseconds [default = %d]\n", pPars->Slew );
|
||||
fprintf( pAbc->Err, "\t-S <num> : target slew in picoseconds [default = %d]\n", pPars->Slew );
|
||||
fprintf( pAbc->Err, "\t-N <num> : the maximum fanout count [default = %d]\n", pPars->nDegree );
|
||||
fprintf( pAbc->Err, "\t-s : toggle performing only sizing [default = %s]\n", pPars->fSizeOnly? "yes": "no" );
|
||||
fprintf( pAbc->Err, "\t-b : toggle using buffers instead of inverters [default = %s]\n", pPars->fAddBufs? "yes": "no" );
|
||||
|
|
@ -1604,7 +1622,7 @@ int Scl_CommandUpsize( Abc_Frame_t * pAbc, int argc, char **argv )
|
|||
return 1;
|
||||
}
|
||||
|
||||
Abc_SclUpsizePerform( (SC_Lib *)pAbc->pLibScl, pNtk, pPars );
|
||||
Abc_SclUpsizePerform( (SC_Lib *)pAbc->pLibScl, pNtk, pPars, NULL );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
|
|
@ -1781,15 +1799,15 @@ int Scl_CommandDnsize( Abc_Frame_t * pAbc, int argc, char **argv )
|
|||
return 1;
|
||||
}
|
||||
|
||||
Abc_SclDnsizePerform( (SC_Lib *)pAbc->pLibScl, pNtk, pPars );
|
||||
Abc_SclDnsizePerform( (SC_Lib *)pAbc->pLibScl, pNtk, pPars, NULL );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pAbc->Err, "usage: dnsize [-IJNDGTX num] [-csdvwh]\n" );
|
||||
fprintf( pAbc->Err, "\t selectively decreases gate sizes while maintaining delay\n" );
|
||||
fprintf( pAbc->Err, "\t-I <num> : the number of upsizing iterations to perform [default = %d]\n", pPars->nIters );
|
||||
fprintf( pAbc->Err, "\t-I <num> : the number of downsizing iterations to perform [default = %d]\n", pPars->nIters );
|
||||
fprintf( pAbc->Err, "\t-J <num> : the number of iterations without improvement to stop [default = %d]\n", pPars->nIterNoChange );
|
||||
fprintf( pAbc->Err, "\t-N <num> : limit on discrete upsizing steps at a node [default = %d]\n", pPars->Notches );
|
||||
fprintf( pAbc->Err, "\t-N <num> : limit on discrete downsizing steps at a node [default = %d]\n", pPars->Notches );
|
||||
fprintf( pAbc->Err, "\t-D <num> : delay target set by the user, in picoseconds [default = %d]\n", pPars->DelayUser );
|
||||
fprintf( pAbc->Err, "\t-G <num> : delay gap during updating, in picoseconds [default = %d]\n", pPars->DelayGap );
|
||||
fprintf( pAbc->Err, "\t-T <num> : approximate timeout in seconds [default = %d]\n", pPars->TimeOut );
|
||||
|
|
|
|||
|
|
@ -239,7 +239,7 @@ void Abc_SclDnsizePrint( SC_Man * p, int Iter, int nAttempts, int nOverlaps, int
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_SclDnsizePerformInt( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars )
|
||||
void Abc_SclDnsizePerformInt( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars, void * pFuncFanin )
|
||||
{
|
||||
SC_Man * p;
|
||||
Abc_Obj_t * pObj;
|
||||
|
|
@ -261,11 +261,12 @@ void Abc_SclDnsizePerformInt( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPa
|
|||
|
||||
// prepare the manager; collect init stats
|
||||
p = Abc_SclManStart( pLib, pNtk, pPars->fUseWireLoads, pPars->fUseDept, pPars->DelayUser, pPars->BuffTreeEst );
|
||||
p->pFuncFanin = (float (*)(void *, Abc_Obj_t *, Abc_Obj_t *, int, int))pFuncFanin;
|
||||
p->timeTotal = Abc_Clock();
|
||||
assert( p->vGatesBest == NULL );
|
||||
p->vGatesBest = Vec_IntDup( p->pNtk->vGates );
|
||||
|
||||
// perform upsizing
|
||||
// perform downsizing
|
||||
vNodes = Vec_IntAlloc( 1000 );
|
||||
vEvals = Vec_IntAlloc( 1000 );
|
||||
vTryLater = Vec_IntAlloc( 1000 );
|
||||
|
|
@ -357,12 +358,12 @@ void Abc_SclDnsizePerformInt( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPa
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars )
|
||||
void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars, void * pFuncFanin )
|
||||
{
|
||||
Abc_Ntk_t * pNtkNew = pNtk;
|
||||
if ( pNtk->nBarBufs2 > 0 )
|
||||
pNtkNew = Abc_NtkDupDfsNoBarBufs( pNtk );
|
||||
Abc_SclDnsizePerformInt( pLib, pNtkNew, pPars );
|
||||
Abc_SclDnsizePerformInt( pLib, pNtkNew, pPars, pFuncFanin );
|
||||
if ( pNtk->nBarBufs2 > 0 )
|
||||
Abc_SclTransferGates( pNtk, pNtkNew );
|
||||
if ( pNtk->nBarBufs2 > 0 )
|
||||
|
|
|
|||
|
|
@ -748,7 +748,7 @@ extern SC_Lib * Abc_SclReadFromStr( Vec_Str_t * vOut );
|
|||
extern SC_Lib * Abc_SclReadFromFile( char * pFileName );
|
||||
extern void Abc_SclWriteScl( char * pFileName, SC_Lib * p );
|
||||
extern void Abc_SclWriteLiberty( char * pFileName, SC_Lib * p );
|
||||
extern SC_Lib * Abc_SclMergeLibraries( SC_Lib * pLib1, SC_Lib * pLib2 );
|
||||
extern SC_Lib * Abc_SclMergeLibraries( SC_Lib * pLib1, SC_Lib * pLib2, int fUsePrefix );
|
||||
/*=== sclLibUtil.c ===============================================================*/
|
||||
extern void Abc_SclHashCells( SC_Lib * p );
|
||||
extern int Abc_SclCellFind( SC_Lib * p, char * pName );
|
||||
|
|
|
|||
|
|
@ -570,7 +570,7 @@ int Abc_SclCountValidCells( SC_Lib * p )
|
|||
n_valid_cells++;
|
||||
return n_valid_cells;
|
||||
}
|
||||
static void Abc_SclWriteLibrary( Vec_Str_t * vOut, SC_Lib * p, int nExtra )
|
||||
static void Abc_SclWriteLibrary( Vec_Str_t * vOut, SC_Lib * p, int nExtra, int fUsePrefix )
|
||||
{
|
||||
SC_WireLoad * pWL;
|
||||
SC_WireLoadSel * pWLS;
|
||||
|
|
@ -624,13 +624,13 @@ static void Abc_SclWriteLibrary( Vec_Str_t * vOut, SC_Lib * p, int nExtra )
|
|||
// Write 'cells' vector:
|
||||
n_valid_cells = Abc_SclCountValidCells( p );
|
||||
Vec_StrPutI( vOut, n_valid_cells + nExtra );
|
||||
Abc_SclWriteLibraryCellsOnly( vOut, p, (int)(nExtra > 0) );
|
||||
Abc_SclWriteLibraryCellsOnly( vOut, p, fUsePrefix ? 1 : 0 );
|
||||
}
|
||||
void Abc_SclWriteScl( char * pFileName, SC_Lib * p )
|
||||
{
|
||||
Vec_Str_t * vOut;
|
||||
vOut = Vec_StrAlloc( 10000 );
|
||||
Abc_SclWriteLibrary( vOut, p, 0 );
|
||||
Abc_SclWriteLibrary( vOut, p, 0, 0 );
|
||||
if ( Vec_StrSize(vOut) > 0 )
|
||||
{
|
||||
FILE * pFile = fopen( pFileName, "wb" );
|
||||
|
|
@ -866,12 +866,12 @@ void Abc_SclWriteLiberty( char * pFileName, SC_Lib * p )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
SC_Lib * Abc_SclMergeLibraries( SC_Lib * pLib1, SC_Lib * pLib2 )
|
||||
SC_Lib * Abc_SclMergeLibraries( SC_Lib * pLib1, SC_Lib * pLib2, int fUsePrefix )
|
||||
{
|
||||
Vec_Str_t * vOut = Vec_StrAlloc( 10000 );
|
||||
int n_valid_cells2 = Abc_SclCountValidCells( pLib2 );
|
||||
Abc_SclWriteLibrary( vOut, pLib1, n_valid_cells2 );
|
||||
Abc_SclWriteLibraryCellsOnly( vOut, pLib2, 2 );
|
||||
Abc_SclWriteLibrary( vOut, pLib1, n_valid_cells2, fUsePrefix );
|
||||
Abc_SclWriteLibraryCellsOnly( vOut, pLib2, fUsePrefix ? 2 : 0 );
|
||||
SC_Lib * p = Abc_SclReadFromStr( vOut );
|
||||
p->pFileName = Abc_UtilStrsav( pLib1->pFileName );
|
||||
p->pName = ABC_ALLOC( char, strlen(pLib1->pName) + strlen(pLib2->pName) + 10 );
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ struct Scl_Tree_t_
|
|||
|
||||
static inline int Scl_LibertyGlobMatch(const char * pattern, const char * string) {
|
||||
#ifdef _WIN32
|
||||
return PathMatchSpec(string, pattern);
|
||||
return PathMatchSpec(string, pattern); // if the compiler complains, add "-lshlwapi"
|
||||
#else
|
||||
return fnmatch(pattern, string, 0) == 0;
|
||||
#endif
|
||||
|
|
@ -281,26 +281,38 @@ static inline char * Scl_LibertyFindMatch( char * pPos, char * pEnd )
|
|||
assert( *pPos == '(' || *pPos == '{' );
|
||||
if ( *pPos == '(' )
|
||||
{
|
||||
for ( ; pPos < pEnd; pPos++ )
|
||||
{
|
||||
if ( *pPos == '(' )
|
||||
++Counter;
|
||||
++pPos;
|
||||
for ( ; pPos < pEnd; pPos++ )
|
||||
{
|
||||
// Invariant: Counter > 0.
|
||||
if ( *pPos == '(' ) {
|
||||
Counter++;
|
||||
if ( *pPos == ')' )
|
||||
continue;
|
||||
}
|
||||
else if ( *pPos == ')' ) {
|
||||
Counter--;
|
||||
if ( Counter == 0 )
|
||||
break;
|
||||
if ( Counter == 0 )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
++Counter;
|
||||
++pPos;
|
||||
for ( ; pPos < pEnd; pPos++ )
|
||||
{
|
||||
if ( *pPos == '{' )
|
||||
// Invariant: Counter > 0.
|
||||
if ( *pPos == '{' ) {
|
||||
Counter++;
|
||||
if ( *pPos == '}' )
|
||||
continue;
|
||||
}
|
||||
else if ( *pPos == '}' ) {
|
||||
Counter--;
|
||||
if ( Counter == 0 )
|
||||
break;
|
||||
if ( Counter == 0 )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
assert( *pPos == ')' || *pPos == '}' );
|
||||
|
|
@ -317,10 +329,14 @@ static inline Scl_Pair_t Scl_LibertyUpdateHead( Scl_Tree_t * p, Scl_Pair_t Head
|
|||
char * pChar;
|
||||
for ( pChar = pBeg; pChar < pEnd; pChar++ )
|
||||
{
|
||||
if ( *pChar == '\n' )
|
||||
if ( *pChar == '\n' ) {
|
||||
p->nLines++;
|
||||
if ( Scl_LibertyCharIsSpace(*pChar) )
|
||||
// Note: Scl_LibertyCharIsSpace returns true for '\n', so we can
|
||||
// continue here and save the call to Scl_LibertyCharIsSpace.
|
||||
continue;
|
||||
} else if ( Scl_LibertyCharIsSpace(*pChar) ) {
|
||||
continue;
|
||||
}
|
||||
pLastNonSpace = pChar;
|
||||
if ( pFirstNonSpace == NULL )
|
||||
pFirstNonSpace = pChar;
|
||||
|
|
|
|||
|
|
@ -270,21 +270,25 @@ void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fPrintPath )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Abc_SclTimeFanin( SC_Man * p, SC_Timing * pTime, Abc_Obj_t * pObj, Abc_Obj_t * pFanin )
|
||||
static inline void Abc_SclTimeFanin( SC_Man * p, SC_Timing * pTime, Abc_Obj_t * pObj, Abc_Obj_t * pFanin, int k )
|
||||
{
|
||||
SC_Pair * pArrIn = Abc_SclObjTime( p, pFanin );
|
||||
SC_Pair * pSlewIn = Abc_SclObjSlew( p, pFanin );
|
||||
SC_Pair * pLoad = Abc_SclObjLoad( p, pObj );
|
||||
SC_Pair * pArrOut = Abc_SclObjTime( p, pObj ); // modified
|
||||
SC_Pair * pSlewOut = Abc_SclObjSlew( p, pObj ); // modified
|
||||
if ( p->pFuncFanin ) pLoad->fall += p->pFuncFanin(p, pObj, pFanin, k, 0);
|
||||
if ( p->pFuncFanin ) pLoad->rise += p->pFuncFanin(p, pObj, pFanin, k, 1);
|
||||
Scl_LibPinArrival( pTime, pArrIn, pSlewIn, pLoad, pArrOut, pSlewOut );
|
||||
}
|
||||
static inline void Abc_SclDeptFanin( SC_Man * p, SC_Timing * pTime, Abc_Obj_t * pObj, Abc_Obj_t * pFanin )
|
||||
static inline void Abc_SclDeptFanin( SC_Man * p, SC_Timing * pTime, Abc_Obj_t * pObj, Abc_Obj_t * pFanin, int k )
|
||||
{
|
||||
SC_Pair * pDepIn = Abc_SclObjDept( p, pFanin ); // modified
|
||||
SC_Pair * pSlewIn = Abc_SclObjSlew( p, pFanin );
|
||||
SC_Pair * pLoad = Abc_SclObjLoad( p, pObj );
|
||||
SC_Pair * pDepOut = Abc_SclObjDept( p, pObj );
|
||||
if ( p->pFuncFanin ) pLoad->fall += p->pFuncFanin(p, pObj, pFanin, k, 0);
|
||||
if ( p->pFuncFanin ) pLoad->rise += p->pFuncFanin(p, pObj, pFanin, k, 1);
|
||||
Scl_LibPinDeparture( pTime, pDepIn, pSlewIn, pLoad, pDepOut );
|
||||
}
|
||||
static inline void Abc_SclDeptObj( SC_Man * p, Abc_Obj_t * pObj )
|
||||
|
|
@ -298,7 +302,7 @@ static inline void Abc_SclDeptObj( SC_Man * p, Abc_Obj_t * pObj )
|
|||
if ( Abc_ObjIsCo(pFanout) || Abc_ObjIsLatch(pFanout) )
|
||||
continue;
|
||||
pTime = Scl_CellPinTime( Abc_SclObjCell(pFanout), Abc_NodeFindFanin(pFanout, pObj) );
|
||||
Abc_SclDeptFanin( p, pTime, pFanout, pObj );
|
||||
Abc_SclDeptFanin( p, pTime, pFanout, pObj, Abc_NodeFindFanin(pFanout, pObj) );
|
||||
}
|
||||
}
|
||||
static inline float Abc_SclObjLoadValue( SC_Man * p, Abc_Obj_t * pObj )
|
||||
|
|
@ -368,9 +372,9 @@ void Abc_SclTimeNode( SC_Man * p, Abc_Obj_t * pObj, int fDept )
|
|||
{
|
||||
pTime = Scl_CellPinTime( pCell, k );
|
||||
if ( fDept )
|
||||
Abc_SclDeptFanin( p, pTime, pObj, pFanin );
|
||||
Abc_SclDeptFanin( p, pTime, pObj, pFanin, k );
|
||||
else
|
||||
Abc_SclTimeFanin( p, pTime, pObj, pFanin );
|
||||
Abc_SclTimeFanin( p, pTime, pObj, pFanin, k );
|
||||
}
|
||||
if ( p->EstLoadMax && Value > 1 )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ struct SC_Man_
|
|||
abctime timeSize; // incremental sizing
|
||||
abctime timeTime; // timing update
|
||||
abctime timeOther; // everything else
|
||||
float (*pFuncFanin)(void * p, Abc_Obj_t * pObj, Abc_Obj_t * pFanin, int iFanin, int fRise); // called to get info about the node's fanin
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -127,7 +128,7 @@ static inline double Abc_SclObjSlackMax( SC_Man * p, Abc_Obj_t * pObj, float
|
|||
static inline void Abc_SclObjDupFanin( SC_Man * p, Abc_Obj_t * pObj ) { assert( Abc_ObjIsCo(pObj) ); *Abc_SclObjTime(p, pObj) = *Abc_SclObjTime(p, Abc_ObjFanin0(pObj)); }
|
||||
static inline float Abc_SclObjInDrive( SC_Man * p, Abc_Obj_t * pObj ) { return Vec_FltEntry( p->vInDrive, pObj->iData ); }
|
||||
static inline void Abc_SclObjSetInDrive( SC_Man * p, Abc_Obj_t * pObj, float c){ Vec_FltWriteEntry( p->vInDrive, pObj->iData, c ); }
|
||||
|
||||
static inline void Abc_SclManSetFaninCallBack( SC_Man * p, void * pCallBack ) { p->pFuncFanin = (float (*)(void *, Abc_Obj_t *, Abc_Obj_t *, int, int))pCallBack; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
|
|
@ -551,7 +552,7 @@ extern int Abc_SclCheckNtk( Abc_Ntk_t * p, int fVerbose );
|
|||
extern Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int DegreeR, int Degree, int fUseInvs, int fVerbose );
|
||||
extern Abc_Ntk_t * Abc_SclBufPerform( Abc_Ntk_t * pNtk, int FanMin, int FanMax, int fBufPis, int fSkipDup, int fVerbose );
|
||||
/*=== sclDnsize.c ===============================================================*/
|
||||
extern void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars );
|
||||
extern void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars, void * pFuncFanin );
|
||||
/*=== sclLoad.c ===============================================================*/
|
||||
extern Vec_Flt_t * Abc_SclFindWireCaps( SC_WireLoad * pWL, int nFanoutMax );
|
||||
extern float Abc_SclFindWireLoad( Vec_Flt_t * vWireCaps, int nFans );
|
||||
|
|
@ -573,7 +574,7 @@ extern void Abc_SclTimePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, int nT
|
|||
extern void Abc_SclPrintBuffers( SC_Lib * pLib, Abc_Ntk_t * pNtk, int fVerbose );
|
||||
/*=== sclUpsize.c ===============================================================*/
|
||||
extern int Abc_SclCountNearCriticalNodes( SC_Man * p );
|
||||
extern void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars );
|
||||
extern void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars, void * pFuncFanin );
|
||||
/*=== sclUtil.c ===============================================================*/
|
||||
extern void Abc_SclMioGates2SclGates( SC_Lib * pLib, Abc_Ntk_t * p );
|
||||
extern void Abc_SclSclGates2MioGates( SC_Lib * pLib, Abc_Ntk_t * p );
|
||||
|
|
|
|||
|
|
@ -865,7 +865,7 @@ void Abc_SclUpsizeRemoveDangling( SC_Man * p, Abc_Ntk_t * pNtk )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_SclUpsizePerformInt( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars )
|
||||
void Abc_SclUpsizePerformInt( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars, void * pFuncFanin )
|
||||
{
|
||||
SC_Man * p;
|
||||
Vec_Int_t * vPathPos = NULL; // critical POs
|
||||
|
|
@ -891,6 +891,7 @@ void Abc_SclUpsizePerformInt( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPa
|
|||
pPars->Window += (Abc_NtkNodeNum(pNtk) > 40000);
|
||||
// prepare the manager; collect init stats
|
||||
p = Abc_SclManStart( pLib, pNtk, pPars->fUseWireLoads, pPars->fUseDept, 0, pPars->BuffTreeEst );
|
||||
p->pFuncFanin = (float (*)(void *, Abc_Obj_t *, Abc_Obj_t *, int, int))pFuncFanin;
|
||||
p->timeTotal = Abc_Clock();
|
||||
assert( p->vGatesBest == NULL );
|
||||
p->vGatesBest = Vec_IntDup( p->pNtk->vGates );
|
||||
|
|
@ -1024,12 +1025,12 @@ void Abc_SclUpsizePerformInt( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPa
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars )
|
||||
void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars, void * pFuncFanin )
|
||||
{
|
||||
Abc_Ntk_t * pNtkNew = pNtk;
|
||||
if ( pNtk->nBarBufs2 > 0 )
|
||||
pNtkNew = Abc_NtkDupDfsNoBarBufs( pNtk );
|
||||
Abc_SclUpsizePerformInt( pLib, pNtkNew, pPars );
|
||||
Abc_SclUpsizePerformInt( pLib, pNtkNew, pPars, pFuncFanin );
|
||||
if ( pNtk->nBarBufs2 > 0 )
|
||||
Abc_SclTransferGates( pNtk, pNtkNew );
|
||||
if ( pNtk->nBarBufs2 > 0 )
|
||||
|
|
|
|||
|
|
@ -626,6 +626,27 @@ static inline void Vec_BitReset( Vec_Bit_t * p )
|
|||
p->pArray[i] = 0;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_BitPrint( Vec_Bit_t * p )
|
||||
{
|
||||
int i, Entry;
|
||||
printf( "Vector has %d entries: {", Vec_BitSize(p) );
|
||||
Vec_BitForEachEntry( p, Entry, i )
|
||||
printf( " %d", Entry );
|
||||
printf( " }\n" );
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -195,6 +195,32 @@ static inline Vec_Wrd_t * Vec_WrdStartTruthTables( int nVars )
|
|||
}
|
||||
return p;
|
||||
}
|
||||
static inline Vec_Wrd_t * Vec_WrdStartTruthTablesRev( int nVars )
|
||||
{
|
||||
Vec_Wrd_t * p;
|
||||
unsigned Masks[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 };
|
||||
int i, k, nWords;
|
||||
nWords = nVars <= 6 ? 1 : (1 << (nVars - 6));
|
||||
p = Vec_WrdStart( nWords * nVars );
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
{
|
||||
unsigned * pTruth = (unsigned *)(p->pArray + nWords * (nVars-1-i));
|
||||
if ( i < 5 )
|
||||
{
|
||||
for ( k = 0; k < 2*nWords; k++ )
|
||||
pTruth[k] = Masks[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( k = 0; k < 2*nWords; k++ )
|
||||
if ( k & (1 << (i-5)) )
|
||||
pTruth[k] = ~(unsigned)0;
|
||||
else
|
||||
pTruth[k] = 0;
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
static inline int Vec_WrdShiftOne( Vec_Wrd_t * p, int nWords )
|
||||
{
|
||||
int i, nObjs = p->nSize/nWords;
|
||||
|
|
|
|||
|
|
@ -120,6 +120,8 @@ struct Cec_ParFra_t_
|
|||
int fVeryVerbose; // verbose stats
|
||||
int fVerbose; // verbose stats
|
||||
int iOutFail; // the failed output
|
||||
int fBMiterInfo; // printing BMiter information
|
||||
int nPO; // number of po in original design given a bmiter
|
||||
};
|
||||
|
||||
// combinational equivalence checking parameters
|
||||
|
|
|
|||
|
|
@ -0,0 +1,341 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [cecSplit.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Combinational equivalence checking.]
|
||||
|
||||
Synopsis [Cofactoring for combinational miters.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: cecSplit.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include <math.h>
|
||||
#include "aig/gia/gia.h"
|
||||
#include "aig/gia/giaAig.h"
|
||||
|
||||
#include "sat/bmc/bmc.h"
|
||||
#include "proof/pdr/pdr.h"
|
||||
#include "proof/cec/cec.h"
|
||||
#include "proof/ssw/ssw.h"
|
||||
|
||||
|
||||
#ifdef ABC_USE_PTHREADS
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "../lib/pthread.h"
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern int Ssw_RarSimulateGia( Gia_Man_t * p, Ssw_RarPars_t * pPars );
|
||||
extern int Bmcg_ManPerform( Gia_Man_t * pGia, Bmc_AndPar_t * pPars );
|
||||
|
||||
#ifndef ABC_USE_PTHREADS
|
||||
|
||||
int Cec_GiaProveTest( Gia_Man_t * p, int nProcs, int nTimeOut, int nTimeOut2, int nTimeOut3, int fVerbose, int fVeryVerbose, int fSilent ) { return -1; }
|
||||
|
||||
#else // pthreads are used
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Cec_GiaProveOne( Gia_Man_t * p, int iEngine, int nTimeOut, int fVerbose )
|
||||
{
|
||||
abctime clk = Abc_Clock();
|
||||
int RetValue = -1;
|
||||
//abctime clkStop = nTimeOut * CLOCKS_PER_SEC + Abc_Clock();
|
||||
if ( fVerbose )
|
||||
printf( "Calling engine %d with timeout %d sec.\n", iEngine, nTimeOut );
|
||||
Abc_CexFreeP( &p->pCexSeq );
|
||||
if ( iEngine == 0 )
|
||||
{
|
||||
Ssw_RarPars_t Pars, * pPars = &Pars;
|
||||
Ssw_RarSetDefaultParams( pPars );
|
||||
pPars->TimeOut = nTimeOut;
|
||||
pPars->fSilent = 1;
|
||||
RetValue = Ssw_RarSimulateGia( p, pPars );
|
||||
}
|
||||
else if ( iEngine == 1 )
|
||||
{
|
||||
Saig_ParBmc_t Pars, * pPars = &Pars;
|
||||
Saig_ParBmcSetDefaultParams( pPars );
|
||||
pPars->nTimeOut = nTimeOut;
|
||||
pPars->fSilent = 1;
|
||||
Aig_Man_t * pAig = Gia_ManToAigSimple( p );
|
||||
RetValue = Saig_ManBmcScalable( pAig, pPars );
|
||||
p->pCexSeq = pAig->pSeqModel; pAig->pSeqModel = NULL;
|
||||
Aig_ManStop( pAig );
|
||||
}
|
||||
else if ( iEngine == 2 )
|
||||
{
|
||||
Pdr_Par_t Pars, * pPars = &Pars;
|
||||
Pdr_ManSetDefaultParams( pPars );
|
||||
pPars->nTimeOut = nTimeOut;
|
||||
pPars->fSilent = 1;
|
||||
Aig_Man_t * pAig = Gia_ManToAigSimple( p );
|
||||
RetValue = Pdr_ManSolve( pAig, pPars );
|
||||
p->pCexSeq = pAig->pSeqModel; pAig->pSeqModel = NULL;
|
||||
Aig_ManStop( pAig );
|
||||
}
|
||||
else if ( iEngine == 3 )
|
||||
{
|
||||
Saig_ParBmc_t Pars, * pPars = &Pars;
|
||||
Saig_ParBmcSetDefaultParams( pPars );
|
||||
pPars->fUseGlucose = 1;
|
||||
pPars->nTimeOut = nTimeOut;
|
||||
pPars->fSilent = 1;
|
||||
Aig_Man_t * pAig = Gia_ManToAigSimple( p );
|
||||
RetValue = Saig_ManBmcScalable( pAig, pPars );
|
||||
p->pCexSeq = pAig->pSeqModel; pAig->pSeqModel = NULL;
|
||||
Aig_ManStop( pAig );
|
||||
}
|
||||
else if ( iEngine == 4 )
|
||||
{
|
||||
Pdr_Par_t Pars, * pPars = &Pars;
|
||||
Pdr_ManSetDefaultParams( pPars );
|
||||
pPars->fUseAbs = 1;
|
||||
pPars->nTimeOut = nTimeOut;
|
||||
pPars->fSilent = 1;
|
||||
Aig_Man_t * pAig = Gia_ManToAigSimple( p );
|
||||
RetValue = Pdr_ManSolve( pAig, pPars );
|
||||
p->pCexSeq = pAig->pSeqModel; pAig->pSeqModel = NULL;
|
||||
Aig_ManStop( pAig );
|
||||
}
|
||||
else if ( iEngine == 5 )
|
||||
{
|
||||
Bmc_AndPar_t Pars, * pPars = &Pars;
|
||||
memset( pPars, 0, sizeof(Bmc_AndPar_t) );
|
||||
pPars->nProcs = 1; // the number of parallel solvers
|
||||
pPars->nFramesAdd = 1; // the number of additional frames
|
||||
pPars->fNotVerbose = 1; // silent
|
||||
pPars->nTimeOut = nTimeOut; // timeout in seconds
|
||||
RetValue = Bmcg_ManPerform( p, pPars );
|
||||
}
|
||||
else assert( 0 );
|
||||
//while ( Abc_Clock() < clkStop );
|
||||
if ( fVerbose ) {
|
||||
printf( "Engine %d finished and %ssolved the problem. ", iEngine, RetValue != -1 ? " " : "not " );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
||||
}
|
||||
return RetValue;
|
||||
}
|
||||
Gia_Man_t * Cec_GiaScorrOld( Gia_Man_t * p )
|
||||
{
|
||||
Ssw_Pars_t Pars, * pPars = &Pars;
|
||||
Ssw_ManSetDefaultParams( pPars );
|
||||
Aig_Man_t * pAig = Gia_ManToAigSimple( p );
|
||||
Aig_Man_t * pAig2 = Ssw_SignalCorrespondence( pAig, pPars );
|
||||
Gia_Man_t * pGia2 = Gia_ManFromAigSimple( pAig2 );
|
||||
Aig_ManStop( pAig2 );
|
||||
Aig_ManStop( pAig );
|
||||
return pGia2;
|
||||
}
|
||||
Gia_Man_t * Cec_GiaScorrNew( Gia_Man_t * p )
|
||||
{
|
||||
Cec_ParCor_t Pars, * pPars = &Pars;
|
||||
Cec_ManCorSetDefaultParams( pPars );
|
||||
pPars->nBTLimit = 100;
|
||||
pPars->nLevelMax = 100;
|
||||
pPars->fVerbose = 0;
|
||||
pPars->fUseCSat = 1;
|
||||
return Cec_ManLSCorrespondence( p, pPars );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
#define PAR_THR_MAX 8
|
||||
typedef struct Par_ThData_t_
|
||||
{
|
||||
Gia_Man_t * p;
|
||||
int iEngine;
|
||||
int fWorking;
|
||||
int nTimeOut;
|
||||
int Result;
|
||||
int fVerbose;
|
||||
} Par_ThData_t;
|
||||
void * Cec_GiaProveWorkerThread( void * pArg )
|
||||
{
|
||||
Par_ThData_t * pThData = (Par_ThData_t *)pArg;
|
||||
volatile int * pPlace = &pThData->fWorking;
|
||||
while ( 1 )
|
||||
{
|
||||
while ( *pPlace == 0 );
|
||||
assert( pThData->fWorking );
|
||||
if ( pThData->p == NULL )
|
||||
{
|
||||
pthread_exit( NULL );
|
||||
assert( 0 );
|
||||
return NULL;
|
||||
}
|
||||
pThData->Result = Cec_GiaProveOne( pThData->p, pThData->iEngine, pThData->nTimeOut, pThData->fVerbose );
|
||||
pThData->fWorking = 0;
|
||||
}
|
||||
assert( 0 );
|
||||
return NULL;
|
||||
}
|
||||
void Cec_GiaInitThreads( Par_ThData_t * ThData, int nProcs, Gia_Man_t * p, int nTimeOut, int fVerbose, pthread_t * WorkerThread )
|
||||
{
|
||||
int i, status;
|
||||
assert( nProcs <= PAR_THR_MAX );
|
||||
for ( i = 0; i < nProcs; i++ )
|
||||
{
|
||||
ThData[i].p = Gia_ManDup(p);
|
||||
ThData[i].iEngine = i;
|
||||
ThData[i].nTimeOut = nTimeOut;
|
||||
ThData[i].fWorking = 0;
|
||||
ThData[i].Result = -1;
|
||||
ThData[i].fVerbose = fVerbose;
|
||||
if ( !WorkerThread )
|
||||
continue;
|
||||
status = pthread_create( WorkerThread + i, NULL,Cec_GiaProveWorkerThread, (void *)(ThData + i) ); assert( status == 0 );
|
||||
}
|
||||
for ( i = 0; i < nProcs; i++ )
|
||||
ThData[i].fWorking = 1;
|
||||
}
|
||||
int Cec_GiaWaitThreads( Par_ThData_t * ThData, int nProcs, Gia_Man_t * p, int RetValue, int * pRetEngine )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < nProcs; i++ )
|
||||
{
|
||||
if ( RetValue == -1 && !ThData[i].fWorking && ThData[i].Result != -1 ) {
|
||||
RetValue = ThData[i].Result;
|
||||
*pRetEngine = i;
|
||||
if ( !p->pCexSeq && ThData[i].p->pCexSeq )
|
||||
p->pCexSeq = Abc_CexDup( ThData[i].p->pCexSeq, -1 );
|
||||
}
|
||||
if ( ThData[i].fWorking )
|
||||
i = -1;
|
||||
}
|
||||
return RetValue;
|
||||
}
|
||||
|
||||
int Cec_GiaProveTest( Gia_Man_t * p, int nProcs, int nTimeOut, int nTimeOut2, int nTimeOut3, int fVerbose, int fVeryVerbose, int fSilent )
|
||||
{
|
||||
abctime clkScorr = 0, clkTotal = Abc_Clock();
|
||||
Par_ThData_t ThData[PAR_THR_MAX];
|
||||
pthread_t WorkerThread[PAR_THR_MAX];
|
||||
int i, RetValue = -1, RetEngine = -2;
|
||||
Abc_CexFreeP( &p->pCexComb );
|
||||
Abc_CexFreeP( &p->pCexSeq );
|
||||
if ( !fSilent && fVerbose )
|
||||
printf( "Solving verification problem with the following parameters:\n" );
|
||||
if ( !fSilent && fVerbose )
|
||||
printf( "Processes = %d TimeOut = %d sec Verbose = %d.\n", nProcs, nTimeOut, fVerbose );
|
||||
fflush( stdout );
|
||||
|
||||
assert( nProcs == 3 || nProcs == 5 );
|
||||
Cec_GiaInitThreads( ThData, nProcs, p, nTimeOut, fVerbose, WorkerThread );
|
||||
|
||||
// meanwhile, perform scorr
|
||||
Gia_Man_t * pScorr = Cec_GiaScorrNew( p );
|
||||
clkScorr = Abc_Clock() - clkTotal;
|
||||
if ( Gia_ManAndNum(pScorr) == 0 )
|
||||
RetValue = 1, RetEngine = -1;
|
||||
|
||||
RetValue = Cec_GiaWaitThreads( ThData, nProcs, p, RetValue, &RetEngine );
|
||||
if ( RetValue == -1 )
|
||||
{
|
||||
abctime clkScorr2, clkStart = Abc_Clock();
|
||||
if ( !fSilent && fVerbose ) {
|
||||
printf( "Reduced the miter from %d to %d nodes. ", Gia_ManAndNum(p), Gia_ManAndNum(pScorr) );
|
||||
Abc_PrintTime( 1, "Time", clkScorr );
|
||||
}
|
||||
Cec_GiaInitThreads( ThData, nProcs, pScorr, nTimeOut2, fVerbose, NULL );
|
||||
|
||||
// meanwhile, perform scorr
|
||||
if ( Gia_ManAndNum(pScorr) < 100000 )
|
||||
{
|
||||
Gia_Man_t * pScorr2 = Cec_GiaScorrOld( pScorr );
|
||||
clkScorr2 = Abc_Clock() - clkStart;
|
||||
if ( Gia_ManAndNum(pScorr2) == 0 )
|
||||
RetValue = 1;
|
||||
|
||||
RetValue = Cec_GiaWaitThreads( ThData, nProcs, p, RetValue, &RetEngine );
|
||||
if ( RetValue == -1 )
|
||||
{
|
||||
if ( !fSilent && fVerbose ) {
|
||||
printf( "Reduced the miter from %d to %d nodes. ", Gia_ManAndNum(pScorr), Gia_ManAndNum(pScorr2) );
|
||||
Abc_PrintTime( 1, "Time", clkScorr2 );
|
||||
}
|
||||
Cec_GiaInitThreads( ThData, nProcs, pScorr2, nTimeOut3, fVerbose, NULL );
|
||||
|
||||
RetValue = Cec_GiaWaitThreads( ThData, nProcs, p, RetValue, &RetEngine );
|
||||
// do something else
|
||||
}
|
||||
Gia_ManStop( pScorr2 );
|
||||
}
|
||||
}
|
||||
Gia_ManStop( pScorr );
|
||||
|
||||
// stop threads
|
||||
for ( i = 0; i < nProcs; i++ )
|
||||
{
|
||||
ThData[i].p = NULL;
|
||||
ThData[i].fWorking = 1;
|
||||
}
|
||||
if ( !fSilent )
|
||||
{
|
||||
printf( "Problem \"%s\" is ", p->pSpec );
|
||||
if ( RetValue == 0 )
|
||||
printf( "SAT (solved by %d).", RetEngine );
|
||||
else if ( RetValue == 1 )
|
||||
printf( "UNSAT (solved by %d).", RetEngine );
|
||||
else if ( RetValue == -1 )
|
||||
printf( "UNDECIDED." );
|
||||
else assert( 0 );
|
||||
printf( " " );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clkTotal );
|
||||
fflush( stdout );
|
||||
}
|
||||
return RetValue;
|
||||
}
|
||||
|
||||
#endif // pthreads are used
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
@ -219,6 +219,7 @@ void Cec4_ManSetParams( Cec_ParFra_t * pPars )
|
|||
pPars->nSatVarMax = 1000; // the max number of SAT variables before recycling SAT solver
|
||||
pPars->nCallsRecycle = 500; // calls to perform before recycling SAT solver
|
||||
pPars->nGenIters = 100; // pattern generation iterations
|
||||
pPars->fBMiterInfo = 0; // printing BMiter information
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -1781,8 +1782,10 @@ void Gia_ManRemoveWrongChoices( Gia_Man_t * p )
|
|||
}
|
||||
//Abc_Print( 1, "Removed %d wrong choices.\n", Counter );
|
||||
}
|
||||
|
||||
int Cec4_ManPerformSweeping( Gia_Man_t * p, Cec_ParFra_t * pPars, Gia_Man_t ** ppNew, int fSimOnly )
|
||||
{
|
||||
|
||||
Cec4_Man_t * pMan = Cec4_ManCreate( p, pPars );
|
||||
Gia_Obj_t * pObj, * pRepr;
|
||||
int i, fSimulate = 1;
|
||||
|
|
@ -1878,8 +1881,16 @@ int Cec4_ManPerformSweeping( Gia_Man_t * p, Cec_ParFra_t * pPars, Gia_Man_t ** p
|
|||
if ( pRepr == NULL )
|
||||
continue;
|
||||
}
|
||||
int id_obj = Gia_ObjId( p, pObj );
|
||||
int id_repr = Gia_ObjId( p, pRepr );
|
||||
|
||||
if ( Abc_Lit2Var(pObj->Value) == Abc_Lit2Var(pRepr->Value) )
|
||||
{
|
||||
if ( pPars->fBMiterInfo )
|
||||
{
|
||||
Bnd_ManMerge( id_repr, id_obj, pObj->fPhase ^ pRepr->fPhase );
|
||||
}
|
||||
|
||||
assert( (pObj->Value ^ pRepr->Value) == (pObj->fPhase ^ pRepr->fPhase) );
|
||||
Gia_ObjSetProved( p, i );
|
||||
if ( Gia_ObjId(p, pRepr) == 0 )
|
||||
|
|
@ -1887,8 +1898,26 @@ int Cec4_ManPerformSweeping( Gia_Man_t * p, Cec_ParFra_t * pPars, Gia_Man_t ** p
|
|||
continue;
|
||||
}
|
||||
if ( Cec4_ManSweepNode(pMan, i, Gia_ObjId(p, pRepr)) && Gia_ObjProved(p, i) )
|
||||
{
|
||||
if (pPars->fBMiterInfo){
|
||||
|
||||
Bnd_ManMerge( id_repr, id_obj, pObj->fPhase ^ pRepr->fPhase );
|
||||
// printf( "proven %d merged into %d (phase : %d)\n", Gia_ObjId(p, pObj), Gia_ObjId(p,pRepr), pObj->fPhase ^ pRepr -> fPhase );
|
||||
|
||||
}
|
||||
pObj->Value = Abc_LitNotCond( pRepr->Value, pObj->fPhase ^ pRepr->fPhase );
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if ( pPars->fBMiterInfo )
|
||||
{
|
||||
// print
|
||||
Bnd_ManFinalizeMappings();
|
||||
// Bnd_ManPrintMappings();
|
||||
}
|
||||
|
||||
if ( p->iPatsPi > 0 )
|
||||
{
|
||||
abctime clk2 = Abc_Clock();
|
||||
|
|
@ -1937,6 +1966,7 @@ Gia_Man_t * Cec4_ManSimulateTest( Gia_Man_t * p, Cec_ParFra_t * pPars )
|
|||
{
|
||||
Gia_Man_t * pNew = NULL;
|
||||
Cec4_ManPerformSweeping( p, pPars, &pNew, 0 );
|
||||
|
||||
return pNew;
|
||||
}
|
||||
void Cec4_ManSimulateTest2( Gia_Man_t * p, int nConfs, int fVerbose )
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ SRC += src/proof/cec/cecCec.c \
|
|||
src/proof/cec/cecIso.c \
|
||||
src/proof/cec/cecMan.c \
|
||||
src/proof/cec/cecPat.c \
|
||||
src/proof/cec/cecProve.c \
|
||||
src/proof/cec/cecSat.c \
|
||||
src/proof/cec/cecSatG.c \
|
||||
src/proof/cec/cecSatG2.c \
|
||||
|
|
|
|||
|
|
@ -1354,7 +1354,7 @@ int Pdr_ManSolveInt( Pdr_Man_t * p )
|
|||
{
|
||||
if ( p->pPars->fVerbose )
|
||||
Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
|
||||
if ( p->timeToStop && Abc_Clock() > p->timeToStop )
|
||||
if ( p->timeToStop && Abc_Clock() > p->timeToStop && !p->pPars->fSilent )
|
||||
Abc_Print( 1, "Reached timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOut, iFrame );
|
||||
else if ( p->pPars->nTimeOutGap && p->pPars->timeLastSolved && Abc_Clock() > p->pPars->timeLastSolved + p->pPars->nTimeOutGap * CLOCKS_PER_SEC )
|
||||
Abc_Print( 1, "Reached gap timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOutGap, iFrame );
|
||||
|
|
@ -1379,7 +1379,7 @@ int Pdr_ManSolveInt( Pdr_Man_t * p )
|
|||
{
|
||||
if ( p->pPars->fVerbose )
|
||||
Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
|
||||
if ( p->timeToStop && Abc_Clock() > p->timeToStop )
|
||||
if ( p->timeToStop && Abc_Clock() > p->timeToStop && !p->pPars->fSilent )
|
||||
Abc_Print( 1, "Reached timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOut, iFrame );
|
||||
else if ( p->pPars->nTimeOutGap && p->pPars->timeLastSolved && Abc_Clock() > p->pPars->timeLastSolved + p->pPars->nTimeOutGap * CLOCKS_PER_SEC )
|
||||
Abc_Print( 1, "Reached gap timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOutGap, iFrame );
|
||||
|
|
|
|||
|
|
@ -1040,8 +1040,10 @@ int Ssw_RarSimulate( Aig_Man_t * pAig, Ssw_RarPars_t * pPars )
|
|||
Abc_Print( 1, "Simulated %d frames for %d rounds with %d restarts.\n", pPars->nFrames, nNumRestart * pPars->nRestart + r, nNumRestart );
|
||||
pAig->pSeqModel = Ssw_RarDeriveCex( p, r * p->pPars->nFrames + f, p->iFailPo, p->iFailPat, pPars->fVerbose );
|
||||
// print final report
|
||||
Abc_Print( 1, "Output %d of miter \"%s\" was asserted in frame %d. ", pAig->pSeqModel->iPo, pAig->pName, pAig->pSeqModel->iFrame );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clkTotal );
|
||||
if ( !pPars->fSilent ) {
|
||||
Abc_Print( 1, "Output %d of miter \"%s\" was asserted in frame %d. ", pAig->pSeqModel->iPo, pAig->pName, pAig->pSeqModel->iFrame );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clkTotal );
|
||||
}
|
||||
goto finish;
|
||||
}
|
||||
timeLastSolved = Abc_Clock();
|
||||
|
|
|
|||
|
|
@ -421,9 +421,11 @@ int Bmcg_ManPerformOne( Gia_Man_t * pGia, Bmc_AndPar_t * pPars )
|
|||
break;
|
||||
}
|
||||
p->timeOth = Abc_Clock() - clkStart - p->timeUnf - p->timeCnf - p->timeSmp - p->timeSat;
|
||||
if ( RetValue == -1 && !pPars->fNotVerbose )
|
||||
printf( "No output failed in %d frames. ", f + (k < pPars->nFramesAdd ? k+1 : 0) );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clkStart );
|
||||
if ( !pPars->fNotVerbose ) {
|
||||
if ( RetValue == -1 && !pPars->fNotVerbose )
|
||||
printf( "No output failed in %d frames. ", f + (k < pPars->nFramesAdd ? k+1 : 0) );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clkStart );
|
||||
}
|
||||
Bmcg_ManPrintTime( p );
|
||||
Bmcg_ManStop( p );
|
||||
return RetValue;
|
||||
|
|
|
|||
|
|
@ -3728,10 +3728,170 @@ void Exa_ManExactSynthesis6( Bmc_EsPar_t * pPars, char * pFileName )
|
|||
if ( pMini ) Mini_AigStop( pMini );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Exa7_AddClause( FILE * pFile, int * pLits, int nLits )
|
||||
{
|
||||
int i, k = 0;
|
||||
for ( i = 0; i < nLits; i++ ) {
|
||||
if ( pLits[i] == 1 )
|
||||
return 0;
|
||||
else if ( pLits[i] == 0 )
|
||||
continue;
|
||||
else
|
||||
pLits[k++] = pLits[i];
|
||||
}
|
||||
nLits = k;
|
||||
assert( nLits > 0 );
|
||||
if ( pFile )
|
||||
{
|
||||
for ( i = 0; i < nLits; i++ )
|
||||
fprintf( pFile, "%s%d ", Abc_LitIsCompl(pLits[i]) ? "-" : "", Abc_Lit2Var(pLits[i]) );
|
||||
fprintf( pFile, "0\n" );
|
||||
}
|
||||
if ( 0 )
|
||||
{
|
||||
for ( i = 0; i < nLits; i++ )
|
||||
fprintf( stdout, "%s%d ", Abc_LitIsCompl(pLits[i]) ? "-" : "", Abc_Lit2Var(pLits[i])-1 );
|
||||
fprintf( stdout, "\n" );
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
static inline int Exa7_AddClause4( FILE * pFile, int Lit0, int Lit1, int Lit2, int Lit3 )
|
||||
{
|
||||
int pLits[4] = { Lit0, Lit1, Lit2, Lit3 };
|
||||
return Exa7_AddClause( pFile, pLits, 4 );
|
||||
}
|
||||
int Exa7_GetVar( int n, int i, int j, int m )
|
||||
{
|
||||
return 1 + n*n*m + n*i + j;
|
||||
}
|
||||
int Exa7_ManGenCnf( char * pFileName, word * pTruth, int nVars, int nNodes, int GateSize )
|
||||
{
|
||||
int m, n, v, k, nV = nVars + nNodes, nMints = 1 << nVars, nClas = 0;
|
||||
int pVars[32] = {0}; assert( nVars + nNodes + 1 < 32 );
|
||||
FILE * pFile = fopen( pFileName, "wb" );
|
||||
fputs( "p cnf \n", pFile );
|
||||
for ( m = 0; m < nMints; m++ )
|
||||
{
|
||||
for ( v = 0; v < nVars; v++ )
|
||||
nClas += Exa7_AddClause4( pFile, Abc_Var2Lit(Exa7_GetVar(nV, v, v, m), ((m >> v)&1)==0), 0, 0, 0 );
|
||||
nClas += Exa7_AddClause4( pFile, Abc_Var2Lit(Exa7_GetVar(nV, nV-1, nV-1, m), ((pTruth[0] >> m)&1)==0), 0, 0, 0 );
|
||||
for ( n = nVars; n < nV; n++ )
|
||||
{
|
||||
int iValNode = Exa7_GetVar(nV, n, n, m);
|
||||
for ( v = 0; v < n; v++ )
|
||||
{
|
||||
int iParVar = Exa7_GetVar(nV, v, n, 0); // v < n
|
||||
int iFanVar = Exa7_GetVar(nV, n, v, m);
|
||||
int iValFan = Exa7_GetVar(nV, v, v, m);
|
||||
// iFanVar = ~iParVar | iValFan
|
||||
nClas += Exa7_AddClause4( pFile, Abc_Var2Lit(iFanVar, 1), Abc_Var2Lit(iParVar, 1), Abc_Var2Lit(iValFan, 0), 0 );
|
||||
nClas += Exa7_AddClause4( pFile, Abc_Var2Lit(iFanVar, 0), Abc_Var2Lit(iParVar, 0), 0, 0 );
|
||||
nClas += Exa7_AddClause4( pFile, Abc_Var2Lit(iFanVar, 0), Abc_Var2Lit(iValFan, 1), 0, 0 );
|
||||
// iParVar & ~iValFan => iValNode
|
||||
nClas += Exa7_AddClause4( pFile, Abc_Var2Lit(iParVar, 1), Abc_Var2Lit(iValFan, 0), Abc_Var2Lit(iValNode, 0), 0 );
|
||||
pVars[v] = Abc_Var2Lit(iFanVar, 1);
|
||||
}
|
||||
pVars[v] = Abc_Var2Lit(iValNode, 1);
|
||||
// (iFanVar0 & iFanVar1 & iFanVar2) => ~iValNode
|
||||
nClas += Exa7_AddClause( pFile, pVars, n+1 );
|
||||
}
|
||||
}
|
||||
for ( n = nVars; n < nV; n++ ) {
|
||||
for ( v = 0; v < n; v++ )
|
||||
pVars[v] = Abc_Var2Lit(Exa7_GetVar(nV, v, n, 0), 0); // v < n
|
||||
nClas += Exa7_AddClause( pFile, pVars, n );
|
||||
if ( GateSize ) {
|
||||
int Total = 1 << n, Limit = GateSize + 1;
|
||||
for ( m = 0; m < Total; m++ )
|
||||
{
|
||||
if ( Abc_TtCountOnes((word)m) != Limit )
|
||||
continue;
|
||||
for ( k = v = 0; v < n; v++ )
|
||||
if ( (m >> v) & 1 )
|
||||
pVars[k++] = Abc_Var2Lit(Exa7_GetVar(nV, v, n, 0), 1);
|
||||
assert( k == Limit );
|
||||
nClas += Exa7_AddClause( pFile, pVars, Limit );
|
||||
}
|
||||
}
|
||||
}
|
||||
rewind( pFile );
|
||||
fprintf( pFile, "p cnf %d %d", nMints * nV * nV, nClas );
|
||||
fclose( pFile );
|
||||
return nClas;
|
||||
}
|
||||
void Exa_ManDumpVerilog( Vec_Int_t * vValues, int nVars, int nNodes, int GateSize, word * pTruth )
|
||||
{
|
||||
FILE * pFile;
|
||||
char Buffer[1000];
|
||||
char FileName[1100];
|
||||
int v, n, k, nV = nVars+nNodes;
|
||||
Extra_PrintHexadecimalString( Buffer, (unsigned *)pTruth, nVars );
|
||||
sprintf( FileName, "func%s_%d_%d.v", Buffer, GateSize, nNodes );
|
||||
pFile = fopen( FileName, "wb" );
|
||||
fprintf( pFile, "// Realization of the %d-input function %s using %d NAND gates:\n", nVars, Buffer, nNodes );
|
||||
fprintf( pFile, "module func%s_%d_%d ( input", Buffer, GateSize, nNodes );
|
||||
for ( v = 0; v < nVars; v++ )
|
||||
fprintf( pFile, " %c,", 'a'+v );
|
||||
fprintf( pFile, " output out );\n" );
|
||||
for ( n = nVars; n < nV; n++ ) {
|
||||
int nFans = 0;
|
||||
for ( v = 0; v < n; v++ )
|
||||
nFans += Vec_IntEntry(vValues, Exa7_GetVar(nV, v, n, 0));
|
||||
fprintf( pFile, " wire %c = ~(", 'a'+n );
|
||||
for ( k = v = 0; v < n; v++ )
|
||||
if ( Vec_IntEntry(vValues, Exa7_GetVar(nV, v, n, 0)) )
|
||||
fprintf( pFile, "%c%s", 'a'+v, ++k < nFans ? " & ":"" );
|
||||
fprintf( pFile, ");\n" );
|
||||
}
|
||||
fprintf( pFile, " assign out = %c;\n", 'a'+nV-1 );
|
||||
fprintf( pFile, "endmodule\n\n" );
|
||||
fclose( pFile );
|
||||
printf( "Solution was dumped into file \"%s\".\n", FileName );
|
||||
}
|
||||
void Exa_ManExactSynthesis7( Bmc_EsPar_t * pPars, int GateSize )
|
||||
{
|
||||
abctime clkTotal = Abc_Clock();
|
||||
int v, n, nMints = 1 << pPars->nVars;
|
||||
int nV = pPars->nVars + pPars->nNodes;
|
||||
word pTruth[16]; Abc_TtReadHex( pTruth, pPars->pTtStr );
|
||||
Vec_Int_t * vValues = NULL;
|
||||
char * pFileNameIn = "_temp_.cnf";
|
||||
char * pFileNameOut = "_temp_out.cnf";
|
||||
int nClas = Exa7_ManGenCnf( pFileNameIn, pTruth, pPars->nVars, pPars->nNodes, GateSize );
|
||||
if ( pPars->fVerbose )
|
||||
printf( "CNF with %d variables and %d clauses was dumped into file \"%s\".\n", nMints * nV * nV, nClas, pFileNameIn );
|
||||
vValues = Exa4_ManSolve( pFileNameIn, pFileNameOut, pPars->RuntimeLim, pPars->fVerbose );
|
||||
if ( pPars->fVerbose && vValues ) {
|
||||
printf( " " );
|
||||
for ( n = 0; n < nV; n++ )
|
||||
printf( "%2d ", n );
|
||||
printf( "\n" );
|
||||
for ( n = pPars->nVars; n < nV; n++, printf("\n") ) {
|
||||
printf( "%2d : ", n );
|
||||
for ( v = 0; v < n; v++ )
|
||||
printf( " %c ", Vec_IntEntry(vValues, Exa7_GetVar(nV, v, n, 0)) ? '1':'.' ); // v < n
|
||||
}
|
||||
}
|
||||
if ( vValues )
|
||||
Exa_ManDumpVerilog( vValues, pPars->nVars, pPars->nNodes, GateSize, pTruth );
|
||||
Vec_IntFreeP( &vValues );
|
||||
Abc_PrintTime( 1, "Total runtime", Abc_Clock() - clkTotal );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,9 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
|
|||
#ifndef Minisat_Alg_h
|
||||
#define Minisat_Alg_h
|
||||
|
||||
#include "Vec.h"
|
||||
#include "sat/bsat2/Vec.h"
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
namespace Minisat {
|
||||
|
||||
|
|
@ -81,4 +83,6 @@ static inline void append(const vec<T>& from, vec<T>& to){ copy(from, to, true);
|
|||
//=================================================================================================
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_END
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -21,8 +21,10 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
|
|||
#ifndef Minisat_Alloc_h
|
||||
#define Minisat_Alloc_h
|
||||
|
||||
#include "XAlloc.h"
|
||||
#include "Vec.h"
|
||||
#include "sat/bsat2/XAlloc.h"
|
||||
#include "sat/bsat2/Vec.h"
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
namespace Minisat {
|
||||
|
||||
|
|
@ -136,4 +138,6 @@ RegionAllocator<T>::alloc(int size)
|
|||
//=================================================================================================
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_END
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -23,8 +23,10 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ParseUtils.h"
|
||||
#include "SolverTypes.h"
|
||||
#include "sat/bsat2/ParseUtils.h"
|
||||
#include "sat/bsat2/SolverTypes.h"
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
namespace Minisat {
|
||||
|
||||
|
|
@ -86,4 +88,6 @@ static void parse_DIMACS(gzFile input_stream, Solver& S) {
|
|||
//=================================================================================================
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_END
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -21,7 +21,9 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
|
|||
#ifndef Minisat_Heap_h
|
||||
#define Minisat_Heap_h
|
||||
|
||||
#include "Vec.h"
|
||||
#include "sat/bsat2/Vec.h"
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
namespace Minisat {
|
||||
|
||||
|
|
@ -146,4 +148,6 @@ class Heap {
|
|||
//=================================================================================================
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_END
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -44,4 +44,6 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
|
|||
|
||||
//=================================================================================================
|
||||
|
||||
#include <misc/util/abc_namespaces.h>
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -23,11 +23,13 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
|
|||
#include <signal.h>
|
||||
#include "misc/zlib/zlib.h"
|
||||
|
||||
#include "System.h"
|
||||
#include "ParseUtils.h"
|
||||
#include "Options.h"
|
||||
#include "Dimacs.h"
|
||||
#include "Solver.h"
|
||||
#include "sat/bsat2/System.h"
|
||||
#include "sat/bsat2/ParseUtils.h"
|
||||
#include "sat/bsat2/Options.h"
|
||||
#include "sat/bsat2/Dimacs.h"
|
||||
#include "sat/bsat2/Solver.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
using namespace Minisat;
|
||||
|
||||
|
|
@ -195,3 +197,6 @@ extern "C" int MainSat(int argc, char** argv)
|
|||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
|
|
|||
|
|
@ -27,11 +27,13 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
|
|||
#include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
#include "System.h"
|
||||
#include "ParseUtils.h"
|
||||
#include "Options.h"
|
||||
#include "Dimacs.h"
|
||||
#include "SimpSolver.h"
|
||||
#include "sat/bsat2/System.h"
|
||||
#include "sat/bsat2/ParseUtils.h"
|
||||
#include "sat/bsat2/Options.h"
|
||||
#include "sat/bsat2/Dimacs.h"
|
||||
#include "sat/bsat2/SimpSolver.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
using namespace Minisat;
|
||||
|
||||
|
|
@ -204,3 +206,6 @@ extern "C" int MainSimp(int argc, char** argv)
|
|||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
|
|
|||
|
|
@ -20,8 +20,10 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
|
|||
#ifndef Minisat_Map_h
|
||||
#define Minisat_Map_h
|
||||
|
||||
#include "IntTypes.h"
|
||||
#include "Vec.h"
|
||||
#include "sat/bsat2/IntTypes.h"
|
||||
#include "sat/bsat2/Vec.h"
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
namespace Minisat {
|
||||
|
||||
|
|
@ -190,4 +192,6 @@ class Map {
|
|||
//=================================================================================================
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_END
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -17,9 +17,11 @@ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|||
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**************************************************************************************************/
|
||||
|
||||
#include "Sort.h"
|
||||
#include "Options.h"
|
||||
#include "ParseUtils.h"
|
||||
#include "sat/bsat2/Sort.h"
|
||||
#include "sat/bsat2/Options.h"
|
||||
#include "sat/bsat2/ParseUtils.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
using namespace Minisat;
|
||||
|
||||
|
|
@ -43,10 +45,12 @@ int Minisat::parseOptions(int& argc, char** argv, bool strict)
|
|||
}
|
||||
|
||||
if (!parsed_ok)
|
||||
{
|
||||
if (strict && match(argv[i], "-"))
|
||||
{ fprintf(stderr, "ERROR! Unknown flag \"%s\". Use '--%shelp' for help.\n", argv[i], Option::getHelpPrefixString()); return 0; } // exit(0);
|
||||
else
|
||||
argv[j++] = argv[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -91,3 +95,5 @@ int Minisat::printUsageAndExit (int argc, char** argv, bool verbose)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
|
|
|||
|
|
@ -25,9 +25,11 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
|
|||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "IntTypes.h"
|
||||
#include "Vec.h"
|
||||
#include "ParseUtils.h"
|
||||
#include "sat/bsat2/IntTypes.h"
|
||||
#include "sat/bsat2/Vec.h"
|
||||
#include "sat/bsat2/ParseUtils.h"
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
namespace Minisat {
|
||||
|
||||
|
|
@ -60,7 +62,7 @@ class Option
|
|||
struct OptionLt {
|
||||
bool operator()(const Option* x, const Option* y) {
|
||||
int test1 = strcmp(x->category, y->category);
|
||||
return test1 < 0 || test1 == 0 && strcmp(x->type_name, y->type_name) < 0;
|
||||
return test1 < 0 || ( test1 == 0 && strcmp(x->type_name, y->type_name) < 0 );
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -384,4 +386,6 @@ class BoolOption : public Option
|
|||
//=================================================================================================
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_END
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
|
|||
|
||||
#include "misc/zlib/zlib.h"
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
namespace Minisat {
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
|
@ -119,4 +121,6 @@ static bool eagerMatch(B& in, const char* str) {
|
|||
//=================================================================================================
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_END
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -21,7 +21,9 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
|
|||
#ifndef Minisat_Queue_h
|
||||
#define Minisat_Queue_h
|
||||
|
||||
#include "Vec.h"
|
||||
#include "sat/bsat2/Vec.h"
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
namespace Minisat {
|
||||
|
||||
|
|
@ -66,4 +68,6 @@ public:
|
|||
//=================================================================================================
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_END
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -18,9 +18,11 @@ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|||
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**************************************************************************************************/
|
||||
|
||||
#include "Sort.h"
|
||||
#include "SimpSolver.h"
|
||||
#include "System.h"
|
||||
#include "sat/bsat2/Sort.h"
|
||||
#include "sat/bsat2/SimpSolver.h"
|
||||
#include "sat/bsat2/System.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
using namespace Minisat;
|
||||
|
||||
|
|
@ -228,10 +230,12 @@ bool SimpSolver::merge(const Clause& _ps, const Clause& _qs, Var v, vec<Lit>& ou
|
|||
if (var(qs[i]) != v){
|
||||
for (j = 0; j < ps.size(); j++)
|
||||
if (var(ps[j]) == var(qs[i]))
|
||||
{
|
||||
if (ps[j] == ~qs[i])
|
||||
return false;
|
||||
else
|
||||
goto next;
|
||||
}
|
||||
out_clause.push(qs[i]);
|
||||
}
|
||||
next:;
|
||||
|
|
@ -262,10 +266,12 @@ bool SimpSolver::merge(const Clause& _ps, const Clause& _qs, Var v, int& size)
|
|||
if (var(__qs[i]) != v){
|
||||
for (int j = 0; j < ps.size(); j++)
|
||||
if (var(__ps[j]) == var(__qs[i]))
|
||||
{
|
||||
if (__ps[j] == ~__qs[i])
|
||||
return false;
|
||||
else
|
||||
goto next;
|
||||
}
|
||||
size++;
|
||||
}
|
||||
next:;
|
||||
|
|
@ -718,3 +724,5 @@ void SimpSolver::garbageCollect()
|
|||
ca.size()*ClauseAllocator::Unit_Size, to.size()*ClauseAllocator::Unit_Size);
|
||||
to.moveTo(ca);
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
|
@ -21,9 +21,10 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
|
|||
#ifndef Minisat_SimpSolver_h
|
||||
#define Minisat_SimpSolver_h
|
||||
|
||||
#include "Queue.h"
|
||||
#include "Solver.h"
|
||||
#include "sat/bsat2/Queue.h"
|
||||
#include "sat/bsat2/Solver.h"
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
namespace Minisat {
|
||||
|
||||
|
|
@ -194,4 +195,6 @@ inline lbool SimpSolver::solveLimited (const vec<Lit>& assumps, bool do_simp, bo
|
|||
//=================================================================================================
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_END
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -20,8 +20,10 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
|
|||
|
||||
#include <math.h>
|
||||
|
||||
#include "Sort.h"
|
||||
#include "Solver.h"
|
||||
#include "sat/bsat2/Sort.h"
|
||||
#include "sat/bsat2/Solver.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
using namespace Minisat;
|
||||
|
||||
|
|
@ -209,7 +211,7 @@ void Solver::cancelUntil(int level) {
|
|||
for (int c = trail.size()-1; c >= trail_lim[level]; c--){
|
||||
Var x = var(trail[c]);
|
||||
assigns [x] = l_Undef;
|
||||
if (phase_saving > 1 || (phase_saving == 1) && c > trail_lim.last())
|
||||
if (phase_saving > 1 || ((phase_saving == 1) && c > trail_lim.last()))
|
||||
polarity[x] = sign(trail[c]);
|
||||
insertVarOrder(x); }
|
||||
qhead = trail_lim[level];
|
||||
|
|
@ -657,7 +659,7 @@ lbool Solver::search(int nof_conflicts)
|
|||
|
||||
}else{
|
||||
// NO CONFLICT
|
||||
if (nof_conflicts >= 0 && conflictC >= nof_conflicts || !withinBudget()){
|
||||
if ( (nof_conflicts >= 0 && conflictC >= nof_conflicts) || !withinBudget()){
|
||||
// Reached bound on number of conflicts:
|
||||
progress_estimate = progressEstimate();
|
||||
cancelUntil(0);
|
||||
|
|
@ -922,3 +924,5 @@ void Solver::garbageCollect()
|
|||
ca.size()*ClauseAllocator::Unit_Size, to.size()*ClauseAllocator::Unit_Size);
|
||||
to.moveTo(ca);
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
|
|
|||
|
|
@ -21,12 +21,13 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
|
|||
#ifndef Minisat_Solver_h
|
||||
#define Minisat_Solver_h
|
||||
|
||||
#include "Vec.h"
|
||||
#include "Heap.h"
|
||||
#include "Alg.h"
|
||||
#include "Options.h"
|
||||
#include "SolverTypes.h"
|
||||
#include "sat/bsat2/Vec.h"
|
||||
#include "sat/bsat2/Heap.h"
|
||||
#include "sat/bsat2/Alg.h"
|
||||
#include "sat/bsat2/Options.h"
|
||||
#include "sat/bsat2/SolverTypes.h"
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
namespace Minisat {
|
||||
|
||||
|
|
@ -370,4 +371,6 @@ inline void Solver::toDimacs (const char* file, Lit p, Lit q, Lit r){ ve
|
|||
//=================================================================================================
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_END
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -24,11 +24,13 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
|
|||
|
||||
#include <assert.h>
|
||||
|
||||
#include "IntTypes.h"
|
||||
#include "Alg.h"
|
||||
#include "Vec.h"
|
||||
#include "Map.h"
|
||||
#include "Alloc.h"
|
||||
#include "sat/bsat2/IntTypes.h"
|
||||
#include "sat/bsat2/Alg.h"
|
||||
#include "sat/bsat2/Vec.h"
|
||||
#include "sat/bsat2/Map.h"
|
||||
#include "sat/bsat2/Alloc.h"
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
namespace Minisat {
|
||||
|
||||
|
|
@ -404,4 +406,6 @@ inline void Clause::strengthen(Lit p)
|
|||
//=================================================================================================
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_END
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -21,11 +21,12 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
|
|||
#ifndef Minisat_Sort_h
|
||||
#define Minisat_Sort_h
|
||||
|
||||
#include "Vec.h"
|
||||
#include "sat/bsat2/Vec.h"
|
||||
|
||||
//=================================================================================================
|
||||
// Some sorting algorithms for vec's
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
namespace Minisat {
|
||||
|
||||
|
|
@ -95,4 +96,6 @@ template <class T> void sort(vec<T>& v) {
|
|||
//=================================================================================================
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_END
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -18,13 +18,15 @@ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|||
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**************************************************************************************************/
|
||||
|
||||
#include "System.h"
|
||||
#include "sat/bsat2/System.h"
|
||||
|
||||
#if defined(__linux__)
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
using namespace Minisat;
|
||||
|
||||
// TODO: split the memory reading functions into two: one for reading high-watermark of RSS, and
|
||||
|
|
@ -72,24 +74,40 @@ double Minisat::memUsedPeak() {
|
|||
double peak = memReadPeak() / 1024;
|
||||
return peak == 0 ? memUsed() : peak; }
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
#elif defined(__FreeBSD__)
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
double Minisat::memUsed(void) {
|
||||
struct rusage ru;
|
||||
getrusage(RUSAGE_SELF, &ru);
|
||||
return (double)ru.ru_maxrss / 1024; }
|
||||
double MiniSat::memUsedPeak(void) { return memUsed(); }
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
#include <malloc/malloc.h>
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
double Minisat::memUsed(void) {
|
||||
malloc_statistics_t t;
|
||||
malloc_zone_statistics(NULL, &t);
|
||||
return (double)t.max_size_in_use / (1024*1024); }
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
#else
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
double Minisat::memUsed() { return 0; }
|
||||
double Minisat::memUsedPeak() { return 0; }
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -22,13 +22,15 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
|
|||
#define Minisat_System_h
|
||||
|
||||
#if defined(__linux__)
|
||||
#include <fpu_control.h>
|
||||
//#include <fpu_control.h>
|
||||
#endif
|
||||
|
||||
#include "IntTypes.h"
|
||||
#include "sat/bsat2/IntTypes.h"
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
namespace Minisat {
|
||||
|
||||
static inline double cpuTime(void); // CPU-time in seconds.
|
||||
|
|
@ -37,24 +39,35 @@ extern double memUsedPeak(); // Peak-memory in mega bytes (returns 0 for
|
|||
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_END
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// Implementation of inline functions:
|
||||
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
#include <time.h>
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
static inline double Minisat::cpuTime(void) { return (double)clock() / CLOCKS_PER_SEC; }
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_END
|
||||
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <unistd.h>
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
static inline double Minisat::cpuTime(void) {
|
||||
struct rusage ru;
|
||||
getrusage(RUSAGE_SELF, &ru);
|
||||
return (double)ru.ru_utime.tv_sec + (double)ru.ru_utime.tv_usec / 1000000; }
|
||||
|
||||
#endif
|
||||
ABC_NAMESPACE_CXX_HEADER_END
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue