Merge branch 'master' of https://github.com/berkeley-abc/abc into yosys-experimental

This commit is contained in:
Martin Povišer 2024-04-22 16:33:29 +02:00
commit 208b48667f
106 changed files with 11824 additions and 311 deletions

1
.gitignore vendored
View File

@ -61,3 +61,4 @@ tags
/cmake
/cscope
abc.history

View File

@ -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

View File

@ -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

View 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] ) );

View File

@ -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

View File

@ -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.]

1374
src/aig/gia/giaBound.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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() )

View File

@ -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 ///
////////////////////////////////////////////////////////////////////////

View 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;
}

View File

@ -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 )

View File

@ -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 )

View File

@ -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 ///

View 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 ///
////////////////////////////////////////////////////////////////////////

View 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;
}

View File

@ -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;

View File

@ -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) );

View File

@ -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 ///
////////////////////////////////////////////////////////////////////////

View 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

View File

@ -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 );

File diff suppressed because it is too large Load Diff

View File

@ -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 );

View File

@ -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 )
{

View File

@ -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 )

View File

@ -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 ///

View 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;

View File

@ -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] );
}

View File

@ -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 ///

View 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 )

View File

@ -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 ///

View 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 []

View File

@ -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 ///
////////////////////////////////////////////////////////////////////////

View 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 );

View File

@ -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 );

View File

@ -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 );

View File

@ -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 ///
////////////////////////////////////////////////////////////////////////

View 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;

View File

@ -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 );

View File

@ -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) )

View File

@ -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");

View File

@ -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

View File

@ -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

View File

@ -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

1233
src/map/if/acd/acd66.hpp Normal file

File diff suppressed because it is too large Load Diff

1258
src/map/if/acd/acdXX.hpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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_

View File

@ -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_

View File

@ -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_

View File

@ -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_

View File

@ -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_

View File

@ -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_

View File

@ -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_

View File

@ -0,0 +1 @@
SRC += src/map/if/acd/ac_wrapper.cpp

View File

@ -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

View File

@ -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 );

View File

@ -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) )
{

335
src/map/if/ifDec66.c Normal file
View File

@ -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

View File

@ -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 )
{

View File

@ -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

View File

@ -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 )

View File

@ -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 \

View File

@ -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 );

View File

@ -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 )

View File

@ -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 );

View File

@ -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 );

View File

@ -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;

View File

@ -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 )
{

View File

@ -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 );

View File

@ -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 )

View File

@ -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

View File

@ -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;

View File

@ -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

341
src/proof/cec/cecProve.c Normal file
View File

@ -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

View File

@ -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 )

View File

@ -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 \

View File

@ -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 );

View File

@ -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();

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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