mirror of https://github.com/YosysHQ/abc.git
Merge remote-tracking branch 'upstream/master' into yosys-experimental
This commit is contained in:
commit
bf64a92253
|
|
@ -1,4 +1,8 @@
|
|||
on: [push]
|
||||
name: Build Posix CMake
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
on: [push]
|
||||
name: Build Posix
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
on: [push]
|
||||
name: Build Windows
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
cmake_minimum_required(VERSION 3.3.0)
|
||||
cmake_minimum_required(VERSION 3.5.0)
|
||||
|
||||
include(CMakeParseArguments)
|
||||
include(CheckCCompilerFlag)
|
||||
include(CheckCXXCompilerFlag)
|
||||
|
||||
# Default c++ standard used unless otherwise specified in target_compile_features.
|
||||
set(CMAKE_CXX_STANDARD 17 CACHE STRING "the C++ standard to use for this project")
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
function(addprefix var prefix)
|
||||
foreach( s ${ARGN} )
|
||||
list(APPEND tmp "-I${s}")
|
||||
|
|
|
|||
2
Makefile
2
Makefile
|
|
@ -152,7 +152,7 @@ ifdef ABC_USE_LIBSTDCXX
|
|||
endif
|
||||
|
||||
$(info $(MSG_PREFIX)Using CFLAGS=$(CFLAGS))
|
||||
CXXFLAGS += $(CFLAGS) -std=c++11
|
||||
CXXFLAGS += $(CFLAGS) -std=c++17 -fno-exceptions
|
||||
|
||||
SRC :=
|
||||
GARBAGE := core core.* *.stackdump ./tags $(PROG) arch_flags
|
||||
|
|
|
|||
2
abc.rc
2
abc.rc
|
|
@ -135,6 +135,8 @@ alias resyn2rs "b; rs -K 6; rw; rs -K 6 -N 2; rf; rs -K 8; b; rs -K 8 -N 2; r
|
|||
alias r2rs "b; rs -K 6; rw; rs -K 6 -N 2; rf; rs -K 8; b; rs -K 8 -N 2; rw; rs -K 10; rwz; rs -K 10 -N 2; b; rs -K 12; rfz; rs -K 12 -N 2; rwz; b"
|
||||
alias compress2rs "b -l; rs -K 6 -l; rw -l; rs -K 6 -N 2 -l; rf -l; rs -K 8 -l; b -l; rs -K 8 -N 2 -l; rw -l; rs -K 10 -l; rwz -l; rs -K 10 -N 2 -l; b -l; rs -K 12 -l; rfz -l; rs -K 12 -N 2 -l; rwz -l; b -l"
|
||||
alias c2rs "b -l; rs -K 6 -l; rw -l; rs -K 6 -N 2 -l; rf -l; rs -K 8 -l; b -l; rs -K 8 -N 2 -l; rw -l; rs -K 10 -l; rwz -l; rs -K 10 -N 2 -l; b -l; rs -K 12 -l; rfz -l; rs -K 12 -N 2 -l; rwz -l; b -l"
|
||||
alias &resyn2rs "&put; resyn2rs; &get"
|
||||
alias &compress2rs "&put; compress2rs; &get"
|
||||
|
||||
# use this script to convert 1-valued and DC-valued flops for an AIG
|
||||
alias fix_aig "logic; undc; strash; zero"
|
||||
|
|
|
|||
20
abclib.dsp
20
abclib.dsp
|
|
@ -1195,6 +1195,10 @@ SOURCE=.\src\bdd\extrab\extraBdd.h
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\bdd\extrab\extraLutCas.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\bdd\extrab\extraBddAuto.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
@ -4151,6 +4155,10 @@ SOURCE=.\src\misc\util\utilNam.h
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\misc\util\utilPth.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\misc\util\utilSignal.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
@ -5123,6 +5131,10 @@ SOURCE=.\src\aig\gia\giaMinLut2.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\gia\giaMulFind.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\gia\giaMuxes.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
@ -5370,14 +5382,6 @@ SOURCE=.\src\aig\miniaig\minilut.h
|
|||
SOURCE=.\src\aig\miniaig\ndr.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "uap"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\uap\uap.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Group
|
||||
# Begin Group "bool"
|
||||
|
||||
|
|
|
|||
24
readmeaig
24
readmeaig
|
|
@ -45,3 +45,27 @@ Using GIA Package in ABC
|
|||
- For each object in the design annotated with the constructed AIG node (pNode), remember its AIG node ID by calling Gia_ObjId(pMan,pNode).
|
||||
- Quit the AIG package using Gia_ManStop().
|
||||
The above process should not produce memory leaks.
|
||||
|
||||
|
||||
|
||||
|
||||
Using MiniAIG Package
|
||||
|
||||
- Add #include "miniaig.h".
|
||||
- Start the AIG package using Mini_AigStart().
|
||||
- Assign primary inputs using Mini_AigCreatePi().
|
||||
- Assign flop outputs using Mini_AigCreatePi().
|
||||
(It is important to create all PIs first, before creating flop outputs.)
|
||||
(Flop control logic, if present, should be elaborated into AND gates. For example, to represent a flop enable, create the driver of enable signal, which can be a PI or an internal node, and then add logic for <flop_input_new> = MUX( <enable>, <flop_input>, <flop_output> ). The output of this logic feeds into the flop.
|
||||
- Construct AIG in a topological order using Mini_AigAnd(), Mini_AigOr(), etc.
|
||||
- If constant-0 or constant-1 functions are needed, use 0 or 1.
|
||||
- Create primary outputs using Mini_AigCreatePo().
|
||||
- Create flop inputs using Mini_AigCreatePo().
|
||||
(It is important to create all POs first, before creating register inputs.)
|
||||
- Set the number of flops by calling Mini_AigSetRegNum().
|
||||
- The AIG may contain internal nodes without fanout and/or internal nodes fed by constants.
|
||||
- Dump AIG in internal MiniAIG binary format using Mini_AigDump() and read it into ABC using "&read -m file.mini"
|
||||
- Dump AIG in standard AIGER format (https://fmv.jku.at/aiger/index.html) using Mini_AigerWrite() and read it into ABC using "&read file.aig"
|
||||
- For each object in the design represented using MiniAIG, it may be helpful to save the MiniAIG literal returned by Mini_AigAnd(), Mini_AigOr(), etc when constructing that object.
|
||||
- Quit the AIG package using Mini_AigStop().
|
||||
The above process should not produce memory leaks.
|
||||
|
|
|
|||
|
|
@ -344,7 +344,7 @@ void Aig_ManShow( Aig_Man_t * pMan, int fHaig, Vec_Ptr_t * vBold )
|
|||
char FileNameDot[200];
|
||||
FILE * pFile;
|
||||
// create the file name
|
||||
sprintf( FileNameDot, "%s", Extra_FileNameGenericAppend(pMan->pName, ".dot") );
|
||||
sprintf( FileNameDot, "%s", Extra_FileNameGenericAppend(pMan->pName ? pMan->pName : (char *)"unknown", ".dot") );
|
||||
// check that the file can be opened
|
||||
if ( (pFile = fopen( FileNameDot, "w" )) == NULL )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1169,8 +1169,13 @@ void Aig_ManRandomTest1()
|
|||
***********************************************************************/
|
||||
unsigned Aig_ManRandom( int fReset )
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
static unsigned int m_z = NUMBER1;
|
||||
static unsigned int m_w = NUMBER2;
|
||||
#else
|
||||
static __thread unsigned int m_z = NUMBER1;
|
||||
static __thread unsigned int m_w = NUMBER2;
|
||||
#endif
|
||||
if ( fReset )
|
||||
{
|
||||
m_z = NUMBER1;
|
||||
|
|
|
|||
|
|
@ -243,7 +243,12 @@ struct Gia_Man_t_
|
|||
Gia_Dat_t * pUData;
|
||||
// retiming data
|
||||
Vec_Str_t * vStopsF;
|
||||
Vec_Str_t * vStopsB;
|
||||
Vec_Str_t * vStopsB;
|
||||
// iteration with boxes
|
||||
int iFirstNonPiId;
|
||||
int iFirstPoId;
|
||||
int iFirstAndObj;
|
||||
int iFirstPoObj;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -1243,7 +1248,16 @@ static inline int Gia_ObjCellId( Gia_Man_t * p, int iLit ) { re
|
|||
for ( i = 0; (i < Gia_ManRegNum(p)) && ((pObjRi) = Gia_ManCo(p, Gia_ManPoNum(p)+i)) && ((pObjRo) = Gia_ManCi(p, Gia_ManPiNum(p)+i)); i++ )
|
||||
#define Gia_ManForEachRoToRiVec( vRoIds, p, pObj, i ) \
|
||||
for ( i = 0; (i < Vec_IntSize(vRoIds)) && ((pObj) = Gia_ObjRoToRi(p, Gia_ManObj(p, Vec_IntEntry(vRoIds, i)))); i++ )
|
||||
|
||||
|
||||
#define Gia_ManForEachObjWithBoxes( p, pObj, i ) \
|
||||
for ( i = p->iFirstAndObj; (i < p->iFirstPoObj) && ((pObj) = Gia_ManObj(p, i)); i++ )
|
||||
#define Gia_ManForEachObjReverseWithBoxes( p, pObj, i ) \
|
||||
for ( i = p->iFirstPoObj - 1; (i >= p->iFirstAndObj) && ((pObj) = Gia_ManObj(p, i)); i-- )
|
||||
#define Gia_ManForEachCiIdWithBoxes( p, Id, i ) \
|
||||
for ( i = 0; (i < p->iFirstNonPiId) && ((Id) = Gia_ObjId(p, Gia_ManCi(p, i))); i++ )
|
||||
#define Gia_ManForEachCoWithBoxes( p, pObj, i ) \
|
||||
for ( i = p->iFirstPoId; (i < Vec_IntSize(p->vCos)) && ((pObj) = Gia_ManCo(p, i)); i++ )
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1673,6 +1687,7 @@ extern int Gia_SweeperRun( Gia_Man_t * p, Vec_Int_t * vProbeIds,
|
|||
extern float Gia_ManEvaluateSwitching( Gia_Man_t * p );
|
||||
extern float Gia_ManComputeSwitching( Gia_Man_t * p, int nFrames, int nPref, int fProbOne );
|
||||
extern Vec_Int_t * Gia_ManComputeSwitchProbs( Gia_Man_t * pGia, int nFrames, int nPref, int fProbOne );
|
||||
extern Vec_Int_t * Gia_ManComputeSwitchProbs2( Gia_Man_t * pGia, int nFrames, int nPref, int fProbOne, int nRandPiFactor );
|
||||
extern Vec_Flt_t * Gia_ManPrintOutputProb( Gia_Man_t * p );
|
||||
/*=== giaTim.c ===========================================================*/
|
||||
extern int Gia_ManBoxNum( Gia_Man_t * p );
|
||||
|
|
|
|||
|
|
@ -382,7 +382,7 @@ Gia_Man_t * Gia_ManCollapseTest( Gia_Man_t * p, int fVerbose )
|
|||
Vec_Ptr_t * vNamesCo = Gia_GetFakeNames( Gia_ManCoNum(p) );
|
||||
char ** ppNamesCi = (char **)Vec_PtrArray( vNamesCi );
|
||||
char ** ppNamesCo = (char **)Vec_PtrArray( vNamesCo );
|
||||
Dsd_TreePrint( stdout, pManDsd, ppNamesCi, ppNamesCo, 0, -1 );
|
||||
Dsd_TreePrint( stdout, pManDsd, ppNamesCi, ppNamesCo, 0, -1, 0 );
|
||||
Vec_PtrFreeFree( vNamesCi );
|
||||
Vec_PtrFreeFree( vNamesCo );
|
||||
}
|
||||
|
|
@ -404,6 +404,43 @@ void Gia_ManCollapseTestTest( Gia_Man_t * p )
|
|||
Gia_ManStop( pNew );
|
||||
}
|
||||
|
||||
void Gia_ManCheckDsd( Gia_Man_t * p, int OffSet, int fVerbose )
|
||||
{
|
||||
DdManager * dd;
|
||||
Dsd_Manager_t * pManDsd;
|
||||
Vec_Ptr_t * vFuncs;
|
||||
dd = Cudd_Init( Gia_ManCiNum(p), 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
|
||||
Cudd_AutodynEnable( dd, CUDD_REORDER_SYMM_SIFT );
|
||||
vFuncs = Gia_ManCollapse( p, dd, 10000, 0 );
|
||||
Cudd_AutodynDisable( dd );
|
||||
if ( vFuncs == NULL )
|
||||
{
|
||||
Extra_StopManager( dd );
|
||||
return;
|
||||
}
|
||||
pManDsd = Dsd_ManagerStart( dd, Gia_ManCiNum(p), 0 );
|
||||
if ( pManDsd == NULL )
|
||||
{
|
||||
Gia_ManCollapseDeref( dd, vFuncs );
|
||||
Cudd_Quit( dd );
|
||||
return;
|
||||
}
|
||||
Dsd_Decompose( pManDsd, (DdNode **)vFuncs->pArray, Gia_ManCoNum(p) );
|
||||
if ( fVerbose )
|
||||
{
|
||||
Vec_Ptr_t * vNamesCi = Gia_GetFakeNames( Gia_ManCiNum(p) );
|
||||
Vec_Ptr_t * vNamesCo = Gia_GetFakeNames( Gia_ManCoNum(p) );
|
||||
char ** ppNamesCi = (char **)Vec_PtrArray( vNamesCi );
|
||||
char ** ppNamesCo = (char **)Vec_PtrArray( vNamesCo );
|
||||
Dsd_TreePrint( stdout, pManDsd, ppNamesCi, ppNamesCo, 0, -1, OffSet );
|
||||
Vec_PtrFreeFree( vNamesCi );
|
||||
Vec_PtrFreeFree( vNamesCo );
|
||||
}
|
||||
Dsd_ManagerStop( pManDsd );
|
||||
Gia_ManCollapseDeref( dd, vFuncs );
|
||||
Extra_StopManager( dd );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
Gia_Man_t * Gia_ManCollapseTest( Gia_Man_t * p, int fVerbose )
|
||||
|
|
@ -411,6 +448,10 @@ Gia_Man_t * Gia_ManCollapseTest( Gia_Man_t * p, int fVerbose )
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void Gia_ManCheckDsd( Gia_Man_t * p, int OffSet, int fVerbose )
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -993,6 +993,97 @@ Gia_Man_t * Gia_ManDupCofAll( Gia_Man_t * p, int nFanLim, int fVerbose )
|
|||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Print the matrix.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Gia_Man_t * Gia_ManDsdMatrix( Gia_Man_t * p, int iIn )
|
||||
{
|
||||
Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj; int i, j;
|
||||
Vec_Int_t * vRes = Vec_IntAlloc( 100 );
|
||||
assert( Gia_ManPoNum(p) == 1 );
|
||||
assert( iIn >= 0 && iIn < Gia_ManPiNum(p) );
|
||||
pNew = Gia_ManStart( Gia_ManObjNum(p) );
|
||||
pNew->pName = Abc_UtilStrsav( p->pName );
|
||||
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
|
||||
Gia_ManHashAlloc( pNew );
|
||||
Gia_ManFillValue( p );
|
||||
Gia_ManConst0(p)->Value = 0;
|
||||
Gia_ManForEachCi( p, pObj, i )
|
||||
pObj->Value = Gia_ManAppendCi(pNew);
|
||||
for ( i = 0; i < Gia_ManPiNum(p); i++ ) if ( i != iIn )
|
||||
for ( j = i+1; j < Gia_ManPiNum(p); j++ ) if ( j != iIn )
|
||||
{
|
||||
int pRes[8], k, n;
|
||||
int iLit0 = Gia_ManPi(p, iIn)->Value;
|
||||
int iLit1 = Gia_ManPi(p, i)->Value;
|
||||
int iLit2 = Gia_ManPi(p, j)->Value;
|
||||
for ( k = 0; k < 8; k++ )
|
||||
{
|
||||
Gia_ManPi(p, iIn)->Value = k & 1;
|
||||
Gia_ManPi(p, i)->Value = (k >> 1) & 1;
|
||||
Gia_ManPi(p, j)->Value = (k >> 2) & 1;
|
||||
Gia_ManForEachAnd( p, pObj, n )
|
||||
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
pRes[k] = Gia_ObjFanin0Copy(Gia_ManPo(p, 0));
|
||||
}
|
||||
Gia_ManPi(p, iIn)->Value = iLit0;
|
||||
Gia_ManPi(p, i)->Value = iLit1;
|
||||
Gia_ManPi(p, j)->Value = iLit2;
|
||||
for ( k = 0; k < 4; k++ )
|
||||
pRes[k] = Gia_ManHashXor( pNew, pRes[2*k], pRes[2*k+1] );
|
||||
Vec_IntPush( vRes, Gia_ManHashXor(pNew, Gia_ManHashAnd(pNew, pRes[0], pRes[3]), Gia_ManHashAnd(pNew, pRes[1], pRes[2])) );
|
||||
}
|
||||
Vec_IntForEachEntry( vRes, j, i )
|
||||
Gia_ManAppendCo( pNew, j );
|
||||
Vec_IntFree( vRes );
|
||||
pNew = Gia_ManCleanup( pTemp = pNew );
|
||||
Gia_ManStop( pTemp );
|
||||
return pNew;
|
||||
}
|
||||
void Gia_ManPrintDsdMatrix( Gia_Man_t * p, int iIn )
|
||||
{
|
||||
extern Gia_Man_t * Cec4_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose );
|
||||
Gia_Man_t * pNew = Gia_ManDsdMatrix( p, iIn ); int i, j, fFirst = 1, Count = 0;
|
||||
Gia_Man_t * pSweep = Cec4_ManSimulateTest3( pNew, 0, 0 );
|
||||
Gia_ManStop( pNew );
|
||||
printf( "%4c : ", ' ' );
|
||||
for ( j = 0; j < Gia_ManPiNum(p); j++ )
|
||||
printf( "%4d", j );
|
||||
printf( "\n" );
|
||||
for ( i = 0; i < Gia_ManPiNum(p); i++, printf("\n"), fFirst = 1 )
|
||||
for ( j = 0; j < Gia_ManPiNum(p); j++ )
|
||||
{
|
||||
if ( fFirst )
|
||||
printf( "%4d : ", i ), fFirst = 0;
|
||||
if ( i == iIn )
|
||||
continue;
|
||||
if ( j == iIn )
|
||||
printf( "%4c", ' ' );
|
||||
else
|
||||
{
|
||||
if ( j > i ) {
|
||||
if ( Gia_ObjFaninLit0p(pSweep, Gia_ManPo(pSweep, Count++)) == 0 )
|
||||
printf( "%4c", '.' );
|
||||
else
|
||||
printf( "%4c", '+' );
|
||||
}
|
||||
else
|
||||
printf( "%4c", ' ' );
|
||||
}
|
||||
}
|
||||
assert( Count == Gia_ManPoNum(pSweep) );
|
||||
Gia_ManStop( pSweep );
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -986,10 +986,127 @@ Vec_Wec_t * Gia_ManExploreCuts( Gia_Man_t * pGia, int nCutSize0, int nCuts0, int
|
|||
Abc_PrintTime( 0, "Time", Abc_Clock() - p->clkStart );
|
||||
}
|
||||
vCutsSel = Gia_ManFilterCuts( pGia, p->vCuts, nCutSize0, nCuts0 );
|
||||
Gia_ManConsiderCuts( pGia, vCutsSel );
|
||||
//Gia_ManConsiderCuts( pGia, vCutsSel );
|
||||
Gia_StoFree( p );
|
||||
return vCutsSel;
|
||||
}
|
||||
void Gia_ManExploreCutsTest( Gia_Man_t * pGia, int nCutSize0, int nCuts0, int fVerbose0 )
|
||||
{
|
||||
Vec_Wec_t * vCutSel = Gia_ManExploreCuts( pGia, nCutSize0, nCuts0, fVerbose0 );
|
||||
Vec_WecPrint( vCutSel, 0 );
|
||||
Vec_WecFree( vCutSel );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Gia_Sto_t * Gia_ManMatchCutsInt( Gia_Man_t * pGia, int nCutSize0, int nCutNum0, int fVerbose0 )
|
||||
{
|
||||
int nCutSize = nCutSize0;
|
||||
int nCutNum = nCutNum0;
|
||||
int fCutMin = 1;
|
||||
int fTruthMin = 1;
|
||||
int fVerbose = fVerbose0;
|
||||
Gia_Sto_t * p = Gia_StoAlloc( pGia, nCutSize, nCutNum, fCutMin, fTruthMin, fVerbose );
|
||||
Gia_Obj_t * pObj; int i, iObj;
|
||||
assert( nCutSize <= GIA_MAX_CUTSIZE );
|
||||
assert( nCutNum < GIA_MAX_CUTNUM );
|
||||
// prepare references
|
||||
Gia_ManForEachObj( p->pGia, pObj, iObj )
|
||||
Gia_StoRefObj( p, iObj );
|
||||
// compute cuts
|
||||
Gia_StoComputeCutsConst0( p, 0 );
|
||||
Gia_ManForEachCiId( p->pGia, iObj, i )
|
||||
Gia_StoComputeCutsCi( p, iObj );
|
||||
Gia_ManForEachAnd( p->pGia, pObj, iObj )
|
||||
Gia_StoComputeCutsNode( p, iObj );
|
||||
if ( p->fVerbose )
|
||||
{
|
||||
printf( "Running cut computation with CutSize = %d CutNum = %d CutMin = %s TruthMin = %s\n",
|
||||
p->nCutSize, p->nCutNum, p->fCutMin ? "yes":"no", p->fTruthMin ? "yes":"no" );
|
||||
printf( "CutPair = %.0f ", p->CutCount[0] );
|
||||
printf( "Merge = %.0f (%.2f %%) ", p->CutCount[1], 100.0*p->CutCount[1]/p->CutCount[0] );
|
||||
printf( "Eval = %.0f (%.2f %%) ", p->CutCount[2], 100.0*p->CutCount[2]/p->CutCount[0] );
|
||||
printf( "Cut = %.0f (%.2f %%) ", p->CutCount[3], 100.0*p->CutCount[3]/p->CutCount[0] );
|
||||
printf( "Cut/Node = %.2f ", p->CutCount[3] / Gia_ManAndNum(p->pGia) );
|
||||
printf( "\n" );
|
||||
printf( "The number of nodes with cut count over the limit (%d cuts) = %d nodes (out of %d). ",
|
||||
p->nCutNum, p->nCutsOver, Gia_ManAndNum(pGia) );
|
||||
Abc_PrintTime( 0, "Time", Abc_Clock() - p->clkStart );
|
||||
}
|
||||
return p;
|
||||
}
|
||||
void Gia_ManMatchCuts( Vec_Mem_t * vTtMem, Gia_Man_t * pGia, int nCutSize, int nCutNum, int fVerbose )
|
||||
{
|
||||
Gia_Sto_t * p = Gia_ManMatchCutsInt( pGia, nCutSize, nCutNum, fVerbose );
|
||||
Vec_Int_t * vLevel; int i, k, * pCut;
|
||||
Vec_Int_t * vNodes = Vec_IntAlloc( 100 );
|
||||
abctime clkStart = Abc_Clock();
|
||||
assert( Abc_Truth6WordNum(nCutSize) == Vec_MemEntrySize(vTtMem) );
|
||||
Vec_WecForEachLevel( p->vCuts, vLevel, i ) if ( Vec_IntSize(vLevel) )
|
||||
{
|
||||
Sdb_ForEachCut( Vec_IntArray(vLevel), pCut, k ) if ( pCut[0] > 1 )
|
||||
{
|
||||
word * pTruth = Vec_MemReadEntry( p->vTtMem, Abc_Lit2Var(pCut[pCut[0]+1]) );
|
||||
int * pSpot = Vec_MemHashLookup( vTtMem, pTruth );
|
||||
if ( *pSpot == -1 )
|
||||
continue;
|
||||
Vec_IntPush( vNodes, i );
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf( "Nodes with matching cuts: " );
|
||||
Vec_IntPrint( vNodes );
|
||||
Vec_IntFree( vNodes );
|
||||
Gia_StoFree( p );
|
||||
if ( fVerbose )
|
||||
Abc_PrintTime( 1, "Cut matching time", Abc_Clock() - clkStart );
|
||||
}
|
||||
Vec_Ptr_t * Gia_ManMatchCutsArray( Vec_Ptr_t * vTtMems, Gia_Man_t * pGia, int nCutSize, int nCutNum, int fVerbose )
|
||||
{
|
||||
Vec_Ptr_t * vRes = Vec_PtrAlloc( Vec_PtrSize(vTtMems) );
|
||||
Gia_Sto_t * p = Gia_ManMatchCutsInt( pGia, nCutSize, nCutNum, fVerbose );
|
||||
Vec_Int_t * vLevel, * vTemp; int i, k, c, * pCut;
|
||||
abctime clkStart = Abc_Clock();
|
||||
for ( i = 0; i < Vec_PtrSize(vTtMems); i++ )
|
||||
Vec_PtrPush( vRes, Vec_WecAlloc(100) );
|
||||
Vec_WecForEachLevel( p->vCuts, vLevel, i ) if ( Vec_IntSize(vLevel) )
|
||||
{
|
||||
Sdb_ForEachCut( Vec_IntArray(vLevel), pCut, k ) if ( pCut[0] > 1 )
|
||||
{
|
||||
Vec_Mem_t * vTtMem; int m;
|
||||
Vec_PtrForEachEntry( Vec_Mem_t *, vTtMems, vTtMem, m )
|
||||
{
|
||||
word * pTruth = Vec_MemReadEntry( p->vTtMem, Abc_Lit2Var(pCut[pCut[0]+1]) );
|
||||
int * pSpot = Vec_MemHashLookup( vTtMem, pTruth );
|
||||
if ( *pSpot == -1 )
|
||||
continue;
|
||||
vTemp = Vec_WecPushLevel( (Vec_Wec_t *)Vec_PtrEntry(vRes, m) );
|
||||
Vec_IntPush( vTemp, i );
|
||||
for ( c = 1; c <= pCut[0]; c++ )
|
||||
Vec_IntPush( vTemp, pCut[c] );
|
||||
}
|
||||
}
|
||||
}
|
||||
Gia_StoFree( p );
|
||||
if ( fVerbose ) {
|
||||
Vec_Wec_t * vCuts;
|
||||
printf( "Detected nodes by type: " );
|
||||
Vec_PtrForEachEntry( Vec_Wec_t *, vRes, vCuts, i )
|
||||
printf( "Type%d = %d ", i, Vec_WecSize(vCuts) );
|
||||
Abc_PrintTime( 1, "Cut matching time", Abc_Clock() - clkStart );
|
||||
}
|
||||
return vRes;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
|
|
|
|||
|
|
@ -5823,6 +5823,349 @@ Gia_Man_t * Gia_ManImplFromBMiter( Gia_Man_t * p, int nPo, int nBInput )
|
|||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Gia_Man_t * Gia_ManDupOdc( Gia_Man_t * p, int iObj, int fVerbose )
|
||||
{
|
||||
Vec_Int_t * vRoots = Vec_IntAlloc( 1 );
|
||||
Vec_Int_t * vNodes = Vec_IntAlloc( 100 );
|
||||
Vec_Int_t * vSupp = Vec_IntAlloc( 100 );
|
||||
Gia_Obj_t * pObj; int i, iRes = 0;
|
||||
Vec_IntPush( vRoots, iObj );
|
||||
Gia_ManStaticFanoutStart( p );
|
||||
Gia_ManCollectTfo( p, vRoots, vNodes );
|
||||
Gia_ManStaticFanoutStop( p );
|
||||
Vec_IntSort(vNodes, 0);
|
||||
Gia_ManForEachObjVecStart( vNodes, p, pObj, i, 1 ) {
|
||||
if ( !Gia_ObjIsTravIdCurrent(p, Gia_ObjFanin0(pObj)) )
|
||||
Vec_IntPushUnique( vSupp, Gia_ObjFaninId0p(p, pObj) );
|
||||
if ( !Gia_ObjIsTravIdCurrent(p, Gia_ObjFanin1(pObj)) )
|
||||
Vec_IntPushUnique( vSupp, Gia_ObjFaninId1p(p, pObj) );
|
||||
}
|
||||
Vec_IntSort(vSupp, 0);
|
||||
if ( fVerbose ) Vec_IntPrint( vSupp );
|
||||
if ( fVerbose ) Vec_IntPrint( vNodes );
|
||||
Gia_Man_t * pTemp, * pNew = Gia_ManStart( 100 );
|
||||
pNew->pName = Abc_UtilStrsav( "care" );
|
||||
Gia_ManFillValue(p);
|
||||
Gia_ManConst0(p)->Value = 0;
|
||||
Gia_ManForEachObjVec( vSupp, p, pObj, i )
|
||||
pObj->Value = Gia_ManAppendCi(pNew);
|
||||
Gia_ManHashStart(pNew);
|
||||
Gia_ManObj(p, iObj)->Value = 0;
|
||||
Gia_ManForEachObjVecStart( vNodes, p, pObj, i, 1 )
|
||||
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
if ( Gia_ObjIsTravIdCurrent(p, pObj) )
|
||||
pObj->Value = Gia_ObjFanin0Copy(pObj);
|
||||
Gia_ManObj(p, iObj)->Value = 1;
|
||||
Gia_ManForEachObjVecStart( vNodes, p, pObj, i, 1 )
|
||||
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
if ( Gia_ObjIsTravIdCurrent(p, pObj) )
|
||||
iRes = Gia_ManHashOr( pNew, iRes, Gia_ManHashXor(pNew, pObj->Value, Gia_ObjFanin0Copy(pObj)) );
|
||||
Gia_ManAppendCo( pNew, Abc_LitNot(iRes) );
|
||||
Vec_IntFree( vRoots );
|
||||
Vec_IntFree( vNodes );
|
||||
Vec_IntFree( vSupp );
|
||||
pNew = Gia_ManCleanup( pTemp = pNew );
|
||||
Gia_ManStop( pTemp );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Mark nodes supported by the cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Gia_ManMarkSupported( Gia_Man_t * p, Vec_Int_t * vObjs )
|
||||
{
|
||||
Gia_Obj_t * pObj; int i;
|
||||
Vec_Int_t * vInner = Vec_IntAlloc( 100 );
|
||||
Gia_ManIncrementTravId(p);
|
||||
Gia_ManForEachObjVec( vObjs, p, pObj, i )
|
||||
Gia_ObjSetTravIdCurrent(p, pObj);
|
||||
Vec_IntAppend( vInner, vObjs );
|
||||
Gia_ManForEachAnd( p, pObj, i ) {
|
||||
if ( Gia_ObjIsTravIdCurrent(p, pObj) )
|
||||
continue;
|
||||
if ( !Gia_ObjIsTravIdCurrent(p, Gia_ObjFanin0(pObj)) || !Gia_ObjIsTravIdCurrent(p, Gia_ObjFanin1(pObj)) )
|
||||
continue;
|
||||
Gia_ObjSetTravIdCurrent(p, pObj);
|
||||
Vec_IntPush( vInner, Gia_ObjId(p, pObj) );
|
||||
}
|
||||
return vInner;
|
||||
}
|
||||
Vec_Int_t * Gia_ManMarkPointed( Gia_Man_t * p, Vec_Int_t * vCut, Vec_Int_t * vInner )
|
||||
{
|
||||
Gia_Obj_t * pObj; int i;
|
||||
Vec_Int_t * vOuts = Vec_IntAlloc( 100 );
|
||||
Gia_ManForEachObjVec( vCut, p, pObj, i )
|
||||
Gia_ObjSetTravIdPrevious(p, pObj);
|
||||
Gia_ManForEachAnd( p, pObj, i ) {
|
||||
if ( Gia_ObjIsTravIdCurrent(p, pObj) )
|
||||
continue;
|
||||
if ( Gia_ObjIsTravIdCurrent(p, Gia_ObjFanin0(pObj)) ) {
|
||||
Gia_ObjSetTravIdPrevious(p, Gia_ObjFanin0(pObj));
|
||||
Vec_IntPush( vOuts, Gia_ObjFaninId0p(p, pObj) );
|
||||
}
|
||||
if ( Gia_ObjIsTravIdCurrent(p, Gia_ObjFanin1(pObj)) ) {
|
||||
Gia_ObjSetTravIdPrevious(p, Gia_ObjFanin1(pObj));
|
||||
Vec_IntPush( vOuts, Gia_ObjFaninId1p(p, pObj) );
|
||||
}
|
||||
}
|
||||
Gia_ManForEachCo( p, pObj, i ) {
|
||||
if ( Gia_ObjIsTravIdCurrent(p, Gia_ObjFanin0(pObj)) ) {
|
||||
Gia_ObjSetTravIdPrevious(p, Gia_ObjFanin0(pObj));
|
||||
Vec_IntPush( vOuts, Gia_ObjFaninId0p(p, pObj) );
|
||||
}
|
||||
}
|
||||
Vec_IntSort( vOuts, 0 );
|
||||
return vOuts;
|
||||
}
|
||||
Gia_Man_t * Gia_ManDupWindow( Gia_Man_t * p, Vec_Int_t * vCut )
|
||||
{
|
||||
Gia_Obj_t * pObj; int i;
|
||||
Vec_Int_t * vInner = Gia_ManMarkSupported( p, vCut );
|
||||
Vec_Int_t * vOuts = Gia_ManMarkPointed( p, vCut, vInner );
|
||||
Gia_Man_t * pNew = Gia_ManStart( 100 );
|
||||
pNew->pName = Abc_UtilStrsav( "win" );
|
||||
Gia_ManConst0(p)->Value = 0;
|
||||
Gia_ManForEachObjVec( vCut, p, pObj, i )
|
||||
pObj->Value = Gia_ManAppendCi( pNew );
|
||||
Gia_ManForEachObjVecStart( vInner, p, pObj, i, Vec_IntSize(vCut) )
|
||||
pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
Gia_ManForEachObjVec( vOuts, p, pObj, i )
|
||||
pObj->Value = Gia_ManAppendCo( pNew, pObj->Value );
|
||||
printf( "Derived window with %d inputs, %d internal nodes, and %d outputs.\n", Vec_IntSize(vCut), Vec_IntSize(vInner), Vec_IntSize(vOuts) );
|
||||
printf( "Outputs: " );
|
||||
Vec_IntPrint( vOuts );
|
||||
Vec_IntFree( vInner );
|
||||
Vec_IntFree( vOuts );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Wec_t * Gia_ManCollectIntTfos( Gia_Man_t * p, Vec_Int_t * vVarNums )
|
||||
{
|
||||
Vec_Wec_t * vTfos = Vec_WecStart( Vec_IntSize(vVarNums) );
|
||||
Vec_Int_t * vNodes = Vec_IntAlloc( 100 );
|
||||
Gia_Obj_t * pObj; int i, k, Input, iNode;
|
||||
Gia_ManIncrementTravId( p );
|
||||
Vec_IntForEachEntry( vVarNums, Input, i )
|
||||
Gia_ObjSetTravIdCurrentId( p, Gia_ManCiIdToId(p, Input) );
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
if ( Gia_ObjIsTravIdCurrentId(p, Gia_ObjFaninId0(pObj, i)) || Gia_ObjIsTravIdCurrentId(p, Gia_ObjFaninId1(pObj, i)) )
|
||||
Gia_ObjSetTravIdCurrentId( p, i ), Vec_IntPush( vNodes, i );
|
||||
Vec_IntForEachEntry( vVarNums, Input, i )
|
||||
{
|
||||
Gia_ManIncrementTravId( p );
|
||||
Gia_ObjSetTravIdCurrentId( p, Gia_ManCiIdToId(p, Input) );
|
||||
Vec_IntForEachEntry( vNodes, iNode, k )
|
||||
if ( Gia_ObjIsTravIdCurrentId(p, Gia_ObjFaninId0(Gia_ManObj(p, iNode), iNode)) || Gia_ObjIsTravIdCurrentId(p, Gia_ObjFaninId1(Gia_ManObj(p, iNode), iNode)) )
|
||||
Gia_ObjSetTravIdCurrentId( p, iNode ), Vec_WecPush( vTfos, i, iNode );
|
||||
}
|
||||
Vec_IntFree( vNodes );
|
||||
return vTfos;
|
||||
}
|
||||
Gia_Man_t * Gia_ManDupCofs( Gia_Man_t * p, Vec_Int_t * vVarNums )
|
||||
{
|
||||
Vec_Int_t * vOutLits = Vec_IntStartFull( 1 << Vec_IntSize(vVarNums) );
|
||||
Vec_Wec_t * vTfos = Gia_ManCollectIntTfos( p, vVarNums );
|
||||
Gia_Man_t * pNew, * pTemp;
|
||||
Gia_Obj_t * pObj, * pRoot = Gia_ManCo(p, 0); int i, iLit;
|
||||
assert( Gia_ManPoNum(p) == 1 && Gia_ManRegNum(p) == 0 );
|
||||
pNew = Gia_ManStart( Gia_ManObjNum(p) );
|
||||
pNew->pName = Abc_UtilStrsav( p->pName );
|
||||
Gia_ManFillValue( p );
|
||||
Gia_ManConst0(p)->Value = 0;
|
||||
Gia_ManForEachCi( p, pObj, i )
|
||||
pObj->Value = Gia_ManAppendCi(pNew);
|
||||
Gia_ManForEachCiVec( vVarNums, p, pObj, i )
|
||||
pObj->Value = 0;
|
||||
Gia_ManHashAlloc( pNew );
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
Vec_IntWriteEntry( vOutLits, 0, Gia_ObjFanin0Copy(pRoot) );
|
||||
int m, g, x, b = 0;
|
||||
for ( m = 1; m < Vec_IntSize(vOutLits); m++ )
|
||||
{
|
||||
g = m ^ (m >> 1); x = (b ^ g) == 1 ? 0 : Abc_Base2Log(b ^ g); b = g;
|
||||
Vec_Int_t * vNode = Vec_WecEntry( vTfos, x );
|
||||
Gia_ManPi(p, Vec_IntEntry(vVarNums, x))->Value ^= 1;
|
||||
Gia_ManForEachObjVec( vNode, p, pObj, i )
|
||||
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
Vec_IntWriteEntry( vOutLits, g, Gia_ObjFanin0Copy(pRoot) );
|
||||
}
|
||||
assert( Vec_IntFindMin(vOutLits) >= 0 );
|
||||
Vec_IntForEachEntry( vOutLits, iLit, i )
|
||||
Gia_ManAppendCo( pNew, iLit );
|
||||
Vec_IntFree( vOutLits );
|
||||
Vec_WecFree( vTfos );
|
||||
pNew = Gia_ManCleanup( pTemp = pNew );
|
||||
Gia_ManStop( pTemp );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Gia_ManCofPattern( Gia_Man_t * p )
|
||||
{
|
||||
Vec_Int_t * vRes = Vec_IntAlloc( Gia_ManCoNum(p) );
|
||||
Vec_Int_t * vMap = Vec_IntStartFull( 2*Gia_ManObjNum(p) );
|
||||
Gia_Obj_t * pObj; int i, iLit, iClass = 0;
|
||||
assert( Gia_ManCoNum(p) == 1 << Abc_Base2Log(Gia_ManCoNum(p)) );
|
||||
Gia_ManForEachPo( p, pObj, i )
|
||||
{
|
||||
iLit = Gia_ObjFaninLit0p(p, pObj);
|
||||
if ( Vec_IntEntry(vMap, iLit) == -1 )
|
||||
Vec_IntWriteEntry( vMap, iLit, iClass++ );
|
||||
Vec_IntPush( vRes, Vec_IntEntry(vMap, iLit) );
|
||||
}
|
||||
Vec_IntFree( vMap );
|
||||
return vRes;
|
||||
}
|
||||
Vec_Int_t * Gia_ManCofClassPattern( Gia_Man_t * p, Vec_Int_t * vVarNums, int fVerbose )
|
||||
{
|
||||
extern Gia_Man_t * Cec4_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose );
|
||||
Gia_Man_t * pCofs = Gia_ManDupCofs( p, vVarNums );
|
||||
Gia_Man_t * pSweep = Cec4_ManSimulateTest3( pCofs, 0, 0 );
|
||||
Vec_Int_t * vRes = Gia_ManCofPattern( pSweep );
|
||||
assert( Vec_IntSize(vRes) == 1 << Vec_IntSize(vVarNums) );
|
||||
Gia_ManStop( pSweep );
|
||||
Gia_ManStop( pCofs );
|
||||
if ( fVerbose )
|
||||
{
|
||||
int i, Class, nClasses = Vec_IntFindMax(vRes)+1;
|
||||
printf( "%d -> %d: ", Vec_IntSize(vVarNums), nClasses );
|
||||
if ( nClasses <= 36 )
|
||||
Vec_IntForEachEntry( vRes, Class, i )
|
||||
printf( "%c", (Class < 10 ? (int)'0' : (int)'A'-10) + Class );
|
||||
printf( "\n" );
|
||||
}
|
||||
return vRes;
|
||||
}
|
||||
Gia_Man_t * Gia_ManDupEncode( Gia_Man_t * p, Vec_Int_t * vVarNums, int fVerbose )
|
||||
{
|
||||
extern Vec_Int_t * Gia_GenDecoder( Gia_Man_t * p, int * pLits, int nLits );
|
||||
Gia_Man_t * pNew, * pTemp;
|
||||
Vec_Int_t * vCols = Gia_ManCofClassPattern( p, vVarNums, fVerbose );
|
||||
Vec_Int_t * vVars = Vec_IntAlloc( 100 ), * vDec;
|
||||
int i, k, Limit = Vec_IntSize(vCols), Entry;
|
||||
int nClasses = Vec_IntFindMax(vCols)+1;
|
||||
int nExtras = Abc_Base2Log(nClasses);
|
||||
pNew = Gia_ManStart( 1000 );
|
||||
pNew->pName = Abc_UtilStrsav( p->pName );
|
||||
for ( i = 0; i < Vec_IntSize(vVarNums) + nExtras; i++ )
|
||||
Vec_IntPush( vVars, Gia_ManAppendCi(pNew) );
|
||||
Gia_ManHashAlloc( pNew );
|
||||
vDec = Gia_GenDecoder( pNew, Vec_IntEntryP(vVars, Vec_IntSize(vVarNums)), nExtras );
|
||||
Vec_IntForEachEntry( vCols, Entry, i )
|
||||
Vec_IntWriteEntry( vCols, i, Vec_IntEntry(vDec, Entry) );
|
||||
Vec_IntFree( vDec );
|
||||
for ( i = Vec_IntSize(vVarNums) - 1; i >= 0; i--, Limit /= 2 )
|
||||
for ( k = 0; k < Limit; k += 2 )
|
||||
Vec_IntWriteEntry( vCols, k/2, Gia_ManHashMux(pNew, Vec_IntEntry(vVars, i), Vec_IntEntry(vCols, k+1), Vec_IntEntry(vCols, k)) );
|
||||
Gia_ManAppendCo( pNew, Vec_IntEntry(vCols, 0) );
|
||||
Vec_IntFree( vCols );
|
||||
Vec_IntFree( vVars );
|
||||
pNew = Gia_ManCleanup( pTemp = pNew );
|
||||
Gia_ManStop( pTemp );
|
||||
if ( fVerbose )
|
||||
printf( "Generated AIG with %d inputs and %d nodes representing %d PIs with %d columns.\n",
|
||||
Gia_ManPiNum(pNew), Gia_ManAndNum(pNew), Vec_IntSize(vVarNums), nClasses );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManCofClassRand( Gia_Man_t * p, int nVars, int nRands )
|
||||
{
|
||||
for ( int n = 0; n < nRands; n++ )
|
||||
{
|
||||
Abc_Random(1);
|
||||
for ( int i = 0; i < n; i++ )
|
||||
Abc_Random(0);
|
||||
Vec_Int_t * vIns = Vec_IntStartNatural( Gia_ManPiNum(p) );
|
||||
Vec_IntRandomizeOrder( vIns );
|
||||
Vec_IntShrink( vIns, nVars );
|
||||
int k, Entry;
|
||||
printf( "Vars: " );
|
||||
Vec_IntForEachEntry( vIns, Entry, k )
|
||||
printf( "%d ", Entry );
|
||||
printf( " " );
|
||||
Vec_Int_t * vTemp = Gia_ManCofClassPattern( p, vIns, 1 );
|
||||
Vec_IntFree( vTemp );
|
||||
Vec_IntFree( vIns );
|
||||
}
|
||||
}
|
||||
void Gia_ManCofClassEnum( Gia_Man_t * p, int nVars )
|
||||
{
|
||||
Vec_Int_t * vIns = Vec_IntAlloc( nVars );
|
||||
int m, k, Entry, Count, nMints = 1 << Gia_ManPiNum(p);
|
||||
for ( m = 0; m < nMints; m++ ) {
|
||||
for ( Count = k = 0; k < Gia_ManPiNum(p); k++ )
|
||||
Count += (m >> k) & 1;
|
||||
if ( Count != nVars )
|
||||
continue;
|
||||
Vec_IntClear( vIns );
|
||||
for ( k = 0; k < Gia_ManPiNum(p); k++ )
|
||||
if ( (m >> k) & 1 )
|
||||
Vec_IntPush( vIns, k );
|
||||
assert( Vec_IntSize(vIns) == Count );
|
||||
printf( "Vars: " );
|
||||
Vec_IntForEachEntry( vIns, Entry, k )
|
||||
printf( "%d ", Entry );
|
||||
printf( " " );
|
||||
Vec_Int_t * vTemp = Gia_ManCofClassPattern( p, vIns, 1 );
|
||||
Vec_IntFree( vTemp );
|
||||
}
|
||||
Vec_IntFree( vIns );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -1308,12 +1308,25 @@ int Gia_ManFromIfLogicNode( void * pIfMan, Gia_Man_t * pNew, int iObj, Vec_Int_t
|
|||
{
|
||||
if ( Length == 2 )
|
||||
{
|
||||
if ( !If_CluCheckExt( NULL, pRes, nLeaves, nLutLeaf, nLutRoot, pLut0, pLut1, &Func0, &Func1 ) )
|
||||
if ( ((If_Man_t *)pIfMan)->pPars->fEnableStructN )
|
||||
{
|
||||
Extra_PrintHex( stdout, (unsigned *)pRes, nLeaves ); printf( " " );
|
||||
Kit_DsdPrintFromTruth( (unsigned*)pRes, nLeaves ); printf( "\n" );
|
||||
printf( "Node %d is not decomposable. Deriving LUT structures has failed.\n", iObj );
|
||||
return -1;
|
||||
if ( !If_CluCheckXXExt( NULL, pRes, nLeaves, nLutLeaf, nLutRoot, pLut0, pLut1, &Func0, &Func1 ) )
|
||||
{
|
||||
Extra_PrintHex( stdout, (unsigned *)pRes, nLeaves ); printf( " " );
|
||||
Kit_DsdPrintFromTruth( (unsigned*)pRes, nLeaves ); printf( "\n" );
|
||||
printf( "Node %d is not decomposable. Deriving LUT structures has failed.\n", iObj );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !If_CluCheckExt( NULL, pRes, nLeaves, nLutLeaf, nLutRoot, pLut0, pLut1, &Func0, &Func1 ) )
|
||||
{
|
||||
Extra_PrintHex( stdout, (unsigned *)pRes, nLeaves ); printf( " " );
|
||||
Kit_DsdPrintFromTruth( (unsigned*)pRes, nLeaves ); printf( "\n" );
|
||||
printf( "Node %d is not decomposable. Deriving LUT structures has failed.\n", iObj );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -1411,6 +1424,90 @@ int Gia_ManFromIfLogicNode( void * pIfMan, Gia_Man_t * pNew, int iObj, Vec_Int_t
|
|||
return iObjLit3;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Implements delay-driven decomposition of the cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_ManFromIfLogicHop( Gia_Man_t * pNew, If_Man_t * pIfMan, If_Cut_t * pCutBest, Vec_Int_t * vLeaves, Vec_Int_t * vLeavesTemp, Vec_Int_t * vCover, Vec_Int_t * vMapping, Vec_Int_t * vMapping2 )
|
||||
{
|
||||
word * pTruth = If_CutTruthW(pIfMan, pCutBest);
|
||||
unsigned char decompArray[92];
|
||||
int val;
|
||||
|
||||
assert( pCutBest->nLeaves > pIfMan->pPars->nLutDecSize );
|
||||
|
||||
unsigned delayProfile = pCutBest->decDelay;
|
||||
val = acd_decompose( pTruth, pCutBest->nLeaves, pIfMan->pPars->nLutDecSize, &(delayProfile), decompArray );
|
||||
assert( val == 0 );
|
||||
|
||||
// convert the LUT-structure into a set of logic nodes in Gia_Man_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 iObjLits[5];
|
||||
int fanin;
|
||||
word *tt;
|
||||
|
||||
for ( i = 0; i < decompArray[1]; ++i )
|
||||
{
|
||||
num_fanins = decompArray[byte_p++];
|
||||
Vec_IntClear( vLeavesTemp );
|
||||
for ( j = 0; j < num_fanins; ++j )
|
||||
{
|
||||
fanin = (int)decompArray[byte_p++];
|
||||
if ( fanin < If_CutLeaveNum(pCutBest) )
|
||||
{
|
||||
Vec_IntPush( vLeavesTemp, Vec_IntEntry(vLeaves, fanin) );
|
||||
}
|
||||
else
|
||||
{
|
||||
Vec_IntPush( vLeavesTemp, iObjLits[fanin - If_CutLeaveNum(pCutBest)] );
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
iObjLits[i] = Gia_ManFromIfLogicCreateLut( pNew, tt, vLeavesTemp, vCover, vMapping, vMapping2 );
|
||||
}
|
||||
|
||||
/* check correct read */
|
||||
assert( byte_p == decompArray[0] );
|
||||
|
||||
return iObjLits[i-1];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recursively derives the local AIG for the cut.]
|
||||
|
|
@ -1894,7 +1991,7 @@ Gia_Man_t * Gia_ManFromIfLogic( If_Man_t * pIfMan )
|
|||
if ( !pIfMan->pPars->fUseTtPerm && !pIfMan->pPars->fDelayOpt && !pIfMan->pPars->fDelayOptLut && !pIfMan->pPars->fDsdBalance &&
|
||||
!pIfMan->pPars->pLutStruct && !pIfMan->pPars->fUserRecLib && !pIfMan->pPars->fUserSesLib && !pIfMan->pPars->nGateSize &&
|
||||
!pIfMan->pPars->fEnableCheck75 && !pIfMan->pPars->fEnableCheck75u && !pIfMan->pPars->fEnableCheck07 && !pIfMan->pPars->fUseDsdTune &&
|
||||
!pIfMan->pPars->fUseCofVars && !pIfMan->pPars->fUseAndVars && !pIfMan->pPars->fUseCheck1 && !pIfMan->pPars->fUseCheck2 )
|
||||
!pIfMan->pPars->fUseCofVars && !pIfMan->pPars->fUseAndVars && !pIfMan->pPars->fUseCheck1 && !pIfMan->pPars->fUseCheck2 && !pIfMan->pPars->fUserLutDec )
|
||||
If_CutRotatePins( pIfMan, pCutBest );
|
||||
// collect leaves of the best cut
|
||||
Vec_IntClear( vLeaves );
|
||||
|
|
@ -1946,6 +2043,10 @@ Gia_Man_t * Gia_ManFromIfLogic( If_Man_t * pIfMan )
|
|||
{
|
||||
pIfObj->iCopy = Gia_ManFromIfLogicCofVars( pNew, pIfMan, pCutBest, vLeaves, vLeaves2, vCover, vMapping, vMapping2 );
|
||||
}
|
||||
else if ( pIfMan->pPars->fUserLutDec && (int)pCutBest->nLeaves > pIfMan->pPars->nLutDecSize )
|
||||
{
|
||||
pIfObj->iCopy = Gia_ManFromIfLogicHop( pNew, pIfMan, pCutBest, vLeaves, vLeaves2, vCover, vMapping, vMapping2 );
|
||||
}
|
||||
else if ( (pIfMan->pPars->fDeriveLuts && pIfMan->pPars->fTruth) || pIfMan->pPars->fUseDsd || pIfMan->pPars->fUseTtPerm || pIfMan->pPars->pFuncCell2 )
|
||||
{
|
||||
word * pTruth = If_CutTruthW(pIfMan, pCutBest);
|
||||
|
|
|
|||
|
|
@ -2291,6 +2291,85 @@ void Gia_GenSandwich( char ** pFNames, int nFNames, char * pFileName )
|
|||
printf( "Dumped hierarchical design into file \"%s\"\n", pFileName );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Generate hierarchical design.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_GenPutOnTopOne( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Int_t * vLits )
|
||||
{
|
||||
Gia_Obj_t * pObj; int i;
|
||||
Gia_ManConst0(p)->Value = 0;
|
||||
assert( Vec_IntSize(vLits) == Gia_ManCiNum(p) );
|
||||
Gia_ManForEachCi( p, pObj, i )
|
||||
pObj->Value = Vec_IntEntry(vLits, i);
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
Vec_IntClear( vLits );
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
Vec_IntPush( vLits, Gia_ObjFanin0Copy(pObj) );
|
||||
assert( Vec_IntSize(vLits) == Gia_ManCoNum(p) );
|
||||
}
|
||||
Gia_Man_t * Gia_GenPutOnTop( char ** pFNames, int nFNames )
|
||||
{
|
||||
Gia_Man_t * pNew, * pTemp;
|
||||
Gia_Man_t * pGias[16] = {0};
|
||||
Vec_Int_t * vLits;
|
||||
int i, iLit, nObjs = 0;
|
||||
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 NULL;
|
||||
}
|
||||
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 NULL;
|
||||
}
|
||||
nObjs += Gia_ManObjNum(pGias[i]);
|
||||
}
|
||||
// start new AIG
|
||||
pNew = Gia_ManStart( nObjs );
|
||||
pNew->pName = Abc_UtilStrsav( "putontop" );
|
||||
Gia_ManHashAlloc( pNew );
|
||||
// collect inputs
|
||||
vLits = Vec_IntAlloc( Gia_ManCiNum(pGias[0]) );
|
||||
for ( i = 0; i < Gia_ManCiNum(pGias[0]); i++ )
|
||||
Vec_IntPush( vLits, Gia_ManAppendCi(pNew) );
|
||||
// add parts
|
||||
for ( i = 0; i < nFNames; i++ )
|
||||
{
|
||||
Gia_Man_t * p = pGias[i];
|
||||
while ( Vec_IntSize(vLits) < Gia_ManCiNum(p) )
|
||||
Vec_IntPush( vLits, Gia_ManAppendCi(pNew) );
|
||||
while ( Vec_IntSize(vLits) > Gia_ManCiNum(p) )
|
||||
Gia_ManAppendCo( pNew, Vec_IntPop(vLits) );
|
||||
Gia_GenPutOnTopOne( pNew, p, vLits );
|
||||
}
|
||||
// create outputs
|
||||
Vec_IntForEachEntry( vLits, iLit, i )
|
||||
Gia_ManAppendCo( pNew, iLit );
|
||||
Vec_IntFree( vLits );
|
||||
// cleanup
|
||||
pNew = Gia_ManDupNormalize( pTemp = pNew, 0 );
|
||||
Gia_ManStop( pTemp );
|
||||
pNew = Gia_ManCleanup( pTemp = pNew );
|
||||
Gia_ManStop( pTemp );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -724,6 +724,23 @@ int * Abc_FrameReadMiniLutSwitching( Abc_Frame_t * pAbc )
|
|||
Vec_IntFree( vSwitching );
|
||||
return pRes;
|
||||
}
|
||||
int * Abc_FrameReadMiniLutSwitching2( Abc_Frame_t * pAbc, int fRandPiFactor )
|
||||
{
|
||||
Vec_Int_t * vSwitching;
|
||||
int i, iObj, * pRes = NULL;
|
||||
if ( pAbc->pGiaMiniLut == NULL )
|
||||
{
|
||||
printf( "GIA derived from MiniLut is not available.\n" );
|
||||
return NULL;
|
||||
}
|
||||
vSwitching = Gia_ManComputeSwitchProbs2( pAbc->pGiaMiniLut, 48, 16, 0, fRandPiFactor );
|
||||
pRes = ABC_CALLOC( int, Vec_IntSize(pAbc->vCopyMiniLut) );
|
||||
Vec_IntForEachEntry( pAbc->vCopyMiniLut, iObj, i )
|
||||
if ( iObj >= 0 )
|
||||
pRes[i] = (int)(10000*Vec_FltEntry( (Vec_Flt_t *)vSwitching, Abc_Lit2Var(iObj) ));
|
||||
Vec_IntFree( vSwitching );
|
||||
return pRes;
|
||||
}
|
||||
int * Abc_FrameReadMiniLutSwitchingPo( Abc_Frame_t * pAbc )
|
||||
{
|
||||
Vec_Int_t * vSwitching;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,478 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [giaMulFind.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Scalable AIG package.]
|
||||
|
||||
Synopsis [Multiplier detection.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: giaMulFind.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "gia.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_ManMulFindOverlap( Vec_Int_t * p1, Vec_Int_t * p2 )
|
||||
{
|
||||
int i, k, ObjI, ObjK, Counter = 0;
|
||||
Vec_IntForEachEntry( p1, ObjI, i )
|
||||
Vec_IntForEachEntry( p2, ObjK, k )
|
||||
if ( ObjI == ObjK )
|
||||
Counter++;
|
||||
return Counter;
|
||||
}
|
||||
void Gia_ManMulFindAssignGroup( Vec_Int_t * vTemp, int iGroup, Vec_Int_t * vMap )
|
||||
{
|
||||
int k, Obj;
|
||||
Vec_IntForEachEntry( vTemp, Obj, k ) {
|
||||
//assert( Vec_IntEntry(vMap, Obj) == -1 || Vec_IntEntry(vMap, Obj) == iGroup );
|
||||
Vec_IntWriteEntry(vMap, Obj, iGroup);
|
||||
}
|
||||
Vec_IntPush( vTemp, iGroup );
|
||||
}
|
||||
Vec_Int_t * Gia_ManMulFindGroups( Vec_Wec_t * p, int nObjs, int fUseMap )
|
||||
{
|
||||
Vec_Int_t * vIndex = Vec_IntAlloc( 100 ), * vTemp;
|
||||
Vec_Int_t * vMap = Vec_IntStartFull( nObjs ); int i, Counter, nGroups = 0;
|
||||
Vec_Int_t * vUngrouped = Vec_IntStartNatural( Vec_WecSize(p) );
|
||||
while ( Vec_IntSize(vUngrouped) ) {
|
||||
int k, Obj, Item = Vec_IntPop(vUngrouped);
|
||||
vTemp = Vec_WecEntry(p, Item);
|
||||
Gia_ManMulFindAssignGroup( vTemp, nGroups, vMap );
|
||||
int fChanges = 1;
|
||||
while ( fChanges ) {
|
||||
fChanges = 0;
|
||||
Vec_IntForEachEntry( vUngrouped, Item, i ) {
|
||||
vTemp = Vec_WecEntry(p, Item);
|
||||
Counter = 0;
|
||||
Vec_IntForEachEntry( vTemp, Obj, k )
|
||||
if ( Vec_IntEntry(vMap, Obj) >= 0 )
|
||||
Counter++;
|
||||
if ( Counter < 1 )
|
||||
continue;
|
||||
Gia_ManMulFindAssignGroup( vTemp, nGroups, vMap );
|
||||
Vec_IntDrop( vUngrouped, i-- );
|
||||
fChanges = 1;
|
||||
}
|
||||
}
|
||||
nGroups++;
|
||||
}
|
||||
Vec_IntFree( vUngrouped );
|
||||
Vec_IntFree( vMap );
|
||||
if ( fUseMap )
|
||||
Vec_WecForEachLevel( p, vTemp, i )
|
||||
Vec_IntPushTwo( vTemp, i, Vec_IntPop(vTemp) );
|
||||
Vec_WecSortByLastInt( p, 0 );
|
||||
Counter = 0;
|
||||
Vec_IntPush( vIndex, 0 );
|
||||
Vec_WecForEachLevel( p, vTemp, i )
|
||||
if ( Vec_IntPop(vTemp) != Counter )
|
||||
Vec_IntPush( vIndex, i ), Counter++;
|
||||
Vec_IntPush( vIndex, Vec_WecSize(p) );
|
||||
assert( Vec_WecSize(p) == 0 || Vec_IntSize(vIndex) == nGroups + 1 );
|
||||
return vIndex;
|
||||
}
|
||||
Vec_Wec_t * Gia_ManMulFindXors( Gia_Man_t * p, Vec_Wec_t * vCuts3, int fVerbose )
|
||||
{
|
||||
Vec_Wec_t * vXors = Vec_WecAlloc( 10 );
|
||||
Vec_Int_t * vIndex = Gia_ManMulFindGroups( vCuts3, Gia_ManObjNum(p), 0 );
|
||||
Vec_Int_t * vAll = Vec_IntAlloc( 100 );
|
||||
Vec_Bit_t * vSigs[2] = { Vec_BitStart(Gia_ManObjNum(p)), Vec_BitStart(Gia_ManObjNum(p)) };
|
||||
Vec_Int_t * vTemp; int g, c, k, Obj, Start;
|
||||
Vec_IntForEachEntryStop( vIndex, Start, g, Vec_IntSize(vIndex)-1 ) {
|
||||
Vec_WecForEachLevelStartStop( vCuts3, vTemp, c, Start, Vec_IntEntry(vIndex, g+1) )
|
||||
Vec_IntForEachEntry( vTemp, Obj, k )
|
||||
if ( !Vec_BitEntry(vSigs[k==0], Obj) ) {
|
||||
Vec_BitWriteEntry( vSigs[k==0], Obj, 1 );
|
||||
Vec_IntPush( vAll, Obj );
|
||||
}
|
||||
Vec_Int_t * vIns = Vec_WecPushLevel( vXors );
|
||||
Vec_Int_t * vOuts = Vec_WecPushLevel( vXors );
|
||||
Vec_IntForEachEntry( vAll, Obj, k ) {
|
||||
if ( Vec_BitEntry(vSigs[0], Obj) && !Vec_BitEntry(vSigs[1], Obj) )
|
||||
Vec_IntPush( vIns, Obj );
|
||||
if ( !Vec_BitEntry(vSigs[0], Obj) && Vec_BitEntry(vSigs[1], Obj) )
|
||||
Vec_IntPush( vOuts, Obj );
|
||||
Vec_BitWriteEntry( vSigs[0], Obj, 0 );
|
||||
Vec_BitWriteEntry( vSigs[1], Obj, 0 );
|
||||
}
|
||||
Vec_IntClear( vAll );
|
||||
}
|
||||
return vXors;
|
||||
}
|
||||
Vec_Int_t * Gia_ManFindMulDetectOrder( Vec_Wec_t * vAll, int iStart, int iStop )
|
||||
{
|
||||
Vec_Int_t * vOrder = Vec_IntAlloc( iStop - iStart );
|
||||
Vec_Int_t * vUsed = Vec_IntStart( iStop ), * vTemp;
|
||||
int i, nMatches = 0, iNext = -1;
|
||||
Vec_WecForEachLevelStartStop( vAll, vTemp, i, iStart, iStop )
|
||||
if ( Vec_IntSize(vTemp) == 2 )
|
||||
nMatches++, iNext = i;
|
||||
if ( nMatches == 1 ) {
|
||||
while ( Vec_IntSize(vOrder) < iStop - iStart ) {
|
||||
Vec_IntPush( vOrder, iNext );
|
||||
Vec_IntWriteEntry( vUsed, iNext, 1 );
|
||||
nMatches = 0;
|
||||
Vec_WecForEachLevelStartStop( vAll, vTemp, i, iStart, iStop ) {
|
||||
if ( Vec_IntEntry(vUsed, i) )
|
||||
continue;
|
||||
Vec_Int_t * vLast = Vec_WecEntry(vAll, Vec_IntEntryLast(vOrder));
|
||||
if ( Gia_ManMulFindOverlap(vTemp, vLast) == Vec_IntSize(vLast) && Vec_IntSize(vTemp) == Vec_IntSize(vLast) + 2 )
|
||||
nMatches++, iNext = i;
|
||||
}
|
||||
if ( nMatches != 1 )
|
||||
break;
|
||||
}
|
||||
}
|
||||
Vec_IntFree( vUsed );
|
||||
if ( Vec_IntSize(vOrder) == 0 )
|
||||
Vec_IntFreeP( &vOrder );
|
||||
return vOrder;
|
||||
}
|
||||
Vec_Wec_t * Gia_ManMulFindAInputs( Gia_Man_t * p, Vec_Wec_t * vXors, int fVerbose )
|
||||
{
|
||||
Vec_Wec_t * vRes = Vec_WecAlloc( 10 );
|
||||
Vec_Wec_t * vAll = Vec_WecAlloc( Vec_WecSize(vXors)/2 );
|
||||
Gia_Obj_t * pObj; Vec_Int_t * vIns, * vOuts, * vTemp, * vIndex, * vOrder; int i, k, g, Start, Entry, Entry0, Entry1;
|
||||
Gia_ManCreateRefs( p );
|
||||
Vec_WecForEachLevelDouble( vXors, vIns, vOuts, i ) {
|
||||
vTemp = Vec_WecPushLevel( vAll );
|
||||
Gia_ManForEachObjVec( vIns, p, pObj, k )
|
||||
if ( Gia_ObjIsAnd(pObj)
|
||||
&& !Gia_ObjFaninC0(pObj) && Gia_ObjRefNum(p, Gia_ObjFanin0(pObj)) >= 4
|
||||
&& !Gia_ObjFaninC1(pObj) && Gia_ObjRefNum(p, Gia_ObjFanin1(pObj)) >= 4 )
|
||||
Vec_IntPushTwo( vTemp, Gia_ObjFaninId0p(p, pObj), Gia_ObjFaninId1p(p, pObj) );
|
||||
if ( Vec_IntSize(vTemp) == 0 )
|
||||
Vec_WecShrink(vAll, Vec_WecSize(vAll)-1);
|
||||
}
|
||||
vIndex = Gia_ManMulFindGroups( vAll, Gia_ManObjNum(p), 0 );
|
||||
Vec_IntForEachEntryStop( vIndex, Start, g, Vec_IntSize(vIndex)-1 ) {
|
||||
vOrder = Gia_ManFindMulDetectOrder( vAll, Start, Vec_IntEntry(vIndex, g+1) );
|
||||
if ( vOrder == NULL )
|
||||
continue;
|
||||
Vec_Int_t * vIn0 = Vec_WecPushLevel( vRes );
|
||||
Vec_Int_t * vIn1 = Vec_WecPushLevel( vRes );
|
||||
Vec_Int_t * vOut = Vec_WecPushLevel( vRes );
|
||||
vTemp = Vec_WecEntry( vAll, Vec_IntEntry(vOrder, 0) );
|
||||
assert( Vec_IntSize(vTemp) == 2 );
|
||||
Vec_IntPush( vIn0, Vec_IntEntry(vTemp, 0) );
|
||||
Vec_IntPush( vIn1, Vec_IntEntry(vTemp, 1) );
|
||||
Vec_IntForEachEntryStart( vOrder, Entry, i, 1 ) {
|
||||
vTemp = Vec_WecEntry( vAll, Entry );
|
||||
Vec_IntForEachEntryDouble( vTemp, Entry0, Entry1, k ) {
|
||||
if ( Vec_IntFind(vIn0, Entry0) >= 0 && Vec_IntFind(vIn1, Entry1) == -1 )
|
||||
Vec_IntPush( vIn1, Entry1 );
|
||||
else if ( Vec_IntFind(vIn0, Entry0) == -1 && Vec_IntFind(vIn1, Entry1) >= 0 )
|
||||
Vec_IntPush( vIn0, Entry0 );
|
||||
else
|
||||
assert( (Vec_IntFind(vIn0, Entry0) >= 0 && Vec_IntFind(vIn1, Entry1) >= 0) ||
|
||||
(Vec_IntFind(vIn0, Entry1) >= 0 && Vec_IntFind(vIn1, Entry0) >= 0) );
|
||||
}
|
||||
}
|
||||
Vec_IntReverseOrder( vIn0 );
|
||||
Vec_IntReverseOrder( vIn1 );
|
||||
vOut = NULL;
|
||||
}
|
||||
Vec_IntFree( vIndex );
|
||||
Vec_WecFree( vAll );
|
||||
return vRes;
|
||||
}
|
||||
Vec_Wec_t * Gia_ManMulFindBInputs( Gia_Man_t * p, Vec_Wec_t * vCuts4, Vec_Wec_t * vCuts5, int fVerbose )
|
||||
{
|
||||
Vec_Wec_t * vRes = Vec_WecAlloc( 10 ); Vec_Int_t * vTemp; int g, c, k, Obj, Start;
|
||||
Vec_Int_t * vIndex = Gia_ManMulFindGroups( vCuts4, Gia_ManObjNum(p), 0 );
|
||||
Vec_IntForEachEntryStop( vIndex, Start, g, Vec_IntSize(vIndex)-1 ) {
|
||||
Vec_Int_t * vAll = Vec_IntAlloc ( 100 );
|
||||
Vec_WecForEachLevelStartStop( vCuts4, vTemp, c, Start, Vec_IntEntry(vIndex, g+1) )
|
||||
Vec_IntForEachEntryStart( vTemp, Obj, k, 1 )
|
||||
Vec_IntPush( vAll, Obj );
|
||||
Vec_IntUniqify( vAll );
|
||||
int GroupSize = Vec_IntEntry(vIndex, g+1) - Start;
|
||||
Vec_Int_t * vCnt = Vec_IntStart( Vec_IntSize(vAll) );
|
||||
Vec_WecForEachLevelStartStop( vCuts4, vTemp, c, Start, Vec_IntEntry(vIndex, g+1) )
|
||||
Vec_IntForEachEntryStart( vTemp, Obj, k, 1 )
|
||||
Vec_IntAddToEntry( vCnt, Vec_IntFind(vAll, Obj), 1 );
|
||||
if ( Vec_IntCountEntry(vCnt, 1) != 2 || Vec_IntCountEntry(vCnt, 2) != GroupSize-1 || Vec_IntCountEntry(vCnt, GroupSize) != 2 ) {
|
||||
printf( "Detection of group %d failed.\n", g );
|
||||
continue;
|
||||
}
|
||||
Vec_Int_t * vIn1 = Vec_WecPushLevel( vRes );
|
||||
Vec_Int_t * vIn2 = Vec_WecPushLevel( vRes );
|
||||
Vec_Int_t * vOut = Vec_WecPushLevel( vRes );
|
||||
Vec_IntForEachEntry( vAll, Obj, k )
|
||||
if ( Vec_IntEntry(vCnt, k) <= 2 )
|
||||
Vec_IntPush( vIn1, Obj );
|
||||
else
|
||||
Vec_IntPush( vIn2, Obj );
|
||||
Vec_IntSort( vIn1, 0 );
|
||||
Vec_IntSort( vIn2, 0 );
|
||||
// TODO: check chain in[i] -> in[i+1]
|
||||
Vec_WecForEachLevel( vCuts5, vTemp, c ) {
|
||||
Vec_IntShift( vTemp, 1 );
|
||||
if ( Gia_ManMulFindOverlap(vTemp, vIn1) >= 2 )
|
||||
Vec_IntForEachEntryStart( vTemp, Obj, k, 1 )
|
||||
if ( Vec_IntFind(vIn1, Obj) == -1 ) {
|
||||
Vec_IntPushUnique(vIn2, Obj);
|
||||
}
|
||||
Vec_IntShift( vTemp, -1 );
|
||||
}
|
||||
Vec_IntSort( vIn2, 0 );
|
||||
vOut = NULL;
|
||||
}
|
||||
Vec_IntFree( vIndex );
|
||||
return vRes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Gia_ManMulFindTfo( Gia_Man_t * p, Vec_Int_t * vIn0, Vec_Int_t * vIn1 )
|
||||
{
|
||||
Vec_Int_t * vTfo = Vec_IntAlloc( 100 );
|
||||
Gia_Obj_t * pObj; int i, Obj;
|
||||
Gia_ManIncrementTravId( p );
|
||||
Vec_IntForEachEntry( vIn0, Obj, i )
|
||||
Gia_ObjSetTravIdCurrentId( p, Obj );
|
||||
Vec_IntForEachEntry( vIn1, Obj, i )
|
||||
Gia_ObjSetTravIdCurrentId( p, Obj );
|
||||
Gia_ManForEachAnd( p, pObj, i ) {
|
||||
if ( Gia_ObjIsTravIdCurrentId(p, i) )
|
||||
continue;
|
||||
if ( Gia_ObjIsTravIdCurrentId(p, Gia_ObjFaninId0(pObj, i)) && Gia_ObjIsTravIdCurrentId(p, Gia_ObjFaninId1(pObj, i)) )
|
||||
Gia_ObjSetTravIdCurrentId( p, i ), Vec_IntPush( vTfo, i );
|
||||
}
|
||||
return vTfo;
|
||||
}
|
||||
Vec_Wrd_t * Gia_ManMulFindSimCone( Gia_Man_t * p, Vec_Int_t * vIn0, Vec_Int_t * vIn1, Vec_Wrd_t * vSim0, Vec_Wrd_t * vSim1, Vec_Int_t * vTfo )
|
||||
{
|
||||
Vec_Wrd_t * vRes = Vec_WrdAlloc( Vec_IntSize(vTfo) );
|
||||
Vec_Wrd_t * vSims = Vec_WrdStart( Gia_ManObjNum(p) );
|
||||
Gia_Obj_t * pObj; int i, Obj;
|
||||
Vec_IntForEachEntry( vIn0, Obj, i )
|
||||
Vec_WrdWriteEntry( vSims, Obj, Vec_WrdEntry(vSim0, i) );
|
||||
Vec_IntForEachEntry( vIn1, Obj, i )
|
||||
Vec_WrdWriteEntry( vSims, Obj, Vec_WrdEntry(vSim1, i) );
|
||||
Gia_ManForEachObjVec( vTfo, p, pObj, i ) {
|
||||
word Sim0 = Vec_WrdEntry(vSims, Gia_ObjFaninId0p(p, pObj) );
|
||||
word Sim1 = Vec_WrdEntry(vSims, Gia_ObjFaninId1p(p, pObj) );
|
||||
Vec_WrdWriteEntry( vSims, Gia_ObjId(p, pObj), (Gia_ObjFaninC0(pObj) ? ~Sim0 : Sim0) & (Gia_ObjFaninC1(pObj) ? ~Sim1 : Sim1) );
|
||||
}
|
||||
Vec_IntForEachEntry( vTfo, Obj, i )
|
||||
Vec_WrdPush( vRes, Vec_WrdEntry(vSims, Obj) );
|
||||
Vec_WrdFree( vSims );
|
||||
return vRes;
|
||||
}
|
||||
int Gia_ManMulFindGetArg( Vec_Wrd_t * vSim, int i, int fSigned )
|
||||
{
|
||||
int w, Res = 0; word Word = 0;
|
||||
Vec_WrdForEachEntry( vSim, Word, w )
|
||||
if ( (Word >> i) & 1 )
|
||||
Res |= (1 << w);
|
||||
if ( fSigned && ((Word >> i) & 1) )
|
||||
Res |= ~0 << Vec_WrdSize(vSim);
|
||||
return Res;
|
||||
}
|
||||
void Gia_ManMulFindSetArg( Vec_Wrd_t * vSim, int i, int iNum )
|
||||
{
|
||||
int w; word * pWords = Vec_WrdArray(vSim);
|
||||
for ( w = 0; w < Vec_WrdSize(vSim); w++ )
|
||||
if ( (iNum >> w) & 1 )
|
||||
pWords[w] |= (word)1 << i;
|
||||
}
|
||||
Vec_Wrd_t * Gia_ManMulFindSim( Vec_Wrd_t * vSim0, Vec_Wrd_t * vSim1, int fSigned )
|
||||
{
|
||||
assert( Vec_WrdSize(vSim0) + Vec_WrdSize(vSim1) <= 30 );
|
||||
Vec_Wrd_t * vRes = Vec_WrdStart( Vec_WrdSize(vSim0) + Vec_WrdSize(vSim1) );
|
||||
for ( int i = 0; i < 64; i++ )
|
||||
{
|
||||
int a = Gia_ManMulFindGetArg( vSim0, i, fSigned );
|
||||
int b = Gia_ManMulFindGetArg( vSim1, i, fSigned );
|
||||
Gia_ManMulFindSetArg( vRes, i, a * b );
|
||||
}
|
||||
return vRes;
|
||||
}
|
||||
void Gia_ManMulFindOutputs( Gia_Man_t * p, Vec_Wec_t * vTerms, int fVerbose )
|
||||
{
|
||||
for ( int m = 0; m < Vec_WecSize(vTerms)/3; m++ ) {
|
||||
Vec_Int_t * vIn0 = Vec_WecEntry(vTerms, 3*m+0);
|
||||
Vec_Int_t * vIn1 = Vec_WecEntry(vTerms, 3*m+1);
|
||||
Vec_Int_t * vOut = Vec_WecEntry(vTerms, 3*m+2);
|
||||
Vec_Wrd_t * vSim0 = Vec_WrdStartRandom( Vec_IntSize(vIn0) );
|
||||
Vec_Wrd_t * vSim1 = Vec_WrdStartRandom( Vec_IntSize(vIn1) );
|
||||
Vec_Wrd_t * vSimU = Gia_ManMulFindSim( vSim0, vSim1, 0 );
|
||||
Vec_Wrd_t * vSimS = Gia_ManMulFindSim( vSim0, vSim1, 1 );
|
||||
Vec_Int_t * vTfo = Gia_ManMulFindTfo( p, vIn0, vIn1 );
|
||||
Vec_Wrd_t * vSims = Gia_ManMulFindSimCone( p, vIn0, vIn1, vSim0, vSim1, vTfo );
|
||||
word Word; int w, iPlace;
|
||||
assert( Vec_IntSize(vOut) == 0 );
|
||||
Vec_WrdForEachEntry( vSimU, Word, w ) {
|
||||
if ( (iPlace = Vec_WrdFind(vSims, Word)) >= 0 )
|
||||
Vec_IntPush( vOut, Abc_Var2Lit(Vec_IntEntry(vTfo, iPlace), 0) );
|
||||
else if ( (iPlace = Vec_WrdFind(vSims, ~Word)) >= 0 )
|
||||
Vec_IntPush( vOut, Abc_Var2Lit(Vec_IntEntry(vTfo, iPlace), 1) );
|
||||
else
|
||||
break;
|
||||
}
|
||||
if ( w == Vec_WrdSize(vSimU) )
|
||||
Vec_IntPush(vOut, 0);
|
||||
else
|
||||
Vec_IntClear(vOut);
|
||||
if ( Vec_IntSize(vOut) == 0 )
|
||||
{
|
||||
Vec_IntClear(vOut);
|
||||
Vec_WrdForEachEntry( vSimS, Word, w ) {
|
||||
if ( (iPlace = Vec_WrdFind(vSims, Word)) >= 0 )
|
||||
Vec_IntPush( vOut, Abc_Var2Lit(Vec_IntEntry(vTfo, iPlace), 0) );
|
||||
else if ( (iPlace = Vec_WrdFind(vSims, ~Word)) >= 0 )
|
||||
Vec_IntPush( vOut, Abc_Var2Lit(Vec_IntEntry(vTfo, iPlace), 1) );
|
||||
else
|
||||
break;
|
||||
}
|
||||
if ( w == Vec_WrdSize(vSimS) )
|
||||
Vec_IntPush(vOut, 1);
|
||||
else
|
||||
Vec_IntClear(vOut);
|
||||
}
|
||||
Vec_WrdFree( vSim0 );
|
||||
Vec_WrdFree( vSim1 );
|
||||
Vec_WrdFree( vSimU );
|
||||
Vec_WrdFree( vSimS );
|
||||
Vec_WrdFree( vSims );
|
||||
Vec_IntFree( vTfo );
|
||||
if ( Vec_IntSize(vOut) )
|
||||
continue;
|
||||
Vec_IntClear(vIn0);
|
||||
Vec_IntClear(vIn1);
|
||||
}
|
||||
Vec_WecRemoveEmpty( vTerms );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Ptr_t * Gia_ManMulFindCuts( Gia_Man_t * p, int nCutNum, int fVerbose )
|
||||
{
|
||||
extern Vec_Mem_t * Dau_CollectNpnFunctions( word * p, int nVars, int fVerbose );
|
||||
extern Vec_Ptr_t * Gia_ManMatchCutsArray( Vec_Ptr_t * vTtMems, Gia_Man_t * pGia, int nCutSize, int nCutNum, int fVerbose );
|
||||
word pTruths[3] = { ABC_CONST(0x6969696969696969), ABC_CONST(0x35C035C035C035C0), ABC_CONST(0xF335ACC0F335ACC0) };
|
||||
Vec_Ptr_t * vTtMems = Vec_PtrAlloc( 3 ); Vec_Mem_t * vTtMem; int i;
|
||||
for ( i = 0; i < 3; i++ )
|
||||
Vec_PtrPush( vTtMems, Dau_CollectNpnFunctions( pTruths+i, i+3, fVerbose ) );
|
||||
Vec_Ptr_t * vAll = Gia_ManMatchCutsArray( vTtMems, p, 5, nCutNum, fVerbose );
|
||||
Vec_PtrForEachEntry( Vec_Mem_t *, vTtMems, vTtMem, i )
|
||||
Vec_MemHashFree( vTtMem ), Vec_MemFree( vTtMem );
|
||||
Vec_PtrFree( vTtMems );
|
||||
return vAll;
|
||||
}
|
||||
Vec_Wec_t * Gia_ManMulFindA( Gia_Man_t * p, Vec_Wec_t * vCuts3, int fVerbose )
|
||||
{
|
||||
Vec_Wec_t * vXors = Gia_ManMulFindXors( p, vCuts3, fVerbose );
|
||||
Vec_Wec_t * vTerms = Gia_ManMulFindAInputs( p, vXors, fVerbose );
|
||||
if ( Vec_WecSize(vTerms) )
|
||||
Gia_ManMulFindOutputs( p, vTerms, fVerbose );
|
||||
Vec_WecFree( vXors );
|
||||
return vTerms;
|
||||
}
|
||||
Vec_Wec_t * Gia_ManMulFindB( Gia_Man_t * p, Vec_Wec_t * vCuts4, Vec_Wec_t * vCuts5, int fVerbose )
|
||||
{
|
||||
Vec_Wec_t * vTerms = Vec_WecAlloc( 12 );
|
||||
if ( Vec_WecSize(vCuts4) && Vec_WecSize(vCuts5) )
|
||||
vTerms = Gia_ManMulFindBInputs( p, vCuts4, vCuts5, fVerbose );
|
||||
if ( Vec_WecSize(vTerms) )
|
||||
Gia_ManMulFindOutputs( p, vTerms, fVerbose );
|
||||
return vTerms;
|
||||
}
|
||||
void Gia_ManMulFindPrintSet( Vec_Int_t * vSet, int fLit, int fSkipLast )
|
||||
{
|
||||
int i, Temp, Limit = Vec_IntSize(vSet) - fSkipLast;
|
||||
printf( "{" );
|
||||
Vec_IntForEachEntryStop( vSet, Temp, i, Limit )
|
||||
printf( "%s%d%s", (fLit & Abc_LitIsCompl(Temp)) ? "~":"", fLit ? Abc_Lit2Var(Temp) : Temp, i < Limit-1 ? " ":"" );
|
||||
printf( "}" );
|
||||
}
|
||||
void Gia_ManMulFindPrintOne( Vec_Wec_t * vTerms, int m, int fBooth )
|
||||
{
|
||||
Vec_Int_t * vIn0 = Vec_WecEntry(vTerms, 3*m+0);
|
||||
Vec_Int_t * vIn1 = Vec_WecEntry(vTerms, 3*m+1);
|
||||
Vec_Int_t * vOut = Vec_WecEntry(vTerms, 3*m+2);
|
||||
printf( "%sooth %ssigned : ", fBooth ? "B" : "Non-b", Vec_IntEntryLast(vOut) ? "" : "un" );
|
||||
Gia_ManMulFindPrintSet( vIn0, 0, 0 );
|
||||
printf( " * " );
|
||||
Gia_ManMulFindPrintSet( vIn1, 0, 0 );
|
||||
printf( " = " );
|
||||
Gia_ManMulFindPrintSet( vOut, 1, 1 );
|
||||
printf( "\n" );
|
||||
}
|
||||
void Gia_ManMulFind( Gia_Man_t * p, int nCutNum, int fVerbose )
|
||||
{
|
||||
Vec_Ptr_t * vAll = Gia_ManMulFindCuts( p, nCutNum, fVerbose ); int m;
|
||||
Vec_Wec_t * vCuts3 = (Vec_Wec_t *)Vec_PtrEntry(vAll, 0);
|
||||
Vec_Wec_t * vCuts4 = (Vec_Wec_t *)Vec_PtrEntry(vAll, 1);
|
||||
Vec_Wec_t * vCuts5 = (Vec_Wec_t *)Vec_PtrEntry(vAll, 2);
|
||||
Vec_Wec_t * vTermsB = Gia_ManMulFindB( p, vCuts4, vCuts5, fVerbose );
|
||||
Vec_Wec_t * vTermsA = Gia_ManMulFindA( p, vCuts3, fVerbose );
|
||||
printf( "Detected %d booth and %d non-booth multipliers.\n", Vec_WecSize(vTermsB)/3, Vec_WecSize(vTermsA)/3 );
|
||||
for ( m = 0; m < Vec_WecSize(vTermsA)/3; m++ )
|
||||
Gia_ManMulFindPrintOne( vTermsA, m, 0 );
|
||||
for ( m = 0; m < Vec_WecSize(vTermsB)/3; m++ )
|
||||
Gia_ManMulFindPrintOne( vTermsB, m, 1 );
|
||||
Vec_WecFree( vTermsB );
|
||||
Vec_WecFree( vTermsA );
|
||||
Vec_WecFree( vCuts3 );
|
||||
Vec_WecFree( vCuts4 );
|
||||
Vec_WecFree( vCuts5 );
|
||||
Vec_PtrFree( vAll );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
@ -21,6 +21,7 @@
|
|||
#ifndef ABC__aig__gia__giaNewBdd_h
|
||||
#define ABC__aig__gia__giaNewBdd_h
|
||||
|
||||
#include <cstdlib>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
|
@ -47,6 +48,11 @@ namespace NewBdd {
|
|||
static inline uniq UniqHash(lit Arg0, lit Arg1) { return Arg0 + 4256249 * Arg1; }
|
||||
static inline cac CacHash(lit Arg0, lit Arg1) { return Arg0 + 4256249 * Arg1; }
|
||||
|
||||
static inline void fatal_error(const char* message) {
|
||||
std::cerr << message << std::endl;
|
||||
std::abort();
|
||||
}
|
||||
|
||||
class Cache {
|
||||
private:
|
||||
cac nSize;
|
||||
|
|
@ -62,10 +68,10 @@ namespace NewBdd {
|
|||
public:
|
||||
Cache(int nCacheSizeLog, int nCacheMaxLog, int nVerbose): nVerbose(nVerbose) {
|
||||
if(nCacheMaxLog < nCacheSizeLog)
|
||||
throw std::invalid_argument("nCacheMax must not be smaller than nCacheSize");
|
||||
fatal_error("nCacheMax must not be smaller than nCacheSize");
|
||||
nMax = (cac)1 << nCacheMaxLog;
|
||||
if(!(nMax << 1))
|
||||
throw std::length_error("Memout (nCacheMax) in init");
|
||||
fatal_error("Memout (nCacheMax) in init");
|
||||
nSize = (cac)1 << nCacheSizeLog;
|
||||
if(nVerbose)
|
||||
std::cout << "Allocating " << nSize << " cache entries" << std::endl;
|
||||
|
|
@ -242,7 +248,7 @@ namespace NewBdd {
|
|||
inline ref Ref(lit x) const { return vRefs[Lit2Bvar(x)]; }
|
||||
inline double OneCount(lit x) const {
|
||||
if(vOneCounts.empty())
|
||||
throw std::logic_error("fCountOnes was not set");
|
||||
fatal_error("fCountOnes was not set");
|
||||
if(LitIsCompl(x))
|
||||
return std::pow(2.0, nVars) - vOneCounts[Lit2Bvar(x)];
|
||||
return vOneCounts[Lit2Bvar(x)];
|
||||
|
|
@ -454,7 +460,7 @@ namespace NewBdd {
|
|||
if(nGbc > 1)
|
||||
fRemoved = Gbc();
|
||||
if(!Resize() && !fRemoved && (nGbc != 1 || !Gbc()))
|
||||
throw std::length_error("Memout (node)");
|
||||
fatal_error("Memout (node)");
|
||||
} else
|
||||
break;
|
||||
}
|
||||
|
|
@ -659,29 +665,29 @@ namespace NewBdd {
|
|||
nVerbose = p.nVerbose;
|
||||
// parameter sanity check
|
||||
if(p.nObjsMaxLog < p.nObjsAllocLog)
|
||||
throw std::invalid_argument("nObjsMax must not be smaller than nObjsAlloc");
|
||||
fatal_error("nObjsMax must not be smaller than nObjsAlloc");
|
||||
if(nVars_ >= (int)VarMax())
|
||||
throw std::length_error("Memout (nVars) in init");
|
||||
fatal_error("Memout (nVars) in init");
|
||||
nVars = nVars_;
|
||||
lit nObjsMaxLit = (lit)1 << p.nObjsMaxLog;
|
||||
if(!nObjsMaxLit)
|
||||
throw std::length_error("Memout (nObjsMax) in init");
|
||||
fatal_error("Memout (nObjsMax) in init");
|
||||
if(nObjsMaxLit > (lit)BvarMax())
|
||||
nObjsMax = BvarMax();
|
||||
else
|
||||
nObjsMax = (bvar)nObjsMaxLit;
|
||||
lit nObjsAllocLit = (lit)1 << p.nObjsAllocLog;
|
||||
if(!nObjsAllocLit)
|
||||
throw std::length_error("Memout (nObjsAlloc) in init");
|
||||
fatal_error("Memout (nObjsAlloc) in init");
|
||||
if(nObjsAllocLit > (lit)BvarMax())
|
||||
nObjsAlloc = BvarMax();
|
||||
else
|
||||
nObjsAlloc = (bvar)nObjsAllocLit;
|
||||
if(nObjsAlloc <= (bvar)nVars)
|
||||
throw std::invalid_argument("nObjsAlloc must be larger than nVars");
|
||||
fatal_error("nObjsAlloc must be larger than nVars");
|
||||
uniq nUniqueSize = (uniq)1 << p.nUniqueSizeLog;
|
||||
if(!nUniqueSize)
|
||||
throw std::length_error("Memout (nUniqueSize) in init");
|
||||
fatal_error("Memout (nUniqueSize) in init");
|
||||
// allocation
|
||||
if(nVerbose)
|
||||
std::cout << "Allocating " << nObjsAlloc << " nodes and " << nVars << " x " << nUniqueSize << " unique table entries" << std::endl;
|
||||
|
|
@ -703,7 +709,7 @@ namespace NewBdd {
|
|||
}
|
||||
if(p.fCountOnes) {
|
||||
if(nVars > 1023)
|
||||
throw std::length_error("nVars must be less than 1024 to count ones");
|
||||
fatal_error("nVars must be less than 1024 to count ones");
|
||||
vOneCounts.resize(nObjsAlloc);
|
||||
}
|
||||
// set up cache
|
||||
|
|
@ -780,10 +786,34 @@ namespace NewBdd {
|
|||
for(size_t i = 0; i < vLits.size(); i++)
|
||||
IncRef(vLits[i]);
|
||||
}
|
||||
void RemoveRefIfUnused() {
|
||||
if(!nGbc && nReo == BvarMax())
|
||||
vRefs.clear();
|
||||
}
|
||||
void TurnOnReo(int nReo_ = 0, std::vector<lit> const *vLits = NULL) {
|
||||
if(nReo_)
|
||||
nReo = nReo_;
|
||||
else
|
||||
nReo = nObjs << 1;
|
||||
if((lit)nReo > (lit)BvarMax())
|
||||
nReo = BvarMax();
|
||||
if(vRefs.empty()) {
|
||||
if(vLits)
|
||||
SetRef(*vLits);
|
||||
else
|
||||
vRefs.resize(nObjsAlloc);
|
||||
}
|
||||
}
|
||||
void TurnOffReo() {
|
||||
nReo = BvarMax();
|
||||
if(!nGbc)
|
||||
vRefs.clear();
|
||||
}
|
||||
var GetNumVars() const {
|
||||
return nVars;
|
||||
}
|
||||
void GetOrdering(std::vector<int> &Var2Level_) {
|
||||
Var2Level_.resize(nVars);
|
||||
for(var v = 0; v < nVars; v++)
|
||||
Var2Level_[v] = Var2Level[v];
|
||||
}
|
||||
bvar CountNodes() {
|
||||
bvar count = 1;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#ifndef ABC__aig__gia__giaNewTt_h
|
||||
#define ABC__aig__gia__giaNewTt_h
|
||||
|
||||
#include <cstdlib>
|
||||
#include <limits>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
|
@ -41,6 +42,11 @@ namespace NewTt {
|
|||
static inline ref RefMax() { return std::numeric_limits<ref>::max(); }
|
||||
static inline size SizeMax() { return std::numeric_limits<size>::max(); }
|
||||
|
||||
static void fatal_error(const char* message) {
|
||||
std::cerr << message << std::endl;
|
||||
std::abort();
|
||||
}
|
||||
|
||||
struct Param {
|
||||
int nObjsAllocLog;
|
||||
int nObjsMaxLog;
|
||||
|
|
@ -48,6 +54,7 @@ namespace NewTt {
|
|||
bool fCountOnes;
|
||||
int nGbc;
|
||||
int nReo; // dummy
|
||||
std::vector<int> *pVar2Level; // dummy
|
||||
Param() {
|
||||
nObjsAllocLog = 15;
|
||||
nObjsMaxLog = 20;
|
||||
|
|
@ -181,35 +188,35 @@ namespace NewTt {
|
|||
public:
|
||||
Man(int nVars, Param p): nVars(nVars) {
|
||||
if(p.nObjsMaxLog < p.nObjsAllocLog)
|
||||
throw std::invalid_argument("nObjsMax must not be smaller than nObjsAlloc");
|
||||
fatal_error("nObjsMax must not be smaller than nObjsAlloc");
|
||||
if(nVars >= lww())
|
||||
nSize = 1ull << (nVars - lww());
|
||||
else
|
||||
nSize = 1;
|
||||
if(!nSize)
|
||||
throw std::length_error("Memout (nVars) in init");
|
||||
fatal_error("Memout (nVars) in init");
|
||||
if(!(nSize << p.nObjsMaxLog))
|
||||
throw std::length_error("Memout (nObjsMax) in init");
|
||||
fatal_error("Memout (nObjsMax) in init");
|
||||
lit nObjsMaxLit = (lit)1 << p.nObjsMaxLog;
|
||||
if(!nObjsMaxLit)
|
||||
throw std::length_error("Memout (nObjsMax) in init");
|
||||
fatal_error("Memout (nObjsMax) in init");
|
||||
if(nObjsMaxLit > (lit)BvarMax())
|
||||
nObjsMax = BvarMax();
|
||||
else
|
||||
nObjsMax = (bvar)nObjsMaxLit;
|
||||
lit nObjsAllocLit = (lit)1 << p.nObjsAllocLog;
|
||||
if(!nObjsAllocLit)
|
||||
throw std::length_error("Memout (nObjsAlloc) in init");
|
||||
fatal_error("Memout (nObjsAlloc) in init");
|
||||
if(nObjsAllocLit > (lit)BvarMax())
|
||||
nObjsAlloc = BvarMax();
|
||||
else
|
||||
nObjsAlloc = (bvar)nObjsAllocLit;
|
||||
if(nObjsAlloc <= (bvar)nVars)
|
||||
throw std::invalid_argument("nObjsAlloc must be larger than nVars");
|
||||
fatal_error("nObjsAlloc must be larger than nVars");
|
||||
nTotalSize = nSize << p.nObjsAllocLog;
|
||||
vVals.resize(nTotalSize);
|
||||
if(p.fCountOnes && nVars > 63)
|
||||
throw std::length_error("nVars must be less than 64 to count ones");
|
||||
fatal_error("nVars must be less than 64 to count ones");
|
||||
nObjs = 1;
|
||||
for(int i = 0; i < 6 && i < nVars; i++) {
|
||||
for(size j = 0; j < nSize; j++)
|
||||
|
|
@ -238,7 +245,7 @@ namespace NewTt {
|
|||
if(nGbc > 1)
|
||||
fRemoved = Gbc();
|
||||
if(!Resize() && !fRemoved && (nGbc != 1 || !Gbc()))
|
||||
throw std::length_error("Memout (node)");
|
||||
fatal_error("Memout (node)");
|
||||
}
|
||||
bvar zvar;
|
||||
if(nObjs < nObjsAlloc)
|
||||
|
|
@ -261,10 +268,14 @@ namespace NewTt {
|
|||
for(size_t i = 0; i < vLits.size(); i++)
|
||||
IncRef(vLits[i]);
|
||||
}
|
||||
void TurnOffReo() {
|
||||
void RemoveRefIfUnused() {
|
||||
if(!nGbc)
|
||||
vRefs.clear();
|
||||
}
|
||||
void TurnOffReo() {}
|
||||
int GetNumVars() const {
|
||||
return nVars;
|
||||
}
|
||||
void PrintNode(lit x) const {
|
||||
bvar a = Lit2Bvar(x);
|
||||
word c = LitIsCompl(x)? one(): 0;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,12 @@
|
|||
#include "opt/dau/dau.h"
|
||||
#include "misc/util/utilNam.h"
|
||||
#include "map/scl/sclCon.h"
|
||||
#include "misc/tim/tim.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# include <intrin.h>
|
||||
# define __builtin_popcount __popcnt
|
||||
#endif
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -82,6 +88,7 @@ struct Nf_Man_t_
|
|||
{
|
||||
// user data
|
||||
Gia_Man_t * pGia; // derived manager
|
||||
Tim_Man_t * pManTim; // timing manager
|
||||
Jf_Par_t * pPars; // parameters
|
||||
// matching
|
||||
Vec_Mem_t * vTtMem; // truth tables
|
||||
|
|
@ -223,7 +230,7 @@ void Nf_StoCreateGateAdd( Vec_Mem_t * vTtMem, Vec_Wec_t * vTt2Match, Mio_Cell2_t
|
|||
if ( fPinQuick ) // reduce the number of matches agressively
|
||||
{
|
||||
Vec_IntForEachEntryDouble( vArray, GateId, Entry, i )
|
||||
if ( GateId == (int)pCell->Id && Abc_TtBitCount8[Nf_Int2Cfg(Entry).Phase] == Abc_TtBitCount8[Mat.Phase] )
|
||||
if ( GateId == (int)pCell->Id && __builtin_popcount( Nf_Int2Cfg(Entry).Phase & 0xff ) == __builtin_popcount( Mat.Phase & 0xff ) )
|
||||
return;
|
||||
}
|
||||
else // reduce the number of matches less agressively
|
||||
|
|
@ -379,6 +386,7 @@ Nf_Man_t * Nf_StoCreate( Gia_Man_t * pGia, Jf_Par_t * pPars )
|
|||
p = ABC_CALLOC( Nf_Man_t, 1 );
|
||||
p->clkStart = Abc_Clock();
|
||||
p->pGia = pGia;
|
||||
p->pManTim = (Tim_Man_t *)pGia->pManTime;
|
||||
p->pPars = pPars;
|
||||
p->pNfObjs = ABC_CALLOC( Nf_Obj_t, Gia_ManObjNum(pGia) );
|
||||
p->iCur = 2;
|
||||
|
|
@ -956,21 +964,42 @@ void Nf_ObjMergeOrder( Nf_Man_t * p, int iObj )
|
|||
}
|
||||
void Nf_ManComputeCuts( Nf_Man_t * p )
|
||||
{
|
||||
Gia_Obj_t * pObj; int i, iFanin;
|
||||
Gia_ManForEachAnd( p->pGia, pObj, i )
|
||||
Gia_Obj_t * pObj; int i, iFanin, arrTime;
|
||||
float CutFlow = 0, CutFlowAve = 0; int fFirstCi = 0, nCutFlow = 0;
|
||||
if ( p->pManTim )
|
||||
Tim_ManIncrementTravId( p->pManTim );
|
||||
Gia_ManForEachObjWithBoxes( p->pGia, pObj, i )
|
||||
if ( Gia_ObjIsBuf(pObj) )
|
||||
{
|
||||
iFanin = Gia_ObjFaninId0(pObj, i);
|
||||
Nf_ObjSetCutFlow( p, i, Nf_ObjCutFlow(p, iFanin) );
|
||||
Nf_ObjSetCutDelay( p, i, Nf_ObjCutDelay(p, iFanin) );
|
||||
}
|
||||
else
|
||||
else if ( Gia_ObjIsAnd(pObj) )
|
||||
Nf_ObjMergeOrder( p, i );
|
||||
else if ( Gia_ObjIsCi(pObj) )
|
||||
{
|
||||
if ( fFirstCi ) {
|
||||
CutFlowAve = CutFlow / nCutFlow;
|
||||
CutFlow = 0;
|
||||
nCutFlow = 0;
|
||||
fFirstCi = 0;
|
||||
}
|
||||
arrTime = Tim_ManGetCiArrival( p->pManTim, Gia_ObjCioId(pObj) );
|
||||
Nf_ObjSetCutFlow( p, i, CutFlowAve ); // approximation!
|
||||
Nf_ObjSetCutDelay( p, i, arrTime );
|
||||
}
|
||||
else if ( Gia_ObjIsCo(pObj) )
|
||||
{
|
||||
iFanin = Gia_ObjFaninId0(pObj, i);
|
||||
CutFlow += Nf_ObjCutFlow(p, iFanin);
|
||||
arrTime = Nf_ObjCutDelay(p, iFanin);
|
||||
Tim_ManSetCoArrival( p->pManTim, Gia_ObjCioId(pObj), arrTime );
|
||||
nCutFlow++;
|
||||
fFirstCi = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -1382,14 +1411,36 @@ void Nf_ManCutMatch( Nf_Man_t * p, int iObj )
|
|||
}
|
||||
*/
|
||||
}
|
||||
static inline Nf_Mat_t * Nf_ObjMatchBest( Nf_Man_t * p, int i, int c )
|
||||
{
|
||||
Nf_Mat_t * pD = Nf_ObjMatchD(p, i, c);
|
||||
Nf_Mat_t * pA = Nf_ObjMatchA(p, i, c);
|
||||
assert( pD->fBest != pA->fBest );
|
||||
//assert( Nf_ObjMapRefNum(p, i, c) > 0 );
|
||||
if ( pA->fBest )
|
||||
return pA;
|
||||
if ( pD->fBest )
|
||||
return pD;
|
||||
return NULL;
|
||||
}
|
||||
void Nf_ManComputeMapping( Nf_Man_t * p )
|
||||
{
|
||||
Gia_Obj_t * pObj; int i;
|
||||
Gia_ManForEachAnd( p->pGia, pObj, i )
|
||||
Gia_Obj_t * pObj; int i, arrTime;
|
||||
if ( p->pManTim )
|
||||
Tim_ManIncrementTravId( p->pManTim );
|
||||
Gia_ManForEachObjWithBoxes( p->pGia, pObj, i )
|
||||
if ( Gia_ObjIsBuf(pObj) )
|
||||
Nf_ObjPrepareBuf( p, pObj );
|
||||
else
|
||||
else if ( Gia_ObjIsAnd(pObj) )
|
||||
Nf_ManCutMatch( p, i );
|
||||
else if ( Gia_ObjIsCi(pObj) ) {
|
||||
arrTime = Tim_ManGetCiArrival( p->pManTim, Gia_ObjCioId(pObj) );
|
||||
Nf_ObjPrepareCi( p, i, arrTime );
|
||||
}
|
||||
else if ( Gia_ObjIsCo(pObj) ) {
|
||||
arrTime = Nf_ObjMatchD( p, Gia_ObjFaninId0(pObj, i), Gia_ObjFaninC0(pObj) )->D;
|
||||
Tim_ManSetCoArrival( p->pManTim, Gia_ObjCioId(pObj), arrTime );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1404,18 +1455,6 @@ void Nf_ManComputeMapping( Nf_Man_t * p )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Nf_Mat_t * Nf_ObjMatchBest( Nf_Man_t * p, int i, int c )
|
||||
{
|
||||
Nf_Mat_t * pD = Nf_ObjMatchD(p, i, c);
|
||||
Nf_Mat_t * pA = Nf_ObjMatchA(p, i, c);
|
||||
assert( pD->fBest != pA->fBest );
|
||||
//assert( Nf_ObjMapRefNum(p, i, c) > 0 );
|
||||
if ( pA->fBest )
|
||||
return pA;
|
||||
if ( pD->fBest )
|
||||
return pD;
|
||||
return NULL;
|
||||
}
|
||||
void Nf_ManSetOutputRequireds( Nf_Man_t * p, int fPropCompl )
|
||||
{
|
||||
Gia_Obj_t * pObj;
|
||||
|
|
@ -1425,7 +1464,7 @@ void Nf_ManSetOutputRequireds( Nf_Man_t * p, int fPropCompl )
|
|||
Vec_IntFill( &p->vRequired, nLits, SCL_INFINITY );
|
||||
// compute delay
|
||||
p->pPars->MapDelay = 0;
|
||||
Gia_ManForEachCo( p->pGia, pObj, i )
|
||||
Gia_ManForEachCoWithBoxes( p->pGia, pObj, i )
|
||||
{
|
||||
Required = Nf_ObjMatchD( p, Gia_ObjFaninId0p(p->pGia, pObj), Gia_ObjFaninC0(pObj) )->D;
|
||||
p->pPars->MapDelay = Abc_MaxInt( p->pPars->MapDelay, Required );
|
||||
|
|
@ -1445,7 +1484,9 @@ void Nf_ManSetOutputRequireds( Nf_Man_t * p, int fPropCompl )
|
|||
}
|
||||
//assert( p->pPars->MapDelayTarget == 0 );
|
||||
// set required times
|
||||
Gia_ManForEachCo( p->pGia, pObj, i )
|
||||
if ( p->pManTim )
|
||||
Tim_ManIncrementTravId( p->pManTim );
|
||||
Gia_ManForEachCoWithBoxes( p->pGia, pObj, i )
|
||||
{
|
||||
iObj = Gia_ObjFaninId0p(p->pGia, pObj);
|
||||
fCompl = Gia_ObjFaninC0(pObj);
|
||||
|
|
@ -1470,6 +1511,13 @@ void Nf_ManSetOutputRequireds( Nf_Man_t * p, int fPropCompl )
|
|||
Nf_ObjUpdateRequired( p, iObj, fCompl, Required );
|
||||
if ( fPropCompl && iObj > 0 && Nf_ObjMatchBest(p, iObj, fCompl)->fCompl )
|
||||
Nf_ObjUpdateRequired( p, iObj, !fCompl, Required - p->InvDelayI );
|
||||
|
||||
if ( p->pManTim == NULL )
|
||||
continue;
|
||||
if ( fPropCompl && iObj > 0 && Nf_ObjMatchBest(p, iObj, fCompl)->fCompl )
|
||||
Tim_ManSetCoRequired( p->pManTim, Gia_ObjCioId(pObj), Required - p->InvDelayI );
|
||||
else
|
||||
Tim_ManSetCoRequired( p->pManTim, Gia_ObjCioId(pObj), Required );
|
||||
//Nf_ObjMapRefInc( p, Gia_ObjFaninId0p(p->pGia, pObj), Gia_ObjFaninC0(pObj));
|
||||
}
|
||||
}
|
||||
|
|
@ -1523,7 +1571,7 @@ int Nf_ManSetMapRefs( Nf_Man_t * p )
|
|||
float * pFlowRefs = Vec_FltArray( &p->vFlowRefs );
|
||||
int * pMapRefs = Vec_IntArray( &p->vMapRefs );
|
||||
int nLits = 2*Gia_ManObjNum(p->pGia);
|
||||
int i, c, Id, nRefs[2];
|
||||
int i, c, Id, nRefs[2], reqTime;
|
||||
Gia_Obj_t * pObj;
|
||||
Nf_Mat_t * pD, * pA, * pM;
|
||||
Nf_Mat_t * pDs[2], * pAs[2], * pMs[2];
|
||||
|
|
@ -1541,7 +1589,7 @@ int Nf_ManSetMapRefs( Nf_Man_t * p )
|
|||
p->nInvs = 0;
|
||||
p->pPars->MapAreaF = 0;
|
||||
p->pPars->Area = p->pPars->Edge = 0;
|
||||
Gia_ManForEachAndReverse( p->pGia, pObj, i )
|
||||
Gia_ManForEachObjReverseWithBoxes( p->pGia, pObj, i )
|
||||
{
|
||||
if ( Gia_ObjIsBuf(pObj) )
|
||||
{
|
||||
|
|
@ -1558,6 +1606,28 @@ int Nf_ManSetMapRefs( Nf_Man_t * p )
|
|||
Nf_ObjMapRefInc( p, Gia_ObjFaninId0(pObj, i), Gia_ObjFaninC0(pObj));
|
||||
continue;
|
||||
}
|
||||
if ( Gia_ObjIsCi(pObj) )
|
||||
{
|
||||
if ( Nf_ObjMapRefNum(p, i, 1) )
|
||||
{
|
||||
Nf_ObjMapRefInc( p, i, 0 );
|
||||
Nf_ObjUpdateRequired( p, i, 0, Nf_ObjRequired(p, i, 1) - p->InvDelayI );
|
||||
p->pPars->MapAreaF += p->InvAreaF;
|
||||
p->pPars->Edge++;
|
||||
p->pPars->Area++;
|
||||
p->nInvs++;
|
||||
}
|
||||
reqTime = Abc_MinInt( Nf_ObjRequired(p, i, 0), Nf_ObjRequired(p, i, 1) );
|
||||
Tim_ManSetCiRequired( p->pManTim, Gia_ObjCioId(pObj), reqTime );
|
||||
continue;
|
||||
}
|
||||
if ( Gia_ObjIsCo(pObj) )
|
||||
{
|
||||
reqTime = Tim_ManGetCoRequired( p->pManTim, Gia_ObjCioId(pObj) );
|
||||
Nf_ObjUpdateRequired( p, Gia_ObjFaninId0(pObj, i), Gia_ObjFaninC0(pObj), reqTime );
|
||||
Nf_ObjMapRefInc( p, Gia_ObjFaninId0(pObj, i), Gia_ObjFaninC0(pObj));
|
||||
continue;
|
||||
}
|
||||
// skip if this node is not used
|
||||
for ( c = 0; c < 2; c++ )
|
||||
nRefs[c] = Nf_ObjMapRefNum(p, i, c);
|
||||
|
|
@ -1660,7 +1730,7 @@ int Nf_ManSetMapRefs( Nf_Man_t * p )
|
|||
// - required times are propagated correctly
|
||||
// - references are set correctly
|
||||
}
|
||||
Gia_ManForEachCiId( p->pGia, Id, i )
|
||||
Gia_ManForEachCiIdWithBoxes( p->pGia, Id, i )
|
||||
if ( Nf_ObjMapRefNum(p, Id, 1) )
|
||||
{
|
||||
Nf_ObjMapRefInc( p, Id, 0 );
|
||||
|
|
@ -1949,11 +2019,11 @@ void Nf_ManComputeMappingEla( Nf_Man_t * p )
|
|||
Mio_Cell2_t * pCell;
|
||||
Nf_Mat_t Mb, * pMb = &Mb, * pM;
|
||||
word AreaBef, AreaAft, Gain = 0;
|
||||
int i, c, iVar, Id, fCompl, k, * pCut;
|
||||
int i, c, iVar, Id, fCompl, k, * pCut, reqTime;
|
||||
int Required;
|
||||
Nf_ManSetOutputRequireds( p, 1 );
|
||||
Nf_ManResetMatches( p, p->Iter - p->pPars->nRounds );
|
||||
Gia_ManForEachAndReverse( p->pGia, pObj, i )
|
||||
Gia_ManForEachObjReverseWithBoxes( p->pGia, pObj, i )
|
||||
{
|
||||
if ( Gia_ObjIsBuf(pObj) )
|
||||
{
|
||||
|
|
@ -1962,6 +2032,18 @@ void Nf_ManComputeMappingEla( Nf_Man_t * p )
|
|||
Nf_ObjUpdateRequired( p, Gia_ObjFaninId0(pObj, i), Gia_ObjFaninC0(pObj), Nf_ObjRequired(p, i, 0) );
|
||||
continue;
|
||||
}
|
||||
if ( Gia_ObjIsCi(pObj) )
|
||||
{
|
||||
reqTime = Abc_MinInt( Nf_ObjRequired(p, i, 0), Nf_ObjRequired(p, i, 1) );
|
||||
Tim_ManSetCiRequired( p->pManTim, Gia_ObjCioId(pObj), reqTime );
|
||||
continue;
|
||||
}
|
||||
if ( Gia_ObjIsCo(pObj) )
|
||||
{
|
||||
reqTime = Tim_ManGetCoRequired( p->pManTim, Gia_ObjCioId(pObj) );
|
||||
Nf_ObjUpdateRequired( p, Gia_ObjFaninId0(pObj, i), Gia_ObjFaninC0(pObj), reqTime );
|
||||
continue;
|
||||
}
|
||||
for ( c = 0; c < 2; c++ )
|
||||
if ( Nf_ObjMapRefNum(p, i, c) )
|
||||
{
|
||||
|
|
@ -2012,7 +2094,7 @@ void Nf_ManComputeMappingEla( Nf_Man_t * p )
|
|||
}
|
||||
}
|
||||
}
|
||||
Gia_ManForEachCiId( p->pGia, Id, i )
|
||||
Gia_ManForEachCiIdWithBoxes( p->pGia, Id, i )
|
||||
if ( Nf_ObjMapRefNum(p, Id, 1) )
|
||||
{
|
||||
Required = Nf_ObjRequired( p, i, 1 );
|
||||
|
|
@ -2360,16 +2442,21 @@ void Nf_ManSetDefaultPars( Jf_Par_t * pPars )
|
|||
pPars->nCutNumMax = NF_CUT_MAX;
|
||||
pPars->MapDelayTarget = 0;
|
||||
}
|
||||
Gia_Man_t * Nf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars )
|
||||
Gia_Man_t * Nf_ManPerformMappingInt( Gia_Man_t * pGia, Jf_Par_t * pPars )
|
||||
{
|
||||
Gia_Man_t * pNew = NULL, * pCls;
|
||||
Nf_Man_t * p; int i, Id;
|
||||
if ( Gia_ManHasChoices(pGia) )
|
||||
pPars->fCoarsen = 0;
|
||||
if ( Gia_ManHasChoices(pGia) || pGia->pManTime )
|
||||
pPars->fCoarsen = 0;
|
||||
pCls = pPars->fCoarsen ? Gia_ManDupMuxes(pGia, pPars->nCoarseLimit) : pGia;
|
||||
p = Nf_StoCreate( pCls, pPars );
|
||||
if ( p == NULL )
|
||||
return NULL;
|
||||
// if ( p->pManTim ) Tim_ManPrint( p->pManTim );
|
||||
p->pGia->iFirstNonPiId = p->pManTim ? Tim_ManPiNum(p->pManTim) : Gia_ManCiNum(p->pGia);
|
||||
p->pGia->iFirstPoId = p->pManTim ? Gia_ManCoNum(p->pGia) - Tim_ManPoNum(p->pManTim) : 0;
|
||||
p->pGia->iFirstAndObj = 1 + p->pGia->iFirstNonPiId;
|
||||
p->pGia->iFirstPoObj = Gia_ManObjNum(p->pGia) - Gia_ManCoNum(p->pGia) + p->pGia->iFirstPoId;
|
||||
// if ( pPars->fVeryVerbose )
|
||||
// Nf_StoPrint( p, pPars->fVeryVerbose );
|
||||
if ( pPars->fVerbose && pPars->fCoarsen )
|
||||
|
|
@ -2382,12 +2469,12 @@ Gia_Man_t * Nf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars )
|
|||
Nf_ManPrintQuit( p );
|
||||
if ( Scl_ConIsRunning() )
|
||||
{
|
||||
Gia_ManForEachCiId( p->pGia, Id, i )
|
||||
Gia_ManForEachCiIdWithBoxes( p->pGia, Id, i )
|
||||
Nf_ObjPrepareCi( p, Id, Scl_ConGetInArr(i) );
|
||||
}
|
||||
else
|
||||
{
|
||||
Gia_ManForEachCiId( p->pGia, Id, i )
|
||||
Gia_ManForEachCiIdWithBoxes( p->pGia, Id, i )
|
||||
// Nf_ObjPrepareCi( p, Id, Scl_Flt2Int(p->pGia->vInArrs ? Abc_MaxFloat(0.0, Vec_FltEntry(p->pGia->vInArrs, i)) : 0.0) );
|
||||
Nf_ObjPrepareCi( p, Id, Scl_Flt2Int(p->pGia->vInArrs ? Vec_FltEntry(p->pGia->vInArrs, i) : 0.0) );
|
||||
}
|
||||
|
|
@ -2418,6 +2505,156 @@ Gia_Man_t * Nf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars )
|
|||
return pNew;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_ManCellMappingVerify_rec( Gia_Man_t * p, int iLit )
|
||||
{
|
||||
int iFanLit, k, Result = 1;
|
||||
if ( Abc_LitIsCompl(iLit) && Gia_ObjIsTravIdCurrentId(p, Abc_Lit2Var(iLit)) )
|
||||
return 1;
|
||||
if ( !Abc_LitIsCompl(iLit) && Gia_ObjIsTravIdPreviousId(p, Abc_Lit2Var(iLit)) )
|
||||
return 1;
|
||||
if ( Abc_LitIsCompl(iLit) )
|
||||
Gia_ObjSetTravIdCurrentId(p, Abc_Lit2Var(iLit));
|
||||
else
|
||||
Gia_ObjSetTravIdPreviousId(p, Abc_Lit2Var(iLit));
|
||||
if ( !Gia_ObjIsAndNotBuf(Gia_ManObj(p, Abc_Lit2Var(iLit))) )
|
||||
return 1;
|
||||
if ( !Gia_ObjIsCell(p, iLit) )
|
||||
{
|
||||
Abc_Print( -1, "Gia_ManCellMappingVerify: Internal literal %d does not have mapping.\n", iLit );
|
||||
return 0;
|
||||
}
|
||||
if ( Gia_ObjIsCellBuf(p, iLit) )
|
||||
return Gia_ManCellMappingVerify_rec( p, Gia_ObjFaninLit0p(p, Gia_ManObj(p, Abc_Lit2Var(iLit))) );
|
||||
if ( Gia_ObjIsCellInv(p, iLit) )
|
||||
return Gia_ManCellMappingVerify_rec( p, Abc_LitNot(iLit) );
|
||||
Gia_CellForEachFanin( p, iLit, iFanLit, k )
|
||||
if ( Result )
|
||||
Result &= Gia_ManCellMappingVerify_rec( p, iFanLit );
|
||||
return Result;
|
||||
}
|
||||
void Gia_ManCellMappingVerify( Gia_Man_t * p )
|
||||
{
|
||||
Gia_Obj_t * pObj;
|
||||
int i, iLit, Result = 1;
|
||||
assert( Gia_ManHasCellMapping(p) );
|
||||
Gia_ManIncrementTravId( p );
|
||||
Gia_ManIncrementTravId( p );
|
||||
Gia_ManForEachBuf( p, pObj, i )
|
||||
{
|
||||
if ( !Gia_ObjIsAndNotBuf(Gia_ObjFanin0(pObj)) )
|
||||
continue;
|
||||
iLit = Gia_ObjFaninLit0p(p, pObj);
|
||||
if ( !Gia_ObjIsCell(p, iLit) )
|
||||
{
|
||||
Abc_Print( -1, "Gia_ManCellMappingVerify: Buffer driver %d does not have mapping.\n", Gia_ObjFaninId0p(p, pObj) );
|
||||
Result = 0;
|
||||
continue;
|
||||
}
|
||||
Result &= Gia_ManCellMappingVerify_rec( p, iLit );
|
||||
}
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
{
|
||||
if ( !Gia_ObjIsAndNotBuf(Gia_ObjFanin0(pObj)) )
|
||||
continue;
|
||||
iLit = Gia_ObjFaninLit0p(p, pObj);
|
||||
if ( !Gia_ObjIsCell(p, iLit) )
|
||||
{
|
||||
Abc_Print( -1, "Gia_ManCellMappingVerify: CO driver %d does not have mapping.\n", Gia_ObjFaninId0p(p, pObj) );
|
||||
Result = 0;
|
||||
continue;
|
||||
}
|
||||
Result &= Gia_ManCellMappingVerify_rec( p, iLit );
|
||||
}
|
||||
// if ( Result )
|
||||
// Abc_Print( 1, "Mapping verified correctly.\n" );
|
||||
}
|
||||
|
||||
void Gia_ManTransferCellMapping( Gia_Man_t * p, Gia_Man_t * pGia )
|
||||
{
|
||||
int iLit, iLitNew, k, iFanLit, iPlace;
|
||||
if ( !Gia_ManHasCellMapping(pGia) )
|
||||
return;
|
||||
Gia_ManCellMappingVerify( pGia );
|
||||
Vec_IntFreeP( &p->vCellMapping );
|
||||
p->vCellMapping = Vec_IntAlloc( 4 * Gia_ManObjNum(p) );
|
||||
Vec_IntFill( p->vCellMapping, 2 * Gia_ManObjNum(p), 0 );
|
||||
Gia_ManForEachCell( pGia, iLit )
|
||||
{
|
||||
Gia_Obj_t * pObj = Gia_ManObj(pGia, Abc_Lit2Var(iLit));
|
||||
if ( Gia_ObjValue(pObj) == ~0 ) // handle dangling LUT
|
||||
continue;
|
||||
assert( !Abc_LitIsCompl( Gia_ObjValue(pObj) ) );
|
||||
iLitNew = Abc_LitNotCond( Gia_ObjValue(pObj), Abc_LitIsCompl(iLit) );
|
||||
if ( Gia_ObjIsCellInv(pGia, iLit) ) {
|
||||
Vec_IntWriteEntry( p->vCellMapping, iLitNew, -1 );
|
||||
continue;
|
||||
}
|
||||
if ( Gia_ObjIsCellBuf(pGia, iLit) ) {
|
||||
Vec_IntWriteEntry( p->vCellMapping, iLitNew, -2 );
|
||||
continue;
|
||||
}
|
||||
Vec_IntWriteEntry( p->vCellMapping, iLitNew, Vec_IntSize(p->vCellMapping) );
|
||||
iPlace = Vec_IntSize( p->vCellMapping );
|
||||
Vec_IntPush( p->vCellMapping, Gia_ObjCellSize(pGia, iLit) );
|
||||
Gia_CellForEachFanin( pGia, iLit, iFanLit, k )
|
||||
{
|
||||
int iFanLitNew = Gia_ObjValue( Gia_ManObj(pGia, Abc_Lit2Var(iFanLit)) );
|
||||
if ( iFanLitNew == ~0 ) // handle dangling LUT fanin
|
||||
Vec_IntAddToEntry( p->vCellMapping, iPlace, -1 );
|
||||
else
|
||||
Vec_IntPush( p->vCellMapping, Abc_LitNotCond(iFanLitNew, Abc_LitIsCompl(iFanLit)) );
|
||||
}
|
||||
Vec_IntPush( p->vCellMapping, Gia_ObjCellId(pGia, iLit) );
|
||||
}
|
||||
Gia_ManCellMappingVerify( p );
|
||||
}
|
||||
Gia_Man_t * Nf_ManPerformMapping( Gia_Man_t * p, Jf_Par_t * pPars )
|
||||
{
|
||||
Gia_Man_t * pNew;
|
||||
if ( p->pManTime && Tim_ManBoxNum((Tim_Man_t*)p->pManTime) && Gia_ManIsNormalized(p) )
|
||||
{
|
||||
pNew = Gia_ManDupUnnormalize( p );
|
||||
if ( pNew == NULL )
|
||||
return NULL;
|
||||
Gia_ManTransferTiming( pNew, p );
|
||||
p = pNew;
|
||||
// mapping
|
||||
pNew = Nf_ManPerformMappingInt( p, pPars );
|
||||
if ( pNew != p )
|
||||
{
|
||||
Gia_ManTransferTiming( pNew, p );
|
||||
Gia_ManStop( p );
|
||||
}
|
||||
// normalize
|
||||
pNew = Gia_ManDupNormalize( p = pNew, 0 );
|
||||
Gia_ManTransferCellMapping( pNew, p );
|
||||
Gia_ManTransferTiming( pNew, p );
|
||||
Gia_ManStop( p );
|
||||
assert( Gia_ManIsNormalized(pNew) );
|
||||
}
|
||||
else
|
||||
{
|
||||
pNew = Nf_ManPerformMappingInt( p, pPars );
|
||||
Gia_ManTransferTiming( pNew, p );
|
||||
//Gia_ManCellMappingVerify( pNew );
|
||||
}
|
||||
//pNew->MappedDelay = (int)((If_Par_t *)pp)->FinalDelay;
|
||||
//pNew->MappedArea = (int)((If_Par_t *)pp)->FinalArea;
|
||||
return pNew;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -184,13 +184,15 @@ static inline int Min_ManAppendCo( Min_Man_t * p, int iLit0 )
|
|||
***********************************************************************/
|
||||
void Min_ManFromGia_rec( Min_Man_t * pNew, Gia_Man_t * p, int iObj )
|
||||
{
|
||||
Gia_Obj_t * pObj = Gia_ManObj(p, iObj);
|
||||
Gia_Obj_t * pObj = Gia_ManObj(p, iObj); int iLit0, iLit1;
|
||||
if ( ~pObj->Value )
|
||||
return;
|
||||
assert( Gia_ObjIsAnd(pObj) );
|
||||
Min_ManFromGia_rec( pNew, p, Gia_ObjFaninId0(pObj, iObj) );
|
||||
Min_ManFromGia_rec( pNew, p, Gia_ObjFaninId1(pObj, iObj) );
|
||||
pObj->Value = Min_ManAppendObj( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
iLit0 = Gia_ObjFanin0Copy(pObj);
|
||||
iLit1 = Gia_ObjFanin1Copy(pObj);
|
||||
pObj->Value = Min_ManAppendObj( pNew, Abc_MinInt(iLit0, iLit1), Abc_MaxInt(iLit0, iLit1) );
|
||||
}
|
||||
Min_Man_t * Min_ManFromGia( Gia_Man_t * p, Vec_Int_t * vOuts )
|
||||
{
|
||||
|
|
@ -205,7 +207,7 @@ Min_Man_t * Min_ManFromGia( Gia_Man_t * p, Vec_Int_t * vOuts )
|
|||
Gia_ManForEachAnd( p, pObj, i )
|
||||
pObj->Value = Min_ManAppendObj( pNew, Gia_ObjFaninLit0(pObj, i), Gia_ObjFaninLit1(pObj, i) );
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
pObj->Value = Min_ManAppendCo( pNew, Gia_ObjFaninLit0p(p, pObj) );
|
||||
pObj->Value = Min_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -403,8 +405,10 @@ static inline char Min_LitIsImplied2( Min_Man_t * p, int iLit )
|
|||
char Val1 = Min_LitValL(p, iLit1);
|
||||
assert( Min_LitIsNode(p, iLit) ); // internal node
|
||||
assert( Min_LitValL(p, iLit) == 2 ); // unassigned
|
||||
if ( Val0 == 2 && Min_LitIsNode(p, iLit0) )
|
||||
if ( Val0 == 2 && Min_LitIsNode(p, iLit0) ) {
|
||||
Val0 = Min_LitIsImplied1(p, iLit0);
|
||||
Val1 = Min_LitValL(p, iLit1);
|
||||
}
|
||||
if ( Val1 == 2 && Min_LitIsNode(p, iLit1) )
|
||||
Val1 = Min_LitIsImplied1(p, iLit1);
|
||||
if ( Min_LitIsXor(iLit, iLit0, iLit1) )
|
||||
|
|
@ -427,8 +431,10 @@ static inline char Min_LitIsImplied3( Min_Man_t * p, int iLit )
|
|||
char Val1 = Min_LitValL(p, iLit1);
|
||||
assert( Min_LitIsNode(p, iLit) ); // internal node
|
||||
assert( Min_LitValL(p, iLit) == 2 ); // unassigned
|
||||
if ( Val0 == 2 && Min_LitIsNode(p, iLit0) )
|
||||
if ( Val0 == 2 && Min_LitIsNode(p, iLit0) ) {
|
||||
Val0 = Min_LitIsImplied2(p, iLit0);
|
||||
Val1 = Min_LitValL(p, iLit1);
|
||||
}
|
||||
if ( Val1 == 2 && Min_LitIsNode(p, iLit1) )
|
||||
Val1 = Min_LitIsImplied2(p, iLit1);
|
||||
if ( Min_LitIsXor(iLit, iLit0, iLit1) )
|
||||
|
|
@ -451,8 +457,10 @@ static inline char Min_LitIsImplied4( Min_Man_t * p, int iLit )
|
|||
char Val1 = Min_LitValL(p, iLit1);
|
||||
assert( Min_LitIsNode(p, iLit) ); // internal node
|
||||
assert( Min_LitValL(p, iLit) == 2 ); // unassigned
|
||||
if ( Val0 == 2 && Min_LitIsNode(p, iLit0) )
|
||||
if ( Val0 == 2 && Min_LitIsNode(p, iLit0) ) {
|
||||
Val0 = Min_LitIsImplied3(p, iLit0);
|
||||
Val1 = Min_LitValL(p, iLit1);
|
||||
}
|
||||
if ( Val1 == 2 && Min_LitIsNode(p, iLit1) )
|
||||
Val1 = Min_LitIsImplied3(p, iLit1);
|
||||
if ( Min_LitIsXor(iLit, iLit0, iLit1) )
|
||||
|
|
@ -475,8 +483,10 @@ static inline char Min_LitIsImplied5( Min_Man_t * p, int iLit )
|
|||
char Val1 = Min_LitValL(p, iLit1);
|
||||
assert( Min_LitIsNode(p, iLit) ); // internal node
|
||||
assert( Min_LitValL(p, iLit) == 2 ); // unassigned
|
||||
if ( Val0 == 2 && Min_LitIsNode(p, iLit0) )
|
||||
if ( Val0 == 2 && Min_LitIsNode(p, iLit0) ) {
|
||||
Val0 = Min_LitIsImplied4(p, iLit0);
|
||||
Val1 = Min_LitValL(p, iLit1);
|
||||
}
|
||||
if ( Val1 == 2 && Min_LitIsNode(p, iLit1) )
|
||||
Val1 = Min_LitIsImplied4(p, iLit1);
|
||||
if ( Min_LitIsXor(iLit, iLit0, iLit1) )
|
||||
|
|
@ -1351,6 +1361,74 @@ void Min_ManTest2( Gia_Man_t * p )
|
|||
Vec_WrdFreeP( &vSimsPi );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_GenerateCexesDumpFile( char * pFileName, Gia_Man_t * p, Vec_Wec_t * vCexes, int fShort )
|
||||
{
|
||||
FILE * pFile = fopen( pFileName, "wb" );
|
||||
if ( pFile == NULL ) {
|
||||
printf( "Cannot open output file name \"%s\".\n", pFileName );
|
||||
return;
|
||||
}
|
||||
Gia_Obj_t * pObj;
|
||||
char * pLine = ABC_CALLOC( char, Gia_ManCiNum(p)+3 );
|
||||
int i, k, c, iLit, nOuts[2] = {0}, nCexes = Vec_WecSize(vCexes) / Gia_ManCoNum(p);
|
||||
Gia_ManForEachCo( p, pObj, i ) {
|
||||
if ( Gia_ObjFaninLit0p(p, Gia_ManCo(p, i)) == 0 ) {
|
||||
fprintf( pFile, "%d : unsat\n", i );
|
||||
nOuts[0]++;
|
||||
}
|
||||
else if ( fShort ) {
|
||||
for ( c = 0; c < nCexes; c++ ) {
|
||||
Vec_Int_t * vPat = Vec_WecEntry( vCexes, i*nCexes+c );
|
||||
fprintf( pFile, "%d :", i );
|
||||
if ( Vec_IntSize(vPat) == 0 )
|
||||
fprintf( pFile, " not available" );
|
||||
else
|
||||
Vec_IntForEachEntry( vPat, iLit, k )
|
||||
fprintf( pFile, " %d", iLit );
|
||||
fprintf( pFile, "\n" );
|
||||
}
|
||||
nOuts[1]++;
|
||||
}
|
||||
else {
|
||||
for ( c = 0; c < nCexes; c++ ) {
|
||||
Vec_Int_t * vPat = Vec_WecEntry( vCexes, i*nCexes+c );
|
||||
memset(pLine, '-', Gia_ManCiNum(p) );
|
||||
Vec_IntForEachEntry( vPat, iLit, k )
|
||||
pLine[Abc_Lit2Var(iLit)-1] = '1' - Abc_LitIsCompl(iLit);
|
||||
fprintf( pFile, "%d : %s\n", i, pLine );
|
||||
}
|
||||
nOuts[1]++;
|
||||
}
|
||||
}
|
||||
printf( "Information about %d sat, %d unsat, and %d undecided primary outputs was written into file \"%s\".\n",
|
||||
nOuts[1], nOuts[0], Gia_ManCoNum(p)-nOuts[1]-nOuts[0], pFileName );
|
||||
fclose( pFile );
|
||||
free( pLine );
|
||||
}
|
||||
void Gia_GenerateCexes( char * pFileName, Gia_Man_t * p, int nMaxTries, int nMinCexes, int fUseSim, int fUseSat, int fShort, int fVerbose, int fVeryVerbose )
|
||||
{
|
||||
unsigned Start = Abc_Random(1);
|
||||
Vec_Int_t * vStats[3] = {0}; int i;
|
||||
Vec_Wec_t * vCexes = Min_ManComputeCexes( p, NULL, nMaxTries, nMinCexes, vStats, fUseSim, fUseSat, fVerbose );
|
||||
assert( Vec_WecSize(vCexes) == Gia_ManCoNum(p) * nMinCexes );
|
||||
Gia_GenerateCexesDumpFile( pFileName, p, vCexes, fShort );
|
||||
for ( i = 0; i < 3; i++ )
|
||||
Vec_IntFreeP( &vStats[i] );
|
||||
Vec_WecFree( vCexes );
|
||||
Start = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include "misc/extra/extra.h"
|
||||
#include "sat/glucose/AbcGlucose.h"
|
||||
#include "misc/util/utilTruth.h"
|
||||
#include "base/io/ioResub.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -945,6 +946,301 @@ int Gia_QbfSolve( Gia_Man_t * pGia, int nPars, int nIterLimit, int nConfLimit, i
|
|||
return RetValue;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derive the SAT solver.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
sat_solver * Gia_ManGenSolver( Gia_Man_t * p, Vec_Int_t * vInsOuts, int nIns )
|
||||
{
|
||||
Gia_Obj_t * pObj; int i, nObjs = Gia_ManObjNum(p);
|
||||
sat_solver * pSat = sat_solver_new();
|
||||
sat_solver_setnvars( pSat, 2 * nObjs );
|
||||
Gia_ManIncrementTravId(p);
|
||||
Gia_ManForEachObjVecStart( vInsOuts, p, pObj, i, nIns )
|
||||
Gia_ObjSetTravIdCurrent(p, pObj);
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
if ( !Gia_ObjIsTravIdCurrent(p, pObj) )
|
||||
sat_solver_add_and( pSat, i, Gia_ObjFaninId0(pObj, i), Gia_ObjFaninId1(pObj, i), Gia_ObjFaninC0(pObj), Gia_ObjFaninC1(pObj), 0 );
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
sat_solver_add_and( pSat, nObjs+i, nObjs+Gia_ObjFaninId0(pObj, i), nObjs+Gia_ObjFaninId1(pObj, i), Gia_ObjFaninC0(pObj), Gia_ObjFaninC1(pObj), 0 );
|
||||
Gia_ManForEachCi( p, pObj, i )
|
||||
if ( !Gia_ObjIsTravIdCurrent(p, pObj) )
|
||||
sat_solver_add_buffer( pSat, nObjs+Gia_ObjId(p, pObj), Gia_ObjId(p, pObj), 0 );
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
if ( Gia_ObjFaninId0p(p, pObj) > 0 ) {
|
||||
sat_solver_add_buffer( pSat, Gia_ObjId(p, pObj), Gia_ObjFaninId0p(p, pObj), Gia_ObjFaninC0(pObj) );
|
||||
sat_solver_add_buffer( pSat, nObjs+Gia_ObjId(p, pObj), nObjs+Gia_ObjFaninId0p(p, pObj), Gia_ObjFaninC0(pObj) );
|
||||
sat_solver_add_buffer( pSat, nObjs+Gia_ObjId(p, pObj), Gia_ObjId(p, pObj), 0 );
|
||||
}
|
||||
return pSat;
|
||||
}
|
||||
Vec_Int_t * Gia_ManGenCombs( Gia_Man_t * p, Vec_Int_t * vInsOuts, int nIns, int fVerbose )
|
||||
{
|
||||
int nTimeOut = 600, nConfLimit = 1000000;
|
||||
int i, iSatVar, Iter, Mask, nSolutions = 0, RetValue = 0;
|
||||
abctime clkStart = Abc_Clock();
|
||||
sat_solver * pSat = Gia_ManGenSolver( p, vInsOuts, nIns );
|
||||
Vec_Int_t * vLits = Vec_IntAlloc( 100 );
|
||||
Vec_Int_t * vRes = Vec_IntAlloc( 1000 );
|
||||
for ( Iter = 0; Iter < 1000000; Iter++ )
|
||||
{
|
||||
int status = sat_solver_solve( pSat, NULL, NULL, (ABC_INT64_T)nConfLimit, 0, 0, 0 );
|
||||
if ( status == l_False ) { RetValue = 1; break; }
|
||||
if ( status == l_Undef ) { RetValue = 0; break; }
|
||||
nSolutions++;
|
||||
// extract SAT assignment
|
||||
Mask = 0;
|
||||
Vec_IntClear( vLits );
|
||||
Vec_IntForEachEntry( vInsOuts, iSatVar, i ) {
|
||||
Vec_IntPush( vLits, Abc_Var2Lit(iSatVar, sat_solver_var_value(pSat, iSatVar)) );
|
||||
if ( sat_solver_var_value(pSat, iSatVar) )
|
||||
Mask |= 1 << (Vec_IntSize(vInsOuts)-1-i);
|
||||
}
|
||||
Vec_IntPush( vRes, Mask );
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "%5d : ", Iter );
|
||||
Vec_IntForEachEntry( vInsOuts, iSatVar, i ) {
|
||||
if ( i == nIns ) printf( " " );
|
||||
printf( "%d", (Mask >> (Vec_IntSize(vInsOuts)-1-i)) & 1 );
|
||||
}
|
||||
printf( "\n" );
|
||||
}
|
||||
// add clause
|
||||
if ( !sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits) ) )
|
||||
{ RetValue = 1; break; }
|
||||
if ( nTimeOut && (Abc_Clock() - clkStart)/CLOCKS_PER_SEC >= nTimeOut ) { RetValue = 0; break; }
|
||||
}
|
||||
Vec_IntSort( vRes, 0 );
|
||||
Vec_IntFree( vLits );
|
||||
sat_solver_delete( pSat );
|
||||
if ( RetValue == 0 )
|
||||
Vec_IntFreeP( &vRes );
|
||||
if ( fVerbose )
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clkStart );
|
||||
return vRes;
|
||||
}
|
||||
void Gia_ManGenWriteRel( Vec_Int_t * vRes, int nIns, int nOuts, char * pFileName )
|
||||
{
|
||||
int i, k, Mask, nVars = nIns + nOuts;
|
||||
Abc_RData_t * p2, * p = Abc_RDataStart( nIns, nOuts, Vec_IntSize(vRes) );
|
||||
Vec_IntForEachEntry( vRes, Mask, i ) {
|
||||
for ( k = 0; k < nVars; k++ )
|
||||
if ( (Mask >> (nVars-1-k)) & 1 ) { // the bit is 1
|
||||
if ( k < nIns )
|
||||
Abc_RDataSetIn( p, k, i );
|
||||
else
|
||||
Abc_RDataSetOut( p, 2*(k-nIns)+1, i );
|
||||
}
|
||||
else { // the bit is zero
|
||||
if ( k >= nIns )
|
||||
Abc_RDataSetOut( p, 2*(k-nIns), i );
|
||||
}
|
||||
}
|
||||
Abc_WritePla( p, pFileName, 0 );
|
||||
p2 = Abc_RData2Rel( p );
|
||||
Abc_WritePla( p2, Extra_FileNameGenericAppend(pFileName, "_rel.pla"), 1 );
|
||||
Abc_RDataStop( p2 );
|
||||
Abc_RDataStop( p );
|
||||
}
|
||||
void Gia_ManGenRel2( Gia_Man_t * pGia, Vec_Int_t * vInsOuts, int nIns, char * pFileName, int fVerbose )
|
||||
{
|
||||
Vec_Int_t * vRes = Gia_ManGenCombs( pGia, vInsOuts, nIns, fVerbose );
|
||||
if ( vRes == NULL ) {
|
||||
printf( "Enumerating solutions did not succeed.\n" );
|
||||
return;
|
||||
}
|
||||
Gia_ManGenWriteRel( vRes, nIns, Vec_IntSize(vInsOuts)-nIns, pFileName );
|
||||
Vec_IntFree( vRes );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derive the SAT solver.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Gia_ManCollectNodeTfos( Gia_Man_t * p, int * pNodes, int nNodes )
|
||||
{
|
||||
Vec_Int_t * vTfo = Vec_IntAlloc( 100 );
|
||||
Gia_Obj_t * pObj; int i;
|
||||
Gia_ManIncrementTravId( p );
|
||||
for ( i = 0; i < nNodes; i++ )
|
||||
Gia_ObjSetTravIdCurrentId( p, pNodes[i] );
|
||||
Gia_ManForEachAnd( p, pObj, i ) {
|
||||
if ( Gia_ObjIsTravIdCurrentId(p, i) )
|
||||
continue;
|
||||
if ( Gia_ObjIsTravIdCurrentId(p, Gia_ObjFaninId0(pObj, i)) || Gia_ObjIsTravIdCurrentId(p, Gia_ObjFaninId1(pObj, i)) )
|
||||
Gia_ObjSetTravIdCurrentId( p, i ), Vec_IntPush( vTfo, i );
|
||||
}
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
if ( Gia_ObjIsTravIdCurrentId(p, Gia_ObjFaninId0p(p, pObj)) )
|
||||
Vec_IntPush( vTfo, Gia_ObjId(p, pObj) );
|
||||
return vTfo;
|
||||
}
|
||||
Vec_Int_t * Gia_ManCollectNodeTfis( Gia_Man_t * p, Vec_Int_t * vNodes )
|
||||
{
|
||||
Vec_Int_t * vTfi = Vec_IntAlloc( 100 );
|
||||
Gia_Obj_t * pObj; int i, Id;
|
||||
Gia_ManIncrementTravId( p );
|
||||
Gia_ManForEachObjVec( vNodes, p, pObj, i )
|
||||
if ( Gia_ObjIsCo(pObj) )
|
||||
Gia_ObjSetTravIdCurrentId( p, Gia_ObjFaninId0p(p, pObj) );
|
||||
Gia_ManForEachAndReverse( p, pObj, i ) {
|
||||
if ( !Gia_ObjIsTravIdCurrentId(p, i) )
|
||||
continue;
|
||||
Gia_ObjSetTravIdCurrentId(p, Gia_ObjFaninId0(pObj, i));
|
||||
Gia_ObjSetTravIdCurrentId(p, Gia_ObjFaninId1(pObj, i));
|
||||
}
|
||||
Gia_ManForEachCiId( p, Id, i )
|
||||
if ( Gia_ObjIsTravIdCurrentId(p, Id) )
|
||||
Vec_IntPush( vTfi, Id );
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
if ( Gia_ObjIsTravIdCurrentId(p, i) )
|
||||
Vec_IntPush( vTfi, i );
|
||||
return vTfi;
|
||||
}
|
||||
Gia_Man_t * Gia_ManGenRelMiter( Gia_Man_t * pGia, Vec_Int_t * vInsOuts, int nIns )
|
||||
{
|
||||
Vec_Int_t * vTfo = Gia_ManCollectNodeTfos( pGia, Vec_IntEntryP(vInsOuts, nIns), Vec_IntSize(vInsOuts)-nIns );
|
||||
Vec_Int_t * vTfi = Gia_ManCollectNodeTfis( pGia, vTfo );
|
||||
Vec_Int_t * vInLits = Vec_IntAlloc( nIns );
|
||||
Vec_Int_t * vOutLits = Vec_IntAlloc( Vec_IntSize(vInsOuts) - nIns );
|
||||
Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj; int i, iLit = 0;
|
||||
Gia_ManFillValue( pGia );
|
||||
pNew = Gia_ManStart( 1000 );
|
||||
pNew->pName = Abc_UtilStrsav( pGia->pName );
|
||||
Gia_ManHashAlloc( pNew );
|
||||
Gia_ManForEachObjVec( vTfi, pGia, pObj, i )
|
||||
if ( Gia_ObjIsCi(pObj) )
|
||||
pObj->Value = Gia_ManAppendCi(pNew);
|
||||
for ( i = 0; i < Vec_IntSize(vInsOuts)-nIns; i++ )
|
||||
Vec_IntPush( vInLits, Gia_ManAppendCi(pNew) );
|
||||
Gia_ManForEachObjVec( vTfi, pGia, pObj, i )
|
||||
if ( Gia_ObjIsAnd(pObj) )
|
||||
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
Gia_ManForEachObjVec( vTfo, pGia, pObj, i )
|
||||
if ( Gia_ObjIsCo(pObj) )
|
||||
pObj->Value = Gia_ObjFanin0Copy(pObj);
|
||||
Gia_ManForEachObjVec( vInsOuts, pGia, pObj, i )
|
||||
if ( i < nIns )
|
||||
Vec_IntPush( vOutLits, pObj->Value );
|
||||
else
|
||||
pObj->Value = Vec_IntEntry( vInLits, i-nIns );
|
||||
Gia_ManForEachObjVec( vTfo, pGia, pObj, i )
|
||||
if ( Gia_ObjIsAnd(pObj) )
|
||||
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
Gia_ManForEachObjVec( vTfo, pGia, pObj, i )
|
||||
if ( Gia_ObjIsCo(pObj) )
|
||||
iLit = Gia_ManHashOr( pNew, iLit, Gia_ManHashXor(pNew, Gia_ObjFanin0Copy(pObj), pObj->Value) );
|
||||
Gia_ManAppendCo( pNew, iLit );
|
||||
Vec_IntForEachEntry( vOutLits, iLit, i )
|
||||
Gia_ManAppendCo( pNew, iLit );
|
||||
Vec_IntFree( vTfo );
|
||||
Vec_IntFree( vTfi );
|
||||
Vec_IntFree( vInLits );
|
||||
Vec_IntFree( vOutLits );
|
||||
pNew = Gia_ManCleanup( pTemp = pNew );
|
||||
Gia_ManStop( pTemp );
|
||||
Gia_ManSetRegNum( pNew, Gia_ManRegNum(pGia) );
|
||||
return pNew;
|
||||
}
|
||||
void Gia_ManPrintRelMinterm( int Mint, int nIns, int nVars )
|
||||
{
|
||||
for ( int i = 0; i < nVars; i++ )
|
||||
printf( "%s%d", i == nIns ? " ":"", (Mint >> (nVars-1-i)) & 1 );
|
||||
printf( "\n" );
|
||||
}
|
||||
Vec_Int_t * Gia_ManGenIoCombs( Gia_Man_t * pGia, Vec_Int_t * vInsOuts, int nIns, int fVerbose )
|
||||
{
|
||||
abctime clkStart = Abc_Clock();
|
||||
int nTimeOut = 600, nConfLimit = 1000000;
|
||||
int i, iNode, iSatVar, Iter, Mask, nSolutions = 0, RetValue = 0;
|
||||
Gia_Man_t * pMiter = Gia_ManGenRelMiter( pGia, vInsOuts, nIns );
|
||||
Cnf_Dat_t * pCnf = (Cnf_Dat_t*)Mf_ManGenerateCnf( pMiter, 8, 0, 0, 0, 0 );
|
||||
sat_solver * pSat = (sat_solver*)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
|
||||
int iLit = Abc_Var2Lit( 1, 0 ); // enumerating the care set (the miter output is 1)
|
||||
int status = sat_solver_addclause( pSat, &iLit, &iLit + 1 ); assert( status );
|
||||
Vec_Int_t * vSatVars = Vec_IntAlloc( Vec_IntSize(vInsOuts) );
|
||||
Vec_IntForEachEntry( vInsOuts, iNode, i )
|
||||
Vec_IntPush( vSatVars, i < nIns ? 2+i : pCnf->nVars-Vec_IntSize(vInsOuts)+i );
|
||||
Vec_Int_t * vLits = Vec_IntAlloc( 100 );
|
||||
Vec_Int_t * vRes = Vec_IntAlloc( 1000 );
|
||||
for ( Iter = 0; Iter < 1000000; Iter++ )
|
||||
{
|
||||
int status = sat_solver_solve( pSat, NULL, NULL, (ABC_INT64_T)nConfLimit, 0, 0, 0 );
|
||||
if ( status == l_False ) { RetValue = 1; break; }
|
||||
if ( status == l_Undef ) { RetValue = 0; break; }
|
||||
nSolutions++;
|
||||
// extract SAT assignment
|
||||
Mask = 0;
|
||||
Vec_IntClear( vLits );
|
||||
Vec_IntForEachEntry( vSatVars, iSatVar, i ) {
|
||||
Vec_IntPush( vLits, Abc_Var2Lit(iSatVar, sat_solver_var_value(pSat, iSatVar)) );
|
||||
if ( sat_solver_var_value(pSat, iSatVar) )
|
||||
Mask |= 1 << (Vec_IntSize(vInsOuts)-1-i);
|
||||
}
|
||||
Vec_IntPush( vRes, Mask );
|
||||
if ( 0 ) {
|
||||
printf( "%5d : ", Iter );
|
||||
Gia_ManPrintRelMinterm( Mask, nIns, Vec_IntSize(vSatVars) );
|
||||
}
|
||||
// add clause
|
||||
if ( !sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits) ) )
|
||||
{ RetValue = 1; break; }
|
||||
if ( nTimeOut && (Abc_Clock() - clkStart)/CLOCKS_PER_SEC >= nTimeOut ) { RetValue = 0; break; }
|
||||
}
|
||||
// complement the set of input/output minterms
|
||||
Vec_Int_t * vBits = Vec_IntStart( 1 << Vec_IntSize(vInsOuts) );
|
||||
Vec_IntForEachEntry( vRes, Mask, i )
|
||||
Vec_IntWriteEntry( vBits, Mask, 1 );
|
||||
Vec_IntClear( vRes );
|
||||
Vec_IntForEachEntry( vBits, Mask, i )
|
||||
if ( !Mask )
|
||||
Vec_IntPush( vRes, i );
|
||||
Vec_IntFree( vBits );
|
||||
// cleanup
|
||||
Vec_IntFree( vLits );
|
||||
sat_solver_delete( pSat );
|
||||
Gia_ManStop( pMiter );
|
||||
Cnf_DataFree( pCnf );
|
||||
if ( RetValue == 0 )
|
||||
Vec_IntFreeP( &vRes );
|
||||
return vRes;
|
||||
}
|
||||
void Gia_ManGenRel( Gia_Man_t * pGia, Vec_Int_t * vInsOuts, int nIns, char * pFileName, int fVerbose )
|
||||
{
|
||||
abctime clkStart = Abc_Clock();
|
||||
Vec_Int_t * vRes = Gia_ManGenIoCombs( pGia, vInsOuts, nIns, fVerbose );
|
||||
if ( vRes == NULL ) {
|
||||
printf( "Enumerating solutions did not succeed.\n" );
|
||||
return;
|
||||
}
|
||||
Gia_ManGenWriteRel( vRes, nIns, Vec_IntSize(vInsOuts)-nIns, pFileName );
|
||||
if ( fVerbose ) {
|
||||
printf( "The resulting relation with %d input/output minterms is written into file \"%s\". ", Vec_IntSize(vRes), pFileName );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clkStart );
|
||||
if ( 0 ) {
|
||||
int i, Mint;
|
||||
Vec_IntForEachEntry( vRes, Mint, i )
|
||||
Gia_ManPrintRelMinterm( Mint, nIns, Vec_IntSize(vInsOuts) );
|
||||
}
|
||||
}
|
||||
Vec_IntFree( vRes );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include "misc/vec/vecQue.h"
|
||||
#include "misc/vec/vecHsh.h"
|
||||
#include "misc/util/utilTruth.h"
|
||||
#include "base/io/ioResub.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -2048,10 +2049,111 @@ Vec_Int_t * Gia_ManDeriveSubset( Gia_Man_t * p, Vec_Wrd_t * vFuncs, Vec_Int_t *
|
|||
return vRes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Gia_ManResubFindUsed( Vec_Int_t * vRes, int nDivs, int nNodes, Vec_Int_t * vSupp )
|
||||
{
|
||||
int i, k, iLit, Counter = 1;
|
||||
Vec_Int_t * vUsed = Vec_IntStartFull( nDivs );
|
||||
Vec_Int_t * vRes2 = Vec_IntDup( vRes );
|
||||
Vec_IntWriteEntry( vUsed, 0, 0 );
|
||||
assert( Vec_IntSize(vRes) % 2 == 1 );
|
||||
Vec_IntSort( vRes2, 0 );
|
||||
Vec_IntForEachEntry( vRes2, iLit, k )
|
||||
{
|
||||
int iVar = Abc_Lit2Var(iLit);
|
||||
if ( iVar > 0 && iVar < nDivs && Vec_IntEntry(vUsed, iVar) == -1 ) {
|
||||
Vec_IntWriteEntry( vUsed, iVar, Counter++ );
|
||||
Vec_IntPush( vSupp, iVar-2 );
|
||||
}
|
||||
}
|
||||
Vec_IntFree( vRes2 );
|
||||
for ( i = nDivs; i < nDivs + nNodes; i++ )
|
||||
Vec_IntPush( vUsed, Counter++ );
|
||||
return vUsed;
|
||||
}
|
||||
Vec_Int_t * Gia_ManResubRemapSolution( Vec_Int_t * vRes, Vec_Int_t * vUsed )
|
||||
{
|
||||
int i, iLit;
|
||||
Vec_Int_t * vResNew = Vec_IntAlloc( Vec_IntSize(vRes) );
|
||||
Vec_IntForEachEntry( vRes, iLit, i )
|
||||
Vec_IntPush( vResNew, Abc_Lit2LitV(Vec_IntArray(vUsed), iLit) );
|
||||
return vResNew;
|
||||
}
|
||||
void Gia_ManResubRecordSolution( char * pFileName, Vec_Int_t * vRes, int nDivs )
|
||||
{
|
||||
FILE * pFile = fopen( pFileName, "ab" );
|
||||
if ( pFile == NULL ) {
|
||||
printf( "Cannot open file \"%s\" for writing.\n", pFileName );
|
||||
return;
|
||||
}
|
||||
Vec_Int_t * vSupp = Vec_IntAlloc( 100 );
|
||||
Vec_Int_t * vUsed = Gia_ManResubFindUsed( vRes, nDivs, Vec_IntSize(vRes)/2, vSupp );
|
||||
Vec_Int_t * vResN = Gia_ManResubRemapSolution( vRes, vUsed );
|
||||
|
||||
int i, Temp;
|
||||
fprintf( pFile, "\n.s" );
|
||||
Vec_IntForEachEntry( vSupp, Temp, i )
|
||||
fprintf( pFile, " %d", Temp );
|
||||
fprintf( pFile, "\n.a" );
|
||||
Vec_IntForEachEntry( vResN, Temp, i )
|
||||
fprintf( pFile, " %d", Temp );
|
||||
fprintf( pFile, "\n" );
|
||||
fclose( pFile );
|
||||
|
||||
Vec_IntFree( vUsed );
|
||||
Vec_IntFree( vSupp );
|
||||
Vec_IntFree( vResN );
|
||||
}
|
||||
Gia_Man_t * Gia_ManResubUnateOne( char * pFileName, int nLimit, int nDivMax, int fWriteSol, int fVerbose )
|
||||
{
|
||||
Gia_Man_t * pNew = NULL;
|
||||
Abc_RData_t * p = Abc_ReadPla( pFileName );
|
||||
if ( p == NULL ) return NULL;
|
||||
assert( p->nOuts == 1 );
|
||||
Vec_Ptr_t * vDivs = Vec_PtrAlloc( 2+p->nIns );
|
||||
Vec_Int_t * vRes = Vec_IntAlloc( 100 );
|
||||
Vec_PtrPush( vDivs, Vec_WrdEntryP(p->vSimsOut, 0*p->nSimWords) );
|
||||
Vec_PtrPush( vDivs, Vec_WrdEntryP(p->vSimsOut, 1*p->nSimWords) );
|
||||
int i, k, ArraySize, * pArray;
|
||||
for ( i = 0; i < p->nIns; i++ )
|
||||
Vec_PtrPush( vDivs, Vec_WrdEntryP(p->vSimsIn, i*p->nSimWords) );
|
||||
Abc_ResubPrepareManager( p->nSimWords );
|
||||
if ( fVerbose )
|
||||
printf( "The problem has %d divisors and %d outputs.\n", p->nIns, p->nOuts );
|
||||
ArraySize = Abc_ResubComputeFunction( (void **)Vec_PtrArray(vDivs), Vec_PtrSize(vDivs), p->nSimWords, nLimit, nDivMax, 0, 0, 1, fVerbose, &pArray );
|
||||
for ( k = 0; k < ArraySize; k++ )
|
||||
Vec_IntPush( vRes, pArray[k] );
|
||||
if ( ArraySize ) {
|
||||
//Vec_IntPrint( vRes );
|
||||
Vec_Wec_t * vGates = Vec_WecStart(1);
|
||||
Vec_IntAppend( Vec_WecEntry(vGates, 0), vRes );
|
||||
pNew = Gia_ManConstructFromGates( vGates, Vec_PtrSize(vDivs) );
|
||||
Vec_WecFree( vGates );
|
||||
if ( fVerbose )
|
||||
printf( "The solution has %d inputs and %d nodes.\n", Gia_ManCiNum(pNew), Gia_ManAndNum(pNew) );
|
||||
}
|
||||
if ( fWriteSol && ArraySize )
|
||||
Gia_ManResubRecordSolution( pFileName, vRes, Vec_PtrSize(vDivs) );
|
||||
Abc_ResubPrepareManager( 0 );
|
||||
Vec_IntFree( vRes );
|
||||
Vec_PtrFree( vDivs );
|
||||
Abc_RDataStop( p );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "gia.h"
|
||||
#include "misc/util/utilTruth.h"
|
||||
#include "base/io/ioResub.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -45,6 +46,7 @@ struct Res6_Man_t_
|
|||
Vec_Int_t vSol; // current solution
|
||||
Vec_Int_t vSolBest; // best solution
|
||||
Vec_Int_t vTempBest;// current best solution
|
||||
Vec_Int_t vSupp; // support
|
||||
};
|
||||
|
||||
extern void Dau_DsdPrintFromTruth2( word * pTruth, int nVarsInit );
|
||||
|
|
@ -95,11 +97,47 @@ static inline void Res6_ManStop( Res6_Man_t * p )
|
|||
Vec_IntErase( &p->vSol );
|
||||
Vec_IntErase( &p->vSolBest );
|
||||
Vec_IntErase( &p->vTempBest );
|
||||
Vec_IntErase( &p->vSupp );
|
||||
ABC_FREE( p->ppLits );
|
||||
ABC_FREE( p->ppSets );
|
||||
ABC_FREE( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Res6_Man_t * Res6_ManReadPla( char * pFileName )
|
||||
{
|
||||
int i, n;
|
||||
Abc_RData_t * pData = Abc_ReadPla( pFileName ); assert( pData->nOuts == 1 );
|
||||
Res6_Man_t * p = pData ? Res6_ManStart( 0, pData->nIns, pData->nOuts, pData->nPats ) : NULL;
|
||||
if ( p == NULL ) return NULL;
|
||||
assert( pData->nSimWords == p->nWords );
|
||||
for ( i = 1; i < p->nDivs; i++ )
|
||||
for ( n = 0; n < 2; n++ )
|
||||
Abc_TtCopy( p->ppLits[2*i+n], Vec_WrdEntryP(pData->vSimsIn, (i-1)*pData->nSimWords), pData->nSimWords, n );
|
||||
for ( i = 0; i < (1 << p->nOuts); i++ )
|
||||
Abc_TtCopy( p->ppSets[i], Vec_WrdEntryP(pData->vSimsOut, i*pData->nSimWords), pData->nSimWords, 0 );
|
||||
if ( pData->vDivs )
|
||||
Vec_IntForEachEntry( pData->vDivs, n, i )
|
||||
Vec_IntPush( &p->vSupp, 1+n );
|
||||
if ( pData->vSol ) {
|
||||
Vec_IntForEachEntry( pData->vSol, n, i )
|
||||
Vec_IntPush( &p->vSol, n );
|
||||
Vec_IntPush( &p->vSol, Vec_IntEntryLast(&p->vSol) );
|
||||
}
|
||||
Abc_RDataStop( pData );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -197,7 +235,7 @@ void Res6_ManWrite( char * pFileName, Res6_Man_t * p )
|
|||
void Res6_ManPrintProblem( Res6_Man_t * p, int fVerbose )
|
||||
{
|
||||
int i, nInputs = (p->nIns && p->nIns < 6) ? p->nIns : 6;
|
||||
printf( "Problem: In = %d Div = %d Out = %d Pattern = %d\n", p->nIns, p->nDivs - p->nIns - 1, p->nOuts, p->nPats );
|
||||
printf( "Problem: In = %d Div = %d Out = %d Pat = %d\n", p->nIns, p->nDivs - p->nIns - 1, p->nOuts, p->nPats );
|
||||
if ( !fVerbose )
|
||||
return;
|
||||
printf( "%02d : %s\n", 0, "const0" );
|
||||
|
|
@ -426,6 +464,7 @@ void Res6_ManResubCheck( char * pFileNameRes, char * pFileNameSol, int fVerbose
|
|||
{
|
||||
Res6_Man_t * p = Res6_ManRead( pFileNameRes );
|
||||
Vec_Int_t * vSol = Res6_ManReadSol( FileNameSol );
|
||||
//Vec_IntPrint( vSol );
|
||||
if ( p == NULL || vSol == NULL )
|
||||
return;
|
||||
if ( fVerbose )
|
||||
|
|
@ -440,6 +479,80 @@ void Res6_ManResubCheck( char * pFileNameRes, char * pFileNameSol, int fVerbose
|
|||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Res6_FindBestEvalPla( Res6_Man_t * p, Vec_Int_t * vSol )
|
||||
{
|
||||
int i, n, iObj, iLit0, iLit1, iOffset = 2*(1+Vec_IntSize(&p->vSupp));
|
||||
assert( Vec_IntSize(vSol) % 2 == 0 );
|
||||
Vec_IntForEachEntry( &p->vSupp, iObj, i )
|
||||
for ( n = 0; n < 2; n++ )
|
||||
Abc_TtCopy( p->ppLits[2*(1+i)+n], p->ppLits[2*iObj+n], p->nWords, 0 );
|
||||
Vec_IntForEachEntryDouble( vSol, iLit0, iLit1, i )
|
||||
{
|
||||
if ( iLit0 > iLit1 )
|
||||
{
|
||||
Abc_TtXor( p->ppLits[iOffset+i+0], p->ppLits[iLit0], p->ppLits[iLit1], p->nWords, 0 );
|
||||
Abc_TtXor( p->ppLits[iOffset+i+1], p->ppLits[iLit0], p->ppLits[iLit1], p->nWords, 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
Abc_TtAnd( p->ppLits[iOffset+i+0], p->ppLits[iLit0], p->ppLits[iLit1], p->nWords, 0 );
|
||||
Abc_TtOr ( p->ppLits[iOffset+i+1], p->ppLits[iLit0^1], p->ppLits[iLit1^1], p->nWords );
|
||||
}
|
||||
}
|
||||
return Res6_FindGetCost( p, Vec_IntEntryLast(vSol) );
|
||||
}
|
||||
void Res6_ManResubVerifyPla( Res6_Man_t * p, Vec_Int_t * vSol )
|
||||
{
|
||||
int Cost = Res6_FindBestEvalPla( p, vSol );
|
||||
if ( Cost == 0 )
|
||||
printf( "Verification successful.\n" );
|
||||
else
|
||||
printf( "Verification FAILED with %d errors on %d patterns.\n", Cost, p->nPats );
|
||||
}
|
||||
void Res6_PrintSolutionPla( Vec_Int_t * vSol, int nSuppSize, int nDivs )
|
||||
{
|
||||
int iNode, nNodes = Vec_IntSize(vSol)/2-1;
|
||||
assert( Vec_IntSize(vSol) % 2 == 0 );
|
||||
printf( "Solution: In = %d Div = %d Node = %d Out = %d\n", nSuppSize, nDivs-1, nNodes, 1 );
|
||||
for ( iNode = 0; iNode <= nNodes; iNode++ )
|
||||
{
|
||||
int * pLits = Vec_IntEntryP( vSol, 2*iNode );
|
||||
printf( "x%-2d = ", 1+nSuppSize+iNode );
|
||||
Res6_LitPrint( pLits[0], 1+nSuppSize );
|
||||
if ( pLits[0] != pLits[1] )
|
||||
{
|
||||
printf( " %c ", pLits[0] < pLits[1] ? '&' : '^' );
|
||||
Res6_LitPrint( pLits[1], 1+nSuppSize );
|
||||
}
|
||||
printf( "\n" );
|
||||
}
|
||||
}
|
||||
void Res6_ManResubCheckPla( char * pFileName, int fVerbose )
|
||||
{
|
||||
Res6_Man_t * p = Res6_ManReadPla( pFileName );
|
||||
if ( p == NULL ) return;
|
||||
//Vec_IntPrint( &p->vSupp );
|
||||
//Vec_IntPrint( &p->vSol );
|
||||
if ( fVerbose )
|
||||
Res6_ManPrintProblem( p, 0 );
|
||||
if ( fVerbose )
|
||||
Res6_PrintSolutionPla( &p->vSol, Vec_IntSize(&p->vSupp), p->nDivs );
|
||||
//if ( fVerbose )
|
||||
// Res6_PrintSuppSims( vSol, p->ppLits, p->nWords, p->nDivs );
|
||||
Res6_ManResubVerifyPla( p, &p->vSol );
|
||||
Res6_ManStop( p );
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -1129,7 +1129,7 @@ void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds,
|
|||
char FileNameDot[200];
|
||||
FILE * pFile;
|
||||
Vec_Int_t * vXors = NULL, * vAdds = fAdders ? Ree_ManComputeCuts( pMan, &vXors, 0 ) : NULL;
|
||||
sprintf( FileNameDot, "%s", Extra_FileNameGenericAppend(pMan->pName, ".dot") );
|
||||
sprintf( FileNameDot, "%s", Extra_FileNameGenericAppend(pMan->pName ? pMan->pName : (char *)"unknown", ".dot") );
|
||||
// check that the file can be opened
|
||||
if ( (pFile = fopen( FileNameDot, "w" )) == NULL )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3625,7 +3625,7 @@ Gia_Man_t * Gia_ManChangeTest3( Gia_Man_t * p )
|
|||
{
|
||||
extern void Exa6_WriteFile2( char * pFileName, int nVars, int nDivs, int nOuts, Vec_Wrd_t * vSimsDiv, Vec_Wrd_t * vSimsOut );
|
||||
extern void Exa_ManExactPrint( Vec_Wrd_t * vSimsDiv, Vec_Wrd_t * vSimsOut, int nDivs, int nOuts );
|
||||
extern Mini_Aig_t * Exa_ManExactSynthesis6Int( Vec_Wrd_t * vSimsDiv, Vec_Wrd_t * vSimsOut, int nVars, int nDivs, int nOuts, int nNodes, int fOnlyAnd, int fVerbose );
|
||||
extern Mini_Aig_t * Exa_ManExactSynthesis6Int( Vec_Wrd_t * vSimsDiv, Vec_Wrd_t * vSimsOut, int nVars, int nDivs, int nOuts, int nNodes, int fOnlyAnd, int fVerbose, char * pFileName );
|
||||
extern Gia_Man_t * Gia_ManDupMini( Gia_Man_t * p, Vec_Int_t * vIns, Vec_Int_t * vDivs, Vec_Int_t * vOuts, Mini_Aig_t * pMini );
|
||||
|
||||
Gia_Man_t * pNew = NULL;
|
||||
|
|
@ -3639,7 +3639,7 @@ Gia_Man_t * Gia_ManChangeTest3( Gia_Man_t * p )
|
|||
Gia_ManRelCompute( p, vIns, vDivs, vOuts, &vSimsDiv, &vSimsOut );
|
||||
Exa_ManExactPrint( vSimsDiv, vSimsOut, 1 + Vec_IntSize(vIns) + Vec_IntSize(vDivs), Vec_IntSize(vOuts) );
|
||||
//Exa6_WriteFile2( "mul44_i%d_n%d_t%d_s%d.rel", Vec_IntSize(vIns), Vec_IntSize(vDivs), Vec_IntSize(vOuts), nNodes );
|
||||
pMini = Exa_ManExactSynthesis6Int( vSimsDiv, vSimsOut, Vec_IntSize(vIns), Vec_IntSize(vDivs), Vec_IntSize(vOuts), nNodes, 1, 1 );
|
||||
pMini = Exa_ManExactSynthesis6Int( vSimsDiv, vSimsOut, Vec_IntSize(vIns), Vec_IntSize(vDivs), Vec_IntSize(vOuts), nNodes, 1, 1, NULL );
|
||||
if ( pMini )
|
||||
{
|
||||
pNew = Gia_ManDupMini( p, vIns, vDivs, vOuts, pMini );
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [giaDeep.c]
|
||||
FileName [giaStoch.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: giaDeep.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
Revision [$Id: giaStoch.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
|
|
@ -22,23 +22,13 @@
|
|||
#include "base/main/main.h"
|
||||
#include "base/cmd/cmd.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifdef WIN32
|
||||
#include <process.h>
|
||||
#define unlink _unlink
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef ABC_USE_PTHREADS
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "../lib/pthread.h"
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -108,7 +98,7 @@ void Gia_StochProcessArray( Vec_Ptr_t * vGias, char * pScript, int TimeSecs, int
|
|||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Processing on a many cores.]
|
||||
Synopsis [Processing on many cores.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -117,27 +107,6 @@ void Gia_StochProcessArray( Vec_Ptr_t * vGias, char * pScript, int TimeSecs, int
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
#ifndef ABC_USE_PTHREADS
|
||||
|
||||
void Gia_StochProcess( Vec_Ptr_t * vGias, char * pScript, int nProcs, int TimeSecs, int fVerbose )
|
||||
{
|
||||
Gia_StochProcessArray( vGias, pScript, TimeSecs, fVerbose );
|
||||
}
|
||||
|
||||
#else // pthreads are used
|
||||
|
||||
|
||||
#define PAR_THR_MAX 100
|
||||
typedef struct Gia_StochThData_t_
|
||||
{
|
||||
Vec_Ptr_t * vGias;
|
||||
char * pScript;
|
||||
int Index;
|
||||
int Rand;
|
||||
int nTimeOut;
|
||||
int fWorking;
|
||||
} Gia_StochThData_t;
|
||||
|
||||
Gia_Man_t * Gia_StochProcessOne( Gia_Man_t * p, char * pScript, int Rand, int TimeSecs )
|
||||
{
|
||||
Gia_Man_t * pNew;
|
||||
|
|
@ -166,87 +135,68 @@ Gia_Man_t * Gia_StochProcessOne( Gia_Man_t * p, char * pScript, int Rand, int Ti
|
|||
return Gia_ManDup(p);
|
||||
}
|
||||
|
||||
void * Gia_StochWorkerThread( void * pArg )
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Generic concurrent processing.]
|
||||
|
||||
Description [User-defined problem-specific data and the way to process it.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
typedef struct StochSynData_t_
|
||||
{
|
||||
Gia_StochThData_t * pThData = (Gia_StochThData_t *)pArg;
|
||||
volatile int * pPlace = &pThData->fWorking;
|
||||
Gia_Man_t * pGia, * pNew;
|
||||
while ( 1 )
|
||||
{
|
||||
while ( *pPlace == 0 );
|
||||
assert( pThData->fWorking );
|
||||
if ( pThData->Index == -1 )
|
||||
{
|
||||
pthread_exit( NULL );
|
||||
assert( 0 );
|
||||
return NULL;
|
||||
}
|
||||
pGia = (Gia_Man_t *)Vec_PtrEntry( pThData->vGias, pThData->Index );
|
||||
pNew = Gia_StochProcessOne( pGia, pThData->pScript, pThData->Rand, pThData->nTimeOut );
|
||||
Gia_ManStop( pGia );
|
||||
Vec_PtrWriteEntry( pThData->vGias, pThData->Index, pNew );
|
||||
pThData->fWorking = 0;
|
||||
}
|
||||
assert( 0 );
|
||||
return NULL;
|
||||
Gia_Man_t * pIn;
|
||||
Gia_Man_t * pOut;
|
||||
char * pScript;
|
||||
int Rand;
|
||||
int TimeOut;
|
||||
} StochSynData_t;
|
||||
|
||||
int Gia_StochProcess1( void * p )
|
||||
{
|
||||
StochSynData_t * pData = (StochSynData_t *)p;
|
||||
assert( pData->pIn != NULL );
|
||||
assert( pData->pOut == NULL );
|
||||
pData->pOut = Gia_StochProcessOne( pData->pIn, pData->pScript, pData->Rand, pData->TimeOut );
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Gia_StochProcess( Vec_Ptr_t * vGias, char * pScript, int nProcs, int TimeSecs, int fVerbose )
|
||||
{
|
||||
Gia_StochThData_t ThData[PAR_THR_MAX];
|
||||
pthread_t WorkerThread[PAR_THR_MAX];
|
||||
int i, k, status;
|
||||
if ( fVerbose )
|
||||
printf( "Running concurrent synthesis with %d processes.\n", nProcs );
|
||||
fflush( stdout );
|
||||
if ( nProcs < 2 )
|
||||
return Gia_StochProcessArray( vGias, pScript, TimeSecs, fVerbose );
|
||||
// subtract manager thread
|
||||
nProcs--;
|
||||
assert( nProcs >= 1 && nProcs <= PAR_THR_MAX );
|
||||
// start threads
|
||||
if ( nProcs <= 2 ) {
|
||||
if ( fVerbose )
|
||||
printf( "Running non-concurrent synthesis.\n" ), fflush(stdout);
|
||||
Gia_StochProcessArray( vGias, pScript, TimeSecs, fVerbose );
|
||||
return;
|
||||
}
|
||||
StochSynData_t * pData = ABC_CALLOC( StochSynData_t, Vec_PtrSize(vGias) );
|
||||
Vec_Ptr_t * vData = Vec_PtrAlloc( Vec_PtrSize(vGias) );
|
||||
Gia_Man_t * pGia; int i;
|
||||
Abc_Random(1);
|
||||
for ( i = 0; i < nProcs; i++ )
|
||||
{
|
||||
ThData[i].vGias = vGias;
|
||||
ThData[i].pScript = pScript;
|
||||
ThData[i].Index = -1;
|
||||
ThData[i].Rand = Abc_Random(0) % 0x1000000;
|
||||
ThData[i].nTimeOut = TimeSecs;
|
||||
ThData[i].fWorking = 0;
|
||||
status = pthread_create( WorkerThread + i, NULL, Gia_StochWorkerThread, (void *)(ThData + i) ); assert( status == 0 );
|
||||
Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i ) {
|
||||
pData[i].pIn = pGia;
|
||||
pData[i].pOut = NULL;
|
||||
pData[i].pScript = pScript;
|
||||
pData[i].Rand = Abc_Random(0) % 0x1000000;
|
||||
pData[i].TimeOut = TimeSecs;
|
||||
Vec_PtrPush( vData, pData+i );
|
||||
}
|
||||
// look at the threads
|
||||
for ( k = 0; k < Vec_PtrSize(vGias); k++ )
|
||||
{
|
||||
for ( i = 0; i < nProcs; i++ )
|
||||
{
|
||||
if ( ThData[i].fWorking )
|
||||
continue;
|
||||
ThData[i].Index = k;
|
||||
ThData[i].fWorking = 1;
|
||||
break;
|
||||
}
|
||||
if ( i == nProcs )
|
||||
k--;
|
||||
}
|
||||
// wait till threads finish
|
||||
for ( i = 0; i < nProcs; i++ )
|
||||
if ( ThData[i].fWorking )
|
||||
i = -1;
|
||||
// stop threads
|
||||
for ( i = 0; i < nProcs; i++ )
|
||||
{
|
||||
assert( !ThData[i].fWorking );
|
||||
// stop
|
||||
ThData[i].Index = -1;
|
||||
ThData[i].fWorking = 1;
|
||||
if ( fVerbose )
|
||||
printf( "Running concurrent synthesis with %d processes.\n", nProcs ), fflush(stdout);
|
||||
Util_ProcessThreads( Gia_StochProcess1, vData, nProcs, TimeSecs, fVerbose );
|
||||
// replace old AIGs by new AIGs
|
||||
Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i ) {
|
||||
Gia_ManStop( pGia );
|
||||
Vec_PtrWriteEntry( vGias, i, pData[i].pOut );
|
||||
}
|
||||
Vec_PtrFree( vData );
|
||||
ABC_FREE( pData );
|
||||
}
|
||||
|
||||
#endif // pthreads are used
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "aig/gia/gia.h"
|
||||
#include "base/main/mainInt.h"
|
||||
#include "base/io/ioResub.h"
|
||||
#include "misc/util/utilTruth.h"
|
||||
#include "misc/extra/extra.h"
|
||||
#include "misc/vec/vecHsh.h"
|
||||
|
|
@ -185,6 +186,50 @@ Supp_Man_t * Supp_ManCreate( Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t *
|
|||
Supp_ManInit( p );
|
||||
return p;
|
||||
}
|
||||
int Supp_DeriveLines2( Supp_Man_t * p )
|
||||
{
|
||||
assert( Vec_WrdSize(p->vSims) % p->nWords == 0 );
|
||||
int n, nDivWords = Abc_Bit6WordNum( Vec_WrdSize(p->vSims) / p->nWords );
|
||||
for ( n = 0; n < 2; n++ )
|
||||
{
|
||||
p->vDivs[n] = Vec_WrdStart( 64*p->nWords*nDivWords );
|
||||
p->vPats[n] = Vec_WrdStart( 64*p->nWords*nDivWords );
|
||||
Abc_TtCopy( Vec_WrdArray(p->vDivs[n]), Vec_WrdArray(p->vSims), Vec_WrdSize(p->vSims), !n );
|
||||
Extra_BitMatrixTransposeP( p->vDivs[n], p->nWords, p->vPats[n], nDivWords );
|
||||
}
|
||||
return nDivWords;
|
||||
}
|
||||
Supp_Man_t * Supp_ManCreate2( Vec_Wrd_t * vIsfs, Vec_Wrd_t * vSims, Vec_Int_t * vWeights, int nWords, int nIters, int nRounds )
|
||||
{
|
||||
Supp_Man_t * p = ABC_CALLOC( Supp_Man_t, 1 );
|
||||
assert( Vec_WrdSize(vSims)%nWords == 0 );
|
||||
p->nIters = nIters;
|
||||
p->nRounds = nRounds;
|
||||
p->nWords = nWords;
|
||||
p->vIsfs = vIsfs;
|
||||
p->vCands = Vec_IntStartNatural( Vec_WrdSize(vSims)/nWords );
|
||||
p->vWeights = NULL;
|
||||
p->vSims = vSims;
|
||||
p->vSimsC = NULL;
|
||||
p->pGia = NULL;
|
||||
// computed data
|
||||
p->nDivWords = Supp_DeriveLines2( p );
|
||||
p->vMatrix = Vec_PtrAlloc( 100 );
|
||||
p->vMask = Vec_WrdAlloc( 100 );
|
||||
p->vRowTemp = Vec_WrdStart( 64*p->nDivWords );
|
||||
p->vCosts = Vec_IntStart( Vec_IntSize(p->vCands) );
|
||||
p->pHash = Hsh_VecManStart( 1000 );
|
||||
p->vSFuncs = Vec_WrdAlloc( 1000 );
|
||||
p->vSStarts = Vec_IntAlloc( 1000 );
|
||||
p->vSCount = Vec_IntAlloc( 1000 );
|
||||
p->vSPairs = Vec_IntAlloc( 1000 );
|
||||
p->vSolutions = Vec_WecStart( 16 );
|
||||
p->vTemp = Vec_IntAlloc( 10 );
|
||||
p->vTempSets = Vec_IntAlloc( 10 );
|
||||
p->vTempPairs = Vec_IntAlloc( 10 );
|
||||
Supp_ManInit( p );
|
||||
return p;
|
||||
}
|
||||
void Supp_ManCleanMatrix( Supp_Man_t * p )
|
||||
{
|
||||
Vec_Wrd_t * vTemp; int i;
|
||||
|
|
@ -214,6 +259,8 @@ void Supp_ManDelete( Supp_Man_t * p )
|
|||
Vec_IntFreeP( &p->vTemp );
|
||||
Vec_IntFreeP( &p->vTempSets );
|
||||
Vec_IntFreeP( &p->vTempPairs );
|
||||
if ( p->vSims == NULL )
|
||||
Vec_IntFreeP( &p->vCands );
|
||||
ABC_FREE( p );
|
||||
}
|
||||
int Supp_ManMemory( Supp_Man_t * p )
|
||||
|
|
@ -771,6 +818,53 @@ void Supp_DeriveDumpSol( Vec_Int_t * vSet, Vec_Int_t * vRes, int nDivs )
|
|||
printf( "Dumped solution info file \"%s\".\n", Buffer );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Supp_DeriveDumpProb2( Vec_Wrd_t * vIsfs, Vec_Wrd_t * vDivs, int nWords, Vec_Int_t * vSupp, Vec_Int_t * vRes )
|
||||
{
|
||||
char Buffer[100]; int i, k, Temp, nDivs = Vec_WrdSize(vDivs)/nWords;
|
||||
int RetValue = sprintf( Buffer, "%02d.pla", s_Counter );
|
||||
FILE * pFile = fopen( Buffer, "wb" );
|
||||
if ( pFile == NULL )
|
||||
printf( "Cannot open output file.\n" );
|
||||
// fprintf( pFile, "resyn %d %d %d %d\n", 0, nDivs, 1, 64*nWords );
|
||||
fprintf( pFile, ".i %d\n", nDivs );
|
||||
fprintf( pFile, ".o %d\n", 1 );
|
||||
fprintf( pFile, ".p %d\n", 64*nWords );
|
||||
for ( i = 0; i < 64*nWords; i++ ) {
|
||||
for ( k = 0; k < nDivs; k++ )
|
||||
fprintf( pFile, "%d", Abc_TtGetBit(Vec_WrdEntryP(vDivs, k*nWords), i) );
|
||||
// fprintf( pFile, " %d\n", Abc_TtGetBit(Vec_WrdEntryP(vIsfs, 1*nWords), i) );
|
||||
if ( Abc_TtGetBit(Vec_WrdEntryP(vIsfs, 0*nWords), i) )
|
||||
fprintf( pFile, " 0\n" );
|
||||
else if ( Abc_TtGetBit(Vec_WrdEntryP(vIsfs, 1*nWords), i) )
|
||||
fprintf( pFile, " 1\n" );
|
||||
else
|
||||
fprintf( pFile, " -\n" );
|
||||
}
|
||||
fprintf( pFile, ".e\n" );
|
||||
|
||||
fprintf( pFile, "\n.s" );
|
||||
Vec_IntForEachEntryStart( vSupp, Temp, i, 2 )
|
||||
fprintf( pFile, " %d", Temp );
|
||||
fprintf( pFile, "\n.a" );
|
||||
Vec_IntForEachEntry( vRes, Temp, i )
|
||||
fprintf( pFile, " %d", Temp );
|
||||
fprintf( pFile, "\n" );
|
||||
fclose ( pFile );
|
||||
RetValue = 0;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -810,6 +904,7 @@ Vec_Int_t * Supp_ManFindBestSolution( Supp_Man_t * p, Vec_Wec_t * vSols, int fVe
|
|||
}
|
||||
if ( iSolBest > 0 && (CostBest >> 2) < 50 )
|
||||
{
|
||||
Vec_Int_t * vDivs2 = Vec_IntAlloc( 100 );
|
||||
Vec_Int_t * vSet = Hsh_VecReadEntry( p->pHash, iSolBest ); int i, iObj;
|
||||
vRes = Gia_ManDeriveSolutionOne( p->pGia, p->vSims, p->vIsfs, p->vCands, vSet, p->nWords, CostBest & 3 );
|
||||
assert( !vRes || Vec_IntSize(vRes) == 2*(CostBest >> 2)+1 );
|
||||
|
|
@ -817,13 +912,18 @@ Vec_Int_t * Supp_ManFindBestSolution( Supp_Man_t * p, Vec_Wec_t * vSols, int fVe
|
|||
{
|
||||
Vec_IntClear( *pvDivs );
|
||||
Vec_IntPushTwo( *pvDivs, -1, -1 );
|
||||
Vec_IntForEachEntry( vSet, iObj, i )
|
||||
Vec_IntPushTwo( vDivs2, -1, -1 );
|
||||
Vec_IntForEachEntry( vSet, iObj, i ) {
|
||||
Vec_IntPush( *pvDivs, Vec_IntEntry(p->vCands, iObj) );
|
||||
Vec_IntPush( vDivs2, iObj );
|
||||
}
|
||||
}
|
||||
//Supp_DeriveDumpProbC( p->vIsfs, p->vDivsC, p->nWords );
|
||||
//Supp_DeriveDumpProb( p->vIsfs, p->vDivs[1], p->nWords );
|
||||
//Supp_DeriveDumpSol( vSet, vRes, Vec_WrdSize(p->vDivs[1])/p->nWords );
|
||||
//s_Counter++;
|
||||
//Supp_DeriveDumpProb2( p->vIsfs, p->vDivs[1], p->nWords, vDivs2, vRes );
|
||||
Vec_IntFree( vDivs2 );
|
||||
s_Counter++;
|
||||
}
|
||||
return vRes;
|
||||
}
|
||||
|
|
@ -870,7 +970,11 @@ Vec_Int_t * Supp_ManCompute( Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t *
|
|||
int i, r, iSet, iBest = -1;
|
||||
abctime clk = Abc_Clock();
|
||||
Vec_Int_t * vRes = NULL;
|
||||
Supp_Man_t * p = Supp_ManCreate( vIsfs, vCands, vWeights, vSims, vSimsC, nWords, pGia, nIters, nRounds );
|
||||
Supp_Man_t * p;
|
||||
if ( vCands )
|
||||
p = Supp_ManCreate( vIsfs, vCands, vWeights, vSims, vSimsC, nWords, pGia, nIters, nRounds );
|
||||
else
|
||||
p = Supp_ManCreate2( vIsfs, vSims, NULL, nWords, nIters, nRounds );
|
||||
if ( Supp_SetFuncNum(p, 0) == 0 )
|
||||
{
|
||||
Supp_ManDelete( p );
|
||||
|
|
@ -881,7 +985,7 @@ Vec_Int_t * Supp_ManCompute( Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t *
|
|||
return vRes;
|
||||
}
|
||||
if ( fVerbose )
|
||||
printf( "\nUsing %d divisors with %d words. Problem has %d functions and %d minterm pairs.\n",
|
||||
printf( "Using %d divisors with %d words. Problem has %d functions and %d minterm pairs.\n",
|
||||
Vec_IntSize(p->vCands), p->nWords, Supp_SetFuncNum(p, 0), Supp_SetPairNum(p, 0) );
|
||||
//iBest = Supp_FindGivenOne( p );
|
||||
if ( iBest == -1 )
|
||||
|
|
@ -962,6 +1066,85 @@ void Supp_ManComputeTest( Gia_Man_t * p )
|
|||
Vec_IntFree( vRes );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Supp_RecordSolution( char * pFileName, Vec_Int_t * vDivs, Vec_Int_t * vRes )
|
||||
{
|
||||
FILE * pFile = fopen( pFileName, "ab" );
|
||||
if ( pFile == NULL ) {
|
||||
printf( "Cannot open file \"%s\" for writing.\n", pFileName );
|
||||
return;
|
||||
}
|
||||
int i, Temp;
|
||||
fprintf( pFile, "\n.s" );
|
||||
Vec_IntForEachEntryStart( vDivs, Temp, i, 2 )
|
||||
fprintf( pFile, " %d", Temp );
|
||||
fprintf( pFile, "\n.a" );
|
||||
Vec_IntForEachEntry( vRes, Temp, i )
|
||||
fprintf( pFile, " %d", Temp-2 );
|
||||
fprintf( pFile, "\n" );
|
||||
fclose( pFile );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Gia_Man_t * Supp_GenerateGia( Vec_Int_t * vRes, Vec_Int_t * vDivs )
|
||||
{
|
||||
int i, nAddOn = 2, nIns = Vec_IntSize(vDivs)-2;
|
||||
int iLit0, iLit1, iTopLit = Vec_IntEntryLast(vRes);
|
||||
assert( Vec_IntSize(vRes) > 0 );
|
||||
assert( Vec_IntSize(vRes) % 2 == 1 );
|
||||
Gia_Man_t * pNew = Gia_ManStart( 100 );
|
||||
pNew->pName = Abc_UtilStrsav( "resub" );
|
||||
for ( i = 0; i < nIns; i++ )
|
||||
Gia_ManAppendCi(pNew);
|
||||
Vec_IntForEachEntryDouble( vRes, iLit0, iLit1, i ) {
|
||||
if ( iLit0 < iLit1 )
|
||||
Gia_ManAppendAnd( pNew, iLit0-nAddOn, iLit1-nAddOn );
|
||||
else if ( iLit0 > iLit1 )
|
||||
Gia_ManAppendXor( pNew, iLit0-nAddOn, iLit1-nAddOn );
|
||||
else assert( 0 );
|
||||
}
|
||||
Gia_ManAppendCo(pNew, iTopLit-nAddOn);
|
||||
return pNew;
|
||||
}
|
||||
Gia_Man_t * Supp_ManSolveOne( char * pFileName, int nIters, int nRounds, int fWriteSol, int fVerbose )
|
||||
{
|
||||
//Abc_Random(1);
|
||||
Abc_RData_t * p = Abc_ReadPla( pFileName );
|
||||
if ( p == NULL ) return NULL;
|
||||
assert( p->nOuts == 1 );
|
||||
Vec_Int_t * vDivs = Vec_IntAlloc( 100 );
|
||||
Vec_Int_t * vRes = Supp_ManCompute( p->vSimsOut, NULL, NULL, p->vSimsIn, NULL, p->nSimWords, NULL, &vDivs, nIters, nRounds, fVerbose );
|
||||
if ( fVerbose && vDivs ) printf( "Divisors: " ), Vec_IntPrint( vDivs );
|
||||
if ( fVerbose && vRes ) printf( "Solution: " ), Vec_IntPrint( vRes );
|
||||
Gia_Man_t * pNew = vRes ? Supp_GenerateGia( vRes, vDivs ) : NULL;
|
||||
if ( fWriteSol && vDivs && vRes )
|
||||
Supp_RecordSolution( pFileName, vDivs, vRes );
|
||||
Vec_IntFreeP( &vRes );
|
||||
Vec_IntFreeP( &vDivs );
|
||||
Abc_RDataStop( p );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -681,6 +681,33 @@ Vec_Int_t * Gia_ManComputeSwitchProbs( Gia_Man_t * pGia, int nFrames, int nPref,
|
|||
// perform the computation of switching activity
|
||||
return Gia_ManSwiSimulate( pGia, pPars );
|
||||
}
|
||||
Vec_Int_t * Gia_ManComputeSwitchProbs2( Gia_Man_t * pGia, int nFrames, int nPref, int fProbOne, int nRandPiFactor )
|
||||
{
|
||||
Gia_ParSwi_t Pars, * pPars = &Pars;
|
||||
// set the default parameters
|
||||
Gia_ManSetDefaultParamsSwi( pPars );
|
||||
pPars->nRandPiFactor = nRandPiFactor;
|
||||
// override some of the defaults
|
||||
pPars->nIters = nFrames; // set number of total timeframes
|
||||
if ( Abc_FrameReadFlag("seqsimframes") )
|
||||
pPars->nIters = atoi( Abc_FrameReadFlag("seqsimframes") );
|
||||
pPars->nPref = nPref; // set number of first timeframes to skip
|
||||
// decide what should be computed
|
||||
if ( fProbOne )
|
||||
{
|
||||
// if the user asked to compute propability of 1, we do not need transition information
|
||||
pPars->fProbOne = 1; // enable computing probabiblity of being one
|
||||
pPars->fProbTrans = 0; // disable computing transition probability
|
||||
}
|
||||
else
|
||||
{
|
||||
// if the user asked for transition propabability, we do not need to compute probability of 1
|
||||
pPars->fProbOne = 0; // disable computing probabiblity of being one
|
||||
pPars->fProbTrans = 1; // enable computing transition probability
|
||||
}
|
||||
// perform the computation of switching activity
|
||||
return Gia_ManSwiSimulate( pGia, pPars );
|
||||
}
|
||||
Vec_Int_t * Saig_ManComputeSwitchProbs( Aig_Man_t * pAig, int nFrames, int nPref, int fProbOne )
|
||||
{
|
||||
Vec_Int_t * vSwitching, * vResult;
|
||||
|
|
|
|||
|
|
@ -423,6 +423,10 @@ Gia_Man_t * Gia_ManTranStoch( Gia_Man_t * pGia, int nRestarts, int nHops, int nS
|
|||
if ( nVerbose )
|
||||
printf( "best: %d\n", Gia_ManAndNum( pBest ) );
|
||||
Vec_PtrFree( vpStarts );
|
||||
ABC_FREE( pBest->pName );
|
||||
ABC_FREE( pBest->pSpec );
|
||||
pBest->pName = Abc_UtilStrsav( pGia->pName );
|
||||
pBest->pSpec = Abc_UtilStrsav( pGia->pSpec );
|
||||
return pBest;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,8 +48,13 @@ ABC_NAMESPACE_IMPL_START
|
|||
***********************************************************************/
|
||||
unsigned Gia_ManRandom( int fReset )
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
static unsigned int m_z = NUMBER1;
|
||||
static unsigned int m_w = NUMBER2;
|
||||
#else
|
||||
static __thread unsigned int m_z = NUMBER1;
|
||||
static __thread unsigned int m_w = NUMBER2;
|
||||
#endif
|
||||
if ( fReset )
|
||||
{
|
||||
m_z = NUMBER1;
|
||||
|
|
@ -3274,6 +3279,194 @@ void Gia_ManTestProblem()
|
|||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Gia_GenDecoder( Gia_Man_t * p, int * pLits, int nLits )
|
||||
{
|
||||
if ( nLits == 1 )
|
||||
{
|
||||
Vec_Int_t * vRes = Vec_IntAlloc( 2 );
|
||||
Vec_IntPush( vRes, Abc_LitNot(pLits[0]) );
|
||||
Vec_IntPush( vRes, pLits[0] );
|
||||
return vRes;
|
||||
}
|
||||
assert( nLits > 1 );
|
||||
int nPart1 = nLits / 2;
|
||||
int nPart2 = nLits - nPart1;
|
||||
Vec_Int_t * vRes1 = Gia_GenDecoder( p, pLits, nPart1 );
|
||||
Vec_Int_t * vRes2 = Gia_GenDecoder( p, pLits+nPart1, nPart2 );
|
||||
Vec_Int_t * vRes = Vec_IntAlloc( Vec_IntSize(vRes1) * Vec_IntSize(vRes2) );
|
||||
int i, k, Lit1, Lit2;
|
||||
Vec_IntForEachEntry( vRes2, Lit2, k )
|
||||
Vec_IntForEachEntry( vRes1, Lit1, i )
|
||||
Vec_IntPush( vRes, Gia_ManHashAnd(p, Lit1, Lit2) );
|
||||
Vec_IntFree( vRes1 );
|
||||
Vec_IntFree( vRes2 );
|
||||
return vRes;
|
||||
}
|
||||
Gia_Man_t * Gia_ManGenMux( int nIns, char * pNums )
|
||||
{
|
||||
Vec_Int_t * vIns = Vec_IntAlloc( nIns );
|
||||
Vec_Int_t * vData = Vec_IntAlloc( 1 << nIns );
|
||||
Gia_Man_t * p = Gia_ManStart( 4*(1 << nIns) + nIns ), * pTemp;
|
||||
int i, iStart = 0, nSize = 1 << nIns;
|
||||
p->pName = Abc_UtilStrsav( "mux" );
|
||||
for ( i = 0; i < nIns; i++ )
|
||||
Vec_IntPush( vIns, Gia_ManAppendCi(p) );
|
||||
for ( i = 0; i < nSize; i++ )
|
||||
Vec_IntPush( vData, Gia_ManAppendCi(p) );
|
||||
Gia_ManHashAlloc( p );
|
||||
for ( i = (int)strlen(pNums)-1; i >= 0; i-- )
|
||||
{
|
||||
int k, b, nBits = (int)(pNums[i] - '0');
|
||||
Vec_Int_t * vDec = Gia_GenDecoder( p, Vec_IntEntryP(vIns, iStart), nBits );
|
||||
for ( k = 0; k < nSize; k++ )
|
||||
Vec_IntWriteEntry( vData, k, Gia_ManHashAnd(p, Vec_IntEntry(vData, k), Vec_IntEntry(vDec, k%Vec_IntSize(vDec))) );
|
||||
for ( b = 0; b < nBits; b++, nSize /= 2 )
|
||||
for ( k = 0; k < nSize/2; k++ )
|
||||
Vec_IntWriteEntry( vData, k, Gia_ManHashOr(p, Vec_IntEntry(vData, 2*k), Vec_IntEntry(vData, 2*k+1)) );
|
||||
Vec_IntFree( vDec );
|
||||
iStart += nBits;
|
||||
}
|
||||
assert( nSize == 1 );
|
||||
Gia_ManAppendCo( p, Vec_IntEntry(vData, 0) );
|
||||
Vec_IntFree( vIns );
|
||||
Vec_IntFree( vData );
|
||||
p = Gia_ManCleanup( pTemp = p );
|
||||
Gia_ManStop( pTemp );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if this window has a topo error (forward path from an output to an input).]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_ManWindowCheckTopoError_rec( Gia_Man_t * p, Gia_Obj_t * pObj )
|
||||
{
|
||||
if ( !Gia_ObjIsAnd(pObj) )
|
||||
return 0;
|
||||
if ( Gia_ObjIsTravIdPrevious(p, pObj) )
|
||||
return 1; // there is an error
|
||||
if ( Gia_ObjIsTravIdCurrent(p, pObj) )
|
||||
return 0; // there is no error; visited this node before
|
||||
Gia_ObjSetTravIdPrevious(p, pObj);
|
||||
if ( Gia_ManWindowCheckTopoError_rec(p, Gia_ObjFanin0(pObj)) || Gia_ManWindowCheckTopoError_rec(p, Gia_ObjFanin1(pObj)) )
|
||||
return 1;
|
||||
Gia_ObjSetTravIdCurrent(p, pObj);
|
||||
return 0;
|
||||
}
|
||||
int Gia_ManWindowCheckTopoError( Gia_Man_t * p, Vec_Int_t * vIns, Vec_Int_t * vOuts )
|
||||
{
|
||||
Gia_Obj_t * pObj; int i, fError = 0;
|
||||
// outputs should be internal nodes
|
||||
Gia_ManForEachObjVec( vOuts, p, pObj, i )
|
||||
assert(Gia_ObjIsAnd(pObj));
|
||||
// mark outputs
|
||||
Gia_ManIncrementTravId( p );
|
||||
Gia_ManForEachObjVec( vOuts, p, pObj, i )
|
||||
Gia_ObjSetTravIdCurrent(p, pObj);
|
||||
// start from inputs and make sure we do not reach any of the outputs
|
||||
Gia_ManIncrementTravId( p );
|
||||
Gia_ManForEachObjVec( vIns, p, pObj, i )
|
||||
fError |= Gia_ManWindowCheckTopoError_rec(p, pObj);
|
||||
return fError;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Updates the AIG after multiple windows have been optimized.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_ManDupInsertWindows_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vMap, Vec_Ptr_t * vvIns, Vec_Ptr_t * vvOuts, Vec_Ptr_t * vWins )
|
||||
{
|
||||
if ( ~pObj->Value )
|
||||
return pObj->Value;
|
||||
assert( Gia_ObjIsAnd(pObj) );
|
||||
if ( Vec_IntEntry(vMap, Gia_ObjId(p, pObj)) == -1 ) // this is a regular node
|
||||
{
|
||||
Gia_ManDupInsertWindows_rec( pNew, p, Gia_ObjFanin0(pObj), vMap, vvIns, vvOuts, vWins );
|
||||
Gia_ManDupInsertWindows_rec( pNew, p, Gia_ObjFanin1(pObj), vMap, vvIns, vvOuts, vWins );
|
||||
return pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
}
|
||||
// this node is an output of a window
|
||||
int iWin = Vec_IntEntry(vMap, Gia_ObjId(p, pObj));
|
||||
Vec_Int_t * vIns = (Vec_Int_t *)Vec_PtrEntry(vvIns, iWin);
|
||||
Vec_Int_t * vOuts = (Vec_Int_t *)Vec_PtrEntry(vvOuts, iWin);
|
||||
Gia_Man_t * pWin = (Gia_Man_t *)Vec_PtrEntry(vWins, iWin);
|
||||
// build transinvite fanins of window inputs
|
||||
Gia_Obj_t * pNode; int i;
|
||||
Gia_ManConst0(pWin)->Value = 0;
|
||||
Gia_ManForEachObjVec( vIns, p, pNode, i )
|
||||
Gia_ManPi(pWin, i)->Value = Gia_ManDupInsertWindows_rec( pNew, p, pNode, vMap, vvIns, vvOuts, vWins );
|
||||
// add window nodes
|
||||
Gia_ManForEachAnd( pWin, pNode, i )
|
||||
pNode->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pNode), Gia_ObjFanin1Copy(pNode) );
|
||||
// transfer to window outputs
|
||||
Gia_ManForEachObjVec( vOuts, p, pNode, i )
|
||||
pNode->Value = Gia_ObjFanin0Copy(Gia_ManPo(pWin, i));
|
||||
assert( ~pObj->Value );
|
||||
return pObj->Value;
|
||||
}
|
||||
Gia_Man_t * Gia_ManDupInsertWindows( Gia_Man_t * p, Vec_Ptr_t * vvIns, Vec_Ptr_t * vvOuts, Vec_Ptr_t * vWins )
|
||||
{
|
||||
// check consistency of input data
|
||||
Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj; int i, k, iNode;
|
||||
Vec_PtrForEachEntry( Gia_Man_t *, vWins, pTemp, i ) {
|
||||
Vec_Int_t * vIns = (Vec_Int_t *)Vec_PtrEntry(vvIns, i);
|
||||
Vec_Int_t * vOuts = (Vec_Int_t *)Vec_PtrEntry(vvOuts, i);
|
||||
assert( Vec_IntSize(vIns) == Gia_ManPiNum(pTemp) );
|
||||
assert( Vec_IntSize(vOuts) == Gia_ManPoNum(pTemp) );
|
||||
assert( !Gia_ManWindowCheckTopoError(p, vIns, vOuts) );
|
||||
}
|
||||
// create mapping of window outputs into window IDs
|
||||
Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) ), * vOuts;
|
||||
Vec_PtrForEachEntry( Vec_Int_t *, vvOuts, vOuts, i )
|
||||
Vec_IntForEachEntry( vOuts, iNode, k )
|
||||
Vec_IntWriteEntry( vMap, iNode, i );
|
||||
// create the resulting AIG by performing DFS from the POs of the original AIG
|
||||
// it goes recursively through original nodes and windows until it reaches the PIs of the original AIG
|
||||
pNew = Gia_ManStart( Gia_ManObjNum(p) );
|
||||
pNew->pName = Abc_UtilStrsav( p->pName );
|
||||
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
|
||||
Gia_ManHashAlloc( pNew );
|
||||
Gia_ManFillValue( p );
|
||||
Gia_ManConst0(p)->Value = 0;
|
||||
Gia_ManForEachCi( p, pObj, i )
|
||||
pObj->Value = Gia_ManAppendCi(pNew);
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
Gia_ManDupInsertWindows_rec( pNew, p, Gia_ObjFanin0(pObj), vMap, vvIns, vvOuts, vWins );
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
|
||||
// cleanup and return
|
||||
Vec_IntFree( vMap );
|
||||
pNew = Gia_ManCleanup( pTemp = pNew );
|
||||
Gia_ManStop( pTemp );
|
||||
//Gia_ManPrint( pNew );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ SRC += src/aig/gia/giaAig.c \
|
|||
src/aig/gia/giaMini.c \
|
||||
src/aig/gia/giaMinLut.c \
|
||||
src/aig/gia/giaMinLut2.c \
|
||||
src/aig/gia/giaMulFind.c \
|
||||
src/aig/gia/giaMuxes.c \
|
||||
src/aig/gia/giaNf.c \
|
||||
src/aig/gia/giaOf.c \
|
||||
|
|
|
|||
|
|
@ -214,6 +214,7 @@ struct Abc_Ntk_t_
|
|||
Vec_Ptr_t * vAttrs; // managers of various node attributes (node functionality, global BDDs, etc)
|
||||
Vec_Int_t * vNameIds; // name IDs
|
||||
Vec_Int_t * vFins; // obj/type info
|
||||
Vec_Int_t * vOrigNodeIds; // original node IDs
|
||||
};
|
||||
|
||||
struct Abc_Des_t_
|
||||
|
|
@ -677,6 +678,7 @@ extern ABC_DLL void Abc_NtkLogicMakeDirectSops( Abc_Ntk_t * pNtk )
|
|||
extern ABC_DLL int Abc_NtkSopToAig( Abc_Ntk_t * pNtk );
|
||||
extern ABC_DLL int Abc_NtkAigToBdd( Abc_Ntk_t * pNtk );
|
||||
extern ABC_DLL Gia_Man_t * Abc_NtkAigToGia( Abc_Ntk_t * p, int fGiaSimple );
|
||||
extern ABC_DLL int Abc_NtkMapToSopUsingLibrary( Abc_Ntk_t * pNtk, void* library );
|
||||
extern ABC_DLL int Abc_NtkMapToSop( Abc_Ntk_t * pNtk );
|
||||
extern ABC_DLL int Abc_NtkToSop( Abc_Ntk_t * pNtk, int fMode, int nCubeLimit );
|
||||
extern ABC_DLL int Abc_NtkToBdd( Abc_Ntk_t * pNtk );
|
||||
|
|
|
|||
|
|
@ -33,7 +33,8 @@ ABC_NAMESPACE_IMPL_START
|
|||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define ABC_MAX_CUBES 100000
|
||||
#define ABC_MAX_CUBES 1000000
|
||||
#define ABC_MAX_CUBES2 10000
|
||||
|
||||
static Hop_Obj_t * Abc_ConvertSopToAig( Hop_Man_t * pMan, char * pSop );
|
||||
|
||||
|
|
@ -42,11 +43,63 @@ static Hop_Obj_t * Abc_ConvertSopToAig( Hop_Man_t * pMan, char * pSop );
|
|||
int Abc_ConvertZddToSop( DdManager * dd, DdNode * zCover, char * pSop, int nFanins, Vec_Str_t * vCube, int fPhase );
|
||||
static DdNode * Abc_ConvertAigToBdd( DdManager * dd, Hop_Obj_t * pRoot);
|
||||
extern int Abc_CountZddCubes( DdManager * dd, DdNode * zCover );
|
||||
extern void Abc_NtkSortCubes( Abc_Ntk_t * pNtk, int fWeight );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Converts the node from SOP to BDD representation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_ConvertSopToBdd2Count( char * pSop, int nCubes, int nStep, int iVar, int pRes[3] )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < nCubes; i++ )
|
||||
if ( pSop[i*nStep+iVar] == '-' )
|
||||
pRes[0]++, assert( pRes[1] == 0 && pRes[2] == 0 );
|
||||
else if ( pSop[i*nStep+iVar] == '0' )
|
||||
pRes[1]++, assert( pRes[2] == 0 );
|
||||
else if ( pSop[i*nStep+iVar] == '1' )
|
||||
pRes[2]++;
|
||||
else assert( 0 );
|
||||
}
|
||||
DdNode * Abc_ConvertSopToBdd2_rec( DdManager * dd, char * pSop, DdNode ** pbVars, int nCubes, int nStep, int iVar )
|
||||
{
|
||||
DdNode * bRes[5] = {NULL};
|
||||
int pRes[3] = {0}, i, Start = 0;
|
||||
if ( nCubes == 0 )
|
||||
return Cudd_ReadLogicZero(dd);
|
||||
if ( iVar == nStep - 3 )
|
||||
return Cudd_ReadOne(dd);
|
||||
Abc_ConvertSopToBdd2Count( pSop, nCubes, nStep, iVar, pRes );
|
||||
for ( i = 0; i < 3; Start += pRes[i++] )
|
||||
bRes[i] = Abc_ConvertSopToBdd2_rec( dd, pSop + Start*nStep, pbVars, pRes[i], nStep, iVar+1 ), Cudd_Ref( bRes[i] );
|
||||
bRes[3] = Cudd_bddIte( dd, pbVars[iVar], bRes[2], bRes[1] ); Cudd_Ref( bRes[3] );
|
||||
Cudd_RecursiveDeref( dd, bRes[1] );
|
||||
Cudd_RecursiveDeref( dd, bRes[2] );
|
||||
bRes[4] = Cudd_bddOr( dd, bRes[0], bRes[3] ); Cudd_Ref( bRes[4] );
|
||||
Cudd_RecursiveDeref( dd, bRes[3] );
|
||||
Cudd_RecursiveDeref( dd, bRes[0] );
|
||||
Cudd_Deref( bRes[4] );
|
||||
return bRes[4];
|
||||
}
|
||||
DdNode * Abc_ConvertSopToBdd2( DdManager * dd, char * pSop, DdNode ** pbVars )
|
||||
{
|
||||
int nCubes = Abc_SopGetCubeNum(pSop);
|
||||
int nStep = Abc_SopGetVarNum(pSop) + 3;
|
||||
assert( pSop[nCubes*nStep] == '\0' );
|
||||
return Abc_ConvertSopToBdd2_rec( dd, pSop, pbVars, nCubes, nStep, 0 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Converts the node from SOP to BDD representation.]
|
||||
|
|
@ -74,6 +127,21 @@ DdNode * Abc_ConvertSopToBdd( DdManager * dd, char * pSop, DdNode ** pbVars )
|
|||
bSum = Cudd_bddXor( dd, bTemp = bSum, pbVars? pbVars[v] : Cudd_bddIthVar(dd, v) ); Cudd_Ref( bSum );
|
||||
Cudd_RecursiveDeref( dd, bTemp );
|
||||
}
|
||||
}
|
||||
else if ( Abc_SopGetCubeNum(pSop) > ABC_MAX_CUBES2 )
|
||||
{
|
||||
Cudd_Deref( bSum );
|
||||
if ( pbVars )
|
||||
bSum = Abc_ConvertSopToBdd2( dd, pSop, pbVars );
|
||||
else
|
||||
{
|
||||
DdNode ** pbVars = ABC_ALLOC( DdNode *, nVars );
|
||||
for ( v = 0; v < nVars; v++ )
|
||||
pbVars[v] = Cudd_bddIthVar( dd, v );
|
||||
bSum = Abc_ConvertSopToBdd2( dd, pSop, pbVars );
|
||||
ABC_FREE( pbVars );
|
||||
}
|
||||
Cudd_Ref( bSum );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -120,10 +188,16 @@ int Abc_NtkSopToBdd( Abc_Ntk_t * pNtk )
|
|||
Abc_Obj_t * pNode;
|
||||
DdManager * dd, * ddTemp = NULL;
|
||||
Vec_Int_t * vFanins = NULL;
|
||||
int nFaninsMax, i, k, iVar;
|
||||
int nFaninsMax, i, k, iVar, nCubesMax = 0;
|
||||
|
||||
assert( Abc_NtkHasSop(pNtk) );
|
||||
|
||||
// check SOP sizes
|
||||
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||
nCubesMax = Abc_MaxInt( nCubesMax, Abc_SopGetCubeNum((char *)pNode->pData) );
|
||||
if ( nCubesMax > ABC_MAX_CUBES2 )
|
||||
Abc_NtkSortCubes( pNtk, 0 );
|
||||
|
||||
// start the functionality manager
|
||||
nFaninsMax = Abc_NtkGetFaninMax( pNtk );
|
||||
if ( nFaninsMax == 0 )
|
||||
|
|
@ -1108,7 +1182,7 @@ Abc_Obj_t * Abc_ConvertAigToAig( Abc_Ntk_t * pNtkAig, Abc_Obj_t * pObjOld )
|
|||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Unmaps the network.]
|
||||
Synopsis [Unmaps the network with user provided Mio library.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -1117,16 +1191,15 @@ Abc_Obj_t * Abc_ConvertAigToAig( Abc_Ntk_t * pNtkAig, Abc_Obj_t * pObjOld )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkMapToSop( Abc_Ntk_t * pNtk )
|
||||
int Abc_NtkMapToSopUsingLibrary( Abc_Ntk_t * pNtk, void* library)
|
||||
{
|
||||
extern void * Abc_FrameReadLibGen();
|
||||
Abc_Obj_t * pNode;
|
||||
char * pSop;
|
||||
int i;
|
||||
|
||||
assert( Abc_NtkHasMapping(pNtk) );
|
||||
// update the functionality manager
|
||||
assert( pNtk->pManFunc == Abc_FrameReadLibGen() );
|
||||
assert( pNtk->pManFunc == (void*) library );
|
||||
pNtk->pManFunc = Mem_FlexStart();
|
||||
// update the nodes
|
||||
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||
|
|
@ -1141,6 +1214,23 @@ int Abc_NtkMapToSop( Abc_Ntk_t * pNtk )
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Unmaps the network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkMapToSop( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
extern void * Abc_FrameReadLibGen();
|
||||
return Abc_NtkMapToSopUsingLibrary(pNtk, Abc_FrameReadLibGen());
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Converts SOP functions into BLIF-MV functions.]
|
||||
|
|
|
|||
|
|
@ -461,6 +461,15 @@ Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk )
|
|||
if ( !Abc_ObjIsBox(pObj) && !Abc_ObjIsBo(pObj) )
|
||||
Abc_ObjForEachFanin( pObj, pFanin, k )
|
||||
Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
|
||||
// move object IDs
|
||||
if ( pNtk->vOrigNodeIds )
|
||||
{
|
||||
pNtkNew->vOrigNodeIds = Vec_IntStartFull( Abc_NtkObjNumMax(pNtkNew) );
|
||||
Abc_NtkForEachObj( pNtk, pObj, i )
|
||||
if ( pObj->pCopy && Vec_IntEntry(pNtk->vOrigNodeIds, pObj->Id) > 0 )
|
||||
Vec_IntWriteEntry( pNtkNew->vOrigNodeIds, pObj->pCopy->Id, Vec_IntEntry(pNtk->vOrigNodeIds, pObj->Id) );
|
||||
}
|
||||
|
||||
}
|
||||
// duplicate the EXDC Ntk
|
||||
if ( pNtk->pExdc )
|
||||
|
|
@ -1483,6 +1492,7 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk )
|
|||
Vec_IntFreeP( &pNtk->vObjPerm );
|
||||
Vec_IntFreeP( &pNtk->vTopo );
|
||||
Vec_IntFreeP( &pNtk->vFins );
|
||||
Vec_IntFreeP( &pNtk->vOrigNodeIds );
|
||||
ABC_FREE( pNtk );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -241,7 +241,7 @@ void Abc_NodeShowCut( Abc_Obj_t * pNode, int nNodeSizeMax, int nConeSizeMax )
|
|||
// add the root node to the cone (for visualization)
|
||||
Vec_PtrPush( vCutSmall, pNode );
|
||||
// write the DOT file
|
||||
Io_WriteDotNtk( pNode->pNtk, vInside, vCutSmall, FileNameDot, 0, 0 );
|
||||
Io_WriteDotNtk( pNode->pNtk, vInside, vCutSmall, FileNameDot, 0, 0, 0 );
|
||||
// stop the cut computation manager
|
||||
Abc_NtkManCutStop( p );
|
||||
|
||||
|
|
@ -260,7 +260,7 @@ void Abc_NodeShowCut( Abc_Obj_t * pNode, int nNodeSizeMax, int nConeSizeMax )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkShow( Abc_Ntk_t * pNtk0, int fGateNames, int fSeq, int fUseReverse, int fKeepDot )
|
||||
void Abc_NtkShow( Abc_Ntk_t * pNtk0, int fGateNames, int fSeq, int fUseReverse, int fKeepDot, int fAigIds )
|
||||
{
|
||||
FILE * pFile;
|
||||
Abc_Ntk_t * pNtk;
|
||||
|
|
@ -302,7 +302,7 @@ void Abc_NtkShow( Abc_Ntk_t * pNtk0, int fGateNames, int fSeq, int fUseReverse,
|
|||
if ( fSeq )
|
||||
Io_WriteDotSeq( pNtk, vNodes, NULL, FileNameDot, fGateNames, fUseReverse );
|
||||
else
|
||||
Io_WriteDotNtk( pNtk, vNodes, NULL, FileNameDot, fGateNames, fUseReverse );
|
||||
Io_WriteDotNtk( pNtk, vNodes, NULL, FileNameDot, fGateNames, fUseReverse, fAigIds );
|
||||
pNtk->nBarBufs = nBarBufs;
|
||||
Vec_PtrFree( vNodes );
|
||||
|
||||
|
|
|
|||
1680
src/base/abci/abc.c
1680
src/base/abci/abc.c
File diff suppressed because it is too large
Load Diff
|
|
@ -19,9 +19,12 @@
|
|||
***********************************************************************/
|
||||
|
||||
#include "base/abc/abc.h"
|
||||
#include "bool/kit/kit.h"
|
||||
#include "aig/miniaig/miniaig.h"
|
||||
|
||||
#ifdef ABC_USE_CUDD
|
||||
#include "bdd/extrab/extraBdd.h"
|
||||
#include "bdd/extrab/extraLutCas.h"
|
||||
#endif
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
|
@ -116,9 +119,153 @@ Abc_Ntk_t * Abc_NtkCascade( Abc_Ntk_t * pNtk, int nLutSize, int fCheck, int fVer
|
|||
#else
|
||||
|
||||
Abc_Ntk_t * Abc_NtkCascade( Abc_Ntk_t * pNtk, int nLutSize, int fCheck, int fVerbose ) { return NULL; }
|
||||
word * Abc_LutCascade( Mini_Aig_t * p, int nLutSize, int fVerbose ) { return NULL; }
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
The decomposed structure of the LUT cascade is represented as an array of 64-bit integers (words).
|
||||
The first word in the record is the number of LUT info blocks in the record, which follow one by one.
|
||||
Each LUT info block contains the following:
|
||||
- the number of words in this block
|
||||
- the number of fanins
|
||||
- the list of fanins
|
||||
- the variable ID of the output (can be one of the fanin variables)
|
||||
- truth tables (one word for 6 vars or less; more words as needed for more than 6 vars)
|
||||
For a 6-input node, the LUT info block takes 10 words (block size, fanin count, 6 fanins, output ID, truth table).
|
||||
For a 4-input node, the LUT info block takes 8 words (block size, fanin count, 4 fanins, output ID, truth table).
|
||||
If the LUT cascade contains a 6-LUT followed by a 4-LUT, the record contains 1+10+8=19 words.
|
||||
*/
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
word * Abc_LutCascadeGenTest()
|
||||
{
|
||||
word * pLuts = ABC_CALLOC( word, 20 ); int i;
|
||||
// node count
|
||||
pLuts[0] = 2;
|
||||
// first node
|
||||
pLuts[1+0] = 10;
|
||||
pLuts[1+1] = 6;
|
||||
for ( i = 0; i < 6; i++ )
|
||||
pLuts[1+2+i] = i;
|
||||
pLuts[1+8] = 0;
|
||||
pLuts[1+9] = ABC_CONST(0x8000000000000000);
|
||||
// second node
|
||||
pLuts[11+0] = 8;
|
||||
pLuts[11+1] = 4;
|
||||
for ( i = 0; i < 4; i++ )
|
||||
pLuts[11+2+i] = i ? i + 5 : 0;
|
||||
pLuts[11+6] = 1;
|
||||
pLuts[11+7] = ABC_CONST(0xFFFEFFFEFFFEFFFE);
|
||||
return pLuts;
|
||||
}
|
||||
void Abc_LutCascadePrint( word * pLuts )
|
||||
{
|
||||
int n, i, k;
|
||||
printf( "Single-rail LUT cascade has %d nodes:\n", (int)pLuts[0] );
|
||||
for ( n = 0, i = 1; n < pLuts[0]; n++, i += pLuts[i] )
|
||||
{
|
||||
word nIns = pLuts[i+1];
|
||||
word * pIns = pLuts+i+2;
|
||||
word * pT = pLuts+i+2+nIns+1;
|
||||
printf( "LUT%d : ", n );
|
||||
printf( "%02d = F( ", (int)pIns[nIns] );
|
||||
for ( k = 0; k < nIns; k++ )
|
||||
printf( "%02d ", (int)pIns[k] );
|
||||
for ( ; k < 8; k++ )
|
||||
printf( " " );
|
||||
printf( ") " );
|
||||
Extra_PrintHex2( stdout, (unsigned *)pT, nIns );
|
||||
printf( "\n" );
|
||||
}
|
||||
}
|
||||
word * Abc_LutCascadeTest( Mini_Aig_t * p, int nLutSize, int fVerbose )
|
||||
{
|
||||
word * pLuts = Abc_LutCascadeGenTest();
|
||||
Abc_LutCascadePrint( pLuts );
|
||||
return pLuts;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Obj_t * Abc_NtkLutCascadeDeriveSop( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeNew, word * pT, int nIns, Vec_Int_t * vCover )
|
||||
{
|
||||
int RetValue = Kit_TruthIsop( (unsigned *)pT, nIns, vCover, 1 );
|
||||
assert( RetValue == 0 || RetValue == 1 );
|
||||
if ( Vec_IntSize(vCover) == 0 || (Vec_IntSize(vCover) == 1 && Vec_IntEntry(vCover,0) == 0) ) {
|
||||
assert( RetValue == 0 );
|
||||
pNodeNew->pData = Abc_SopCreateAnd( (Mem_Flex_t *)pNtkNew->pManFunc, nIns, NULL );
|
||||
return (Vec_IntSize(vCover) == 0) ? Abc_NtkCreateNodeConst0(pNtkNew) : Abc_NtkCreateNodeConst1(pNtkNew);
|
||||
}
|
||||
else {
|
||||
char * pSop = Abc_SopCreateFromIsop( (Mem_Flex_t *)pNtkNew->pManFunc, nIns, vCover );
|
||||
if ( RetValue ) Abc_SopComplement( (char *)pSop );
|
||||
pNodeNew->pData = pSop;
|
||||
return pNodeNew;
|
||||
}
|
||||
}
|
||||
Abc_Ntk_t * Abc_NtkLutCascadeFromLuts( word * pLuts, Abc_Ntk_t * pNtk, int nLutSize, int fVerbose )
|
||||
{
|
||||
Abc_Ntk_t * pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
|
||||
Vec_Int_t * vCover = Vec_IntAlloc( 1000 ); word n, i, k, iLastLut = -1;
|
||||
assert( Abc_NtkCoNum(pNtk) == 1 );
|
||||
for ( n = 0, i = 1; n < pLuts[0]; n++, i += pLuts[i] )
|
||||
{
|
||||
word nIns = pLuts[i+1];
|
||||
word * pIns = pLuts+i+2;
|
||||
word * pT = pLuts+i+2+nIns+1;
|
||||
Abc_Obj_t * pNodeNew = Abc_NtkCreateNode( pNtkNew );
|
||||
for ( k = 0; k < nIns; k++ )
|
||||
Abc_ObjAddFanin( pNodeNew, Abc_NtkCi(pNtk, pIns[k])->pCopy );
|
||||
Abc_NtkCi(pNtk, pIns[nIns])->pCopy = Abc_NtkLutCascadeDeriveSop( pNtkNew, pNodeNew, pT, nIns, vCover );
|
||||
iLastLut = pIns[nIns];
|
||||
}
|
||||
Vec_IntFree( vCover );
|
||||
Abc_ObjAddFanin( Abc_NtkCo(pNtk, 0)->pCopy, Abc_NtkCi(pNtk, iLastLut)->pCopy );
|
||||
if ( !Abc_NtkCheck( pNtkNew ) )
|
||||
{
|
||||
printf( "Abc_NtkLutCascadeFromLuts: The network check has failed.\n" );
|
||||
Abc_NtkDelete( pNtkNew );
|
||||
return NULL;
|
||||
}
|
||||
return pNtkNew;
|
||||
}
|
||||
Abc_Ntk_t * Abc_NtkLutCascade( Abc_Ntk_t * pNtk, int nLutSize, int fVerbose )
|
||||
{
|
||||
extern Gia_Man_t * Abc_NtkStrashToGia( Abc_Ntk_t * pNtk );
|
||||
extern Mini_Aig_t * Gia_ManToMiniAig( Gia_Man_t * pGia );
|
||||
extern word * Abc_LutCascade( Mini_Aig_t * p, int nLutSize, int fVerbose );
|
||||
Gia_Man_t * pGia = Abc_NtkStrashToGia( pNtk );
|
||||
Mini_Aig_t * pM = Gia_ManToMiniAig( pGia );
|
||||
word * pLuts = Abc_LutCascade( pM, nLutSize, fVerbose );
|
||||
Abc_Ntk_t * pNew = pLuts ? Abc_NtkLutCascadeFromLuts( pLuts, pNtk, nLutSize, fVerbose ) : NULL;
|
||||
ABC_FREE( pLuts );
|
||||
Mini_AigStop( pM );
|
||||
Gia_ManStop( pGia );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ Abc_Ntk_t * Abc_NtkDsdInternal( Abc_Ntk_t * pNtk, int fVerbose, int fPrint, int
|
|||
ppNamesCi = Abc_NtkCollectCioNames( pNtk, 0 );
|
||||
ppNamesCo = Abc_NtkCollectCioNames( pNtk, 1 );
|
||||
if ( fVerbose )
|
||||
Dsd_TreePrint( stdout, pManDsd, ppNamesCi, ppNamesCo, fShort, -1 );
|
||||
Dsd_TreePrint( stdout, pManDsd, ppNamesCi, ppNamesCo, fShort, -1, 0 );
|
||||
else
|
||||
Dsd_TreePrint2( stdout, pManDsd, ppNamesCi, ppNamesCo, -1 );
|
||||
ABC_FREE( ppNamesCi );
|
||||
|
|
|
|||
|
|
@ -42,6 +42,32 @@ ABC_NAMESPACE_IMPL_START
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_WriteHalfAdder( FILE * pFile )
|
||||
{
|
||||
int fNaive = 0;
|
||||
fprintf( pFile, ".model HA\n" );
|
||||
fprintf( pFile, ".inputs a b\n" );
|
||||
fprintf( pFile, ".outputs s cout\n" );
|
||||
if ( fNaive )
|
||||
{
|
||||
fprintf( pFile, ".names a b s\n" );
|
||||
fprintf( pFile, "10 1\n" );
|
||||
fprintf( pFile, "01 1\n" );
|
||||
fprintf( pFile, ".names a b cout\n" );
|
||||
fprintf( pFile, "11 1\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( pFile, ".names a b cout\n" );
|
||||
fprintf( pFile, "11 1\n" );
|
||||
fprintf( pFile, ".names a b and1_\n" );
|
||||
fprintf( pFile, "00 1\n" );
|
||||
fprintf( pFile, ".names cout and1_ s\n" );
|
||||
fprintf( pFile, "00 1\n" );
|
||||
}
|
||||
fprintf( pFile, ".end\n" );
|
||||
fprintf( pFile, "\n" );
|
||||
}
|
||||
void Abc_WriteFullAdder( FILE * pFile )
|
||||
{
|
||||
int fNaive = 0;
|
||||
|
|
@ -50,6 +76,7 @@ void Abc_WriteFullAdder( FILE * pFile )
|
|||
fprintf( pFile, ".outputs s cout\n" );
|
||||
if ( fNaive )
|
||||
{
|
||||
/*
|
||||
fprintf( pFile, ".names a b k\n" );
|
||||
fprintf( pFile, "10 1\n" );
|
||||
fprintf( pFile, "01 1\n" );
|
||||
|
|
@ -60,6 +87,19 @@ void Abc_WriteFullAdder( FILE * pFile )
|
|||
fprintf( pFile, "11- 1\n" );
|
||||
fprintf( pFile, "1-1 1\n" );
|
||||
fprintf( pFile, "-11 1\n" );
|
||||
*/
|
||||
fprintf( pFile, ".names a b s0\n" );
|
||||
fprintf( pFile, "10 1\n" );
|
||||
fprintf( pFile, "01 1\n" );
|
||||
fprintf( pFile, ".names a b c0\n" );
|
||||
fprintf( pFile, "11 1\n" );
|
||||
fprintf( pFile, ".names s0 cin s\n" );
|
||||
fprintf( pFile, "10 1\n" );
|
||||
fprintf( pFile, "01 1\n" );
|
||||
fprintf( pFile, ".names s0 cin c1\n" );
|
||||
fprintf( pFile, "11 1\n" );
|
||||
fprintf( pFile, ".names c0 c1 cout\n" );
|
||||
fprintf( pFile, "00 0\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1205,6 +1245,679 @@ void Abc_GenGraph( char * pFileName, int nPis )
|
|||
ABC_FREE( pTruth );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Threshold function generation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_GenComp63a4( FILE * pFile )
|
||||
{
|
||||
fprintf( pFile, ".model C63a\n" );
|
||||
fprintf( pFile, ".inputs x0 x1 x2 x3 x4 x5\n" );
|
||||
fprintf( pFile, ".outputs z0 z1 z2\n" );
|
||||
fprintf( pFile, ".names x1 x2 x3 x0 n10\n" );
|
||||
fprintf( pFile, "--00 1\n" );
|
||||
fprintf( pFile, "-0-0 1\n" );
|
||||
fprintf( pFile, "0--0 1\n" );
|
||||
fprintf( pFile, "000- 1\n" );
|
||||
fprintf( pFile, ".names x4 x5 n13 n10 z0\n" );
|
||||
fprintf( pFile, "--00 1\n" );
|
||||
fprintf( pFile, "-1-0 1\n" );
|
||||
fprintf( pFile, "1--0 1\n" );
|
||||
fprintf( pFile, "111- 1\n" );
|
||||
fprintf( pFile, ".names x1 x2 x3 x0 n13\n" );
|
||||
fprintf( pFile, "-110 1\n" );
|
||||
fprintf( pFile, "1-10 1\n" );
|
||||
fprintf( pFile, "11-0 1\n" );
|
||||
fprintf( pFile, "-001 1\n" );
|
||||
fprintf( pFile, "0-01 1\n" );
|
||||
fprintf( pFile, "00-1 1\n" );
|
||||
fprintf( pFile, ".names x4 x5 n13 n16 z1\n" );
|
||||
fprintf( pFile, "1-00 1\n" );
|
||||
fprintf( pFile, "0-10 1\n" );
|
||||
fprintf( pFile, "-101 1\n" );
|
||||
fprintf( pFile, "-011 1\n" );
|
||||
fprintf( pFile, ".names x1 x2 x3 x4 n16\n" );
|
||||
fprintf( pFile, "1000 1\n" );
|
||||
fprintf( pFile, "0100 1\n" );
|
||||
fprintf( pFile, "0010 1\n" );
|
||||
fprintf( pFile, "1110 1\n" );
|
||||
fprintf( pFile, "0001 1\n" );
|
||||
fprintf( pFile, "1101 1\n" );
|
||||
fprintf( pFile, "1011 1\n" );
|
||||
fprintf( pFile, "0111 1\n" );
|
||||
fprintf( pFile, ".names x5 n16 z2\n" );
|
||||
fprintf( pFile, "10 1\n" );
|
||||
fprintf( pFile, "01 1\n" );
|
||||
fprintf( pFile, ".end\n\n" );
|
||||
}
|
||||
void Abc_GenComp63a6( FILE * pFile )
|
||||
{
|
||||
fprintf( pFile, ".model C63a\n" );
|
||||
fprintf( pFile, ".inputs x0 x1 x2 x3 x4 x5\n" );
|
||||
fprintf( pFile, ".outputs z0 z1 z2\n" );
|
||||
fprintf( pFile, ".names x1 x2 x3 x4 x5 x0 z0\n" );
|
||||
fprintf( pFile, "---111 1\n" );
|
||||
fprintf( pFile, "--1-11 1\n" );
|
||||
fprintf( pFile, "--11-1 1\n" );
|
||||
fprintf( pFile, "-1--11 1\n" );
|
||||
fprintf( pFile, "-1-1-1 1\n" );
|
||||
fprintf( pFile, "-11--1 1\n" );
|
||||
fprintf( pFile, "-1111- 1\n" );
|
||||
fprintf( pFile, "1---11 1\n" );
|
||||
fprintf( pFile, "1--1-1 1\n" );
|
||||
fprintf( pFile, "1-1--1 1\n" );
|
||||
fprintf( pFile, "1-111- 1\n" );
|
||||
fprintf( pFile, "11---1 1\n" );
|
||||
fprintf( pFile, "11-11- 1\n" );
|
||||
fprintf( pFile, "111-1- 1\n" );
|
||||
fprintf( pFile, "1111-- 1\n" );
|
||||
fprintf( pFile, ".names x1 x2 x3 x4 x5 x0 z1\n" );
|
||||
fprintf( pFile, "-00001 1\n" );
|
||||
fprintf( pFile, "-00110 1\n" );
|
||||
fprintf( pFile, "-01010 1\n" );
|
||||
fprintf( pFile, "-01100 1\n" );
|
||||
fprintf( pFile, "-10010 1\n" );
|
||||
fprintf( pFile, "-10100 1\n" );
|
||||
fprintf( pFile, "-11000 1\n" );
|
||||
fprintf( pFile, "-11111 1\n" );
|
||||
fprintf( pFile, "0-0001 1\n" );
|
||||
fprintf( pFile, "0-0110 1\n" );
|
||||
fprintf( pFile, "0-1010 1\n" );
|
||||
fprintf( pFile, "0-1100 1\n" );
|
||||
fprintf( pFile, "00-001 1\n" );
|
||||
fprintf( pFile, "00-110 1\n" );
|
||||
fprintf( pFile, "000-01 1\n" );
|
||||
fprintf( pFile, "0000-1 1\n" );
|
||||
fprintf( pFile, "1-0010 1\n" );
|
||||
fprintf( pFile, "1-0100 1\n" );
|
||||
fprintf( pFile, "1-1000 1\n" );
|
||||
fprintf( pFile, "1-1111 1\n" );
|
||||
fprintf( pFile, "11-000 1\n" );
|
||||
fprintf( pFile, "11-111 1\n" );
|
||||
fprintf( pFile, "111-11 1\n" );
|
||||
fprintf( pFile, "1111-1 1\n" );
|
||||
fprintf( pFile, ".names x1 x2 x3 x4 x5 z2\n" );
|
||||
fprintf( pFile, "00001 1\n" );
|
||||
fprintf( pFile, "00010 1\n" );
|
||||
fprintf( pFile, "00100 1\n" );
|
||||
fprintf( pFile, "00111 1\n" );
|
||||
fprintf( pFile, "01000 1\n" );
|
||||
fprintf( pFile, "01011 1\n" );
|
||||
fprintf( pFile, "01101 1\n" );
|
||||
fprintf( pFile, "01110 1\n" );
|
||||
fprintf( pFile, "10000 1\n" );
|
||||
fprintf( pFile, "10011 1\n" );
|
||||
fprintf( pFile, "10101 1\n" );
|
||||
fprintf( pFile, "10110 1\n" );
|
||||
fprintf( pFile, "11001 1\n" );
|
||||
fprintf( pFile, "11010 1\n" );
|
||||
fprintf( pFile, "11100 1\n" );
|
||||
fprintf( pFile, "11111 1\n" );
|
||||
fprintf( pFile, ".end\n\n" );
|
||||
}
|
||||
void Abc_GenAdder4( FILE * pFile, int nBits, int nLutSize )
|
||||
{
|
||||
int i, n;
|
||||
fprintf( pFile, ".model A%02d_4x\n", nBits );
|
||||
for ( n = 0; n < 4; n++ ) {
|
||||
fprintf( pFile, ".inputs" );
|
||||
for ( i = 0; i < nBits; i++ )
|
||||
fprintf( pFile, " %c%02d", 'a'+n, i );
|
||||
fprintf( pFile, "\n" );
|
||||
}
|
||||
fprintf( pFile, ".outputs" );
|
||||
for ( i = 0; i < nBits; i++ )
|
||||
fprintf( pFile, " s%02d", i );
|
||||
fprintf( pFile, "\n" );
|
||||
fprintf( pFile, ".names v00\n" );
|
||||
fprintf( pFile, ".names w00\n" );
|
||||
for ( i = 0; i < nBits; i++ ) {
|
||||
fprintf( pFile, ".subckt C63a" );
|
||||
fprintf( pFile, " x0=w%02d", i );
|
||||
fprintf( pFile, " x1=v%02d", i );
|
||||
fprintf( pFile, " x2=a%02d", i );
|
||||
fprintf( pFile, " x3=b%02d", i );
|
||||
fprintf( pFile, " x4=c%02d", i );
|
||||
fprintf( pFile, " x5=d%02d", i );
|
||||
fprintf( pFile, " z0=w%02d", i+1 );
|
||||
fprintf( pFile, " z1=v%02d", i+1 );
|
||||
fprintf( pFile, " z2=s%02d", i );
|
||||
fprintf( pFile, "\n" );
|
||||
}
|
||||
fprintf( pFile, ".end\n\n" );
|
||||
if ( nLutSize == 4 )
|
||||
Abc_GenComp63a4( pFile );
|
||||
else if ( nLutSize == 6 )
|
||||
Abc_GenComp63a6( pFile );
|
||||
else assert( 0 );
|
||||
}
|
||||
void Abc_WriteAdder2( FILE * pFile, int nVars )
|
||||
{
|
||||
int i;
|
||||
assert( nVars > 0 );
|
||||
fprintf( pFile, ".model A%02d\n", nVars );
|
||||
fprintf( pFile, ".inputs c\n" );
|
||||
fprintf( pFile, ".inputs" );
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
fprintf( pFile, " a%02d", i );
|
||||
fprintf( pFile, "\n" );
|
||||
fprintf( pFile, ".inputs" );
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
fprintf( pFile, " b%02d", i );
|
||||
fprintf( pFile, "\n" );
|
||||
fprintf( pFile, ".outputs" );
|
||||
for ( i = 0; i <= nVars; i++ )
|
||||
fprintf( pFile, " s%02d", i );
|
||||
fprintf( pFile, "\n" );
|
||||
fprintf( pFile, ".names c t00\n1 1\n" );
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
fprintf( pFile, ".subckt FA a=a%02d b=b%02d cin=t%02d s=s%02d cout=t%02d\n", i, i, i, i, i+1 );
|
||||
fprintf( pFile, ".names t%02d s%02d\n1 1\n", nVars, nVars );
|
||||
fprintf( pFile, ".end\n\n" );
|
||||
Abc_WriteFullAdder( pFile );
|
||||
}
|
||||
void Abc_GenAdder4test( FILE * pFile, int nBits )
|
||||
{
|
||||
int i, n;
|
||||
fprintf( pFile, ".model A%02d_4x\n", nBits );
|
||||
for ( n = 0; n < 4; n++ ) {
|
||||
fprintf( pFile, ".inputs" );
|
||||
for ( i = 0; i < nBits; i++ )
|
||||
fprintf( pFile, " %c%02d", 'a'+n, i );
|
||||
fprintf( pFile, "\n" );
|
||||
}
|
||||
fprintf( pFile, ".outputs" );
|
||||
for ( i = 0; i < nBits; i++ )
|
||||
fprintf( pFile, " o%02d", i );
|
||||
fprintf( pFile, "\n" );
|
||||
|
||||
fprintf( pFile, ".names zero\n" );
|
||||
fprintf( pFile, ".subckt A%02d c=zero", nBits );
|
||||
fprintf( pFile, " \\\n" );
|
||||
for ( i = 0; i < nBits; i++ )
|
||||
fprintf( pFile, " a%0d=a%02d", i, i );
|
||||
fprintf( pFile, " \\\n" );
|
||||
for ( i = 0; i < nBits; i++ )
|
||||
fprintf( pFile, " b%0d=b%02d", i, i );
|
||||
fprintf( pFile, " \\\n" );
|
||||
for ( i = 0; i <= nBits; i++ )
|
||||
fprintf( pFile, " s%0d=t%02d", i, i );
|
||||
fprintf( pFile, "\n" );
|
||||
|
||||
fprintf( pFile, ".subckt A%02d c=zero", nBits );
|
||||
fprintf( pFile, " \\\n" );
|
||||
for ( i = 0; i < nBits; i++ )
|
||||
fprintf( pFile, " a%0d=c%02d", i, i );
|
||||
fprintf( pFile, " \\\n" );
|
||||
for ( i = 0; i < nBits; i++ )
|
||||
fprintf( pFile, " b%0d=t%02d", i, i );
|
||||
fprintf( pFile, " \\\n" );
|
||||
for ( i = 0; i <= nBits; i++ )
|
||||
fprintf( pFile, " s%0d=u%02d", i, i );
|
||||
fprintf( pFile, "\n" );
|
||||
|
||||
fprintf( pFile, ".subckt A%02d c=zero", nBits );
|
||||
fprintf( pFile, " \\\n" );
|
||||
for ( i = 0; i < nBits; i++ )
|
||||
fprintf( pFile, " a%0d=d%02d", i, i );
|
||||
fprintf( pFile, " \\\n" );
|
||||
for ( i = 0; i < nBits; i++ )
|
||||
fprintf( pFile, " b%0d=u%02d", i, i );
|
||||
fprintf( pFile, " \\\n" );
|
||||
for ( i = 0; i <= nBits; i++ )
|
||||
fprintf( pFile, " s%0d=o%02d", i, i );
|
||||
fprintf( pFile, "\n" );
|
||||
|
||||
fprintf( pFile, ".end\n\n" );
|
||||
Abc_WriteAdder( pFile, nBits );
|
||||
}
|
||||
void Abc_WriteWeight( FILE * pFile, int Num, int nBits, int Weight )
|
||||
{
|
||||
int i;
|
||||
fprintf( pFile, ".model W%02d\n", Num );
|
||||
fprintf( pFile, ".inputs i\n" );
|
||||
fprintf( pFile, ".outputs" );
|
||||
for ( i = 0; i < nBits; i++ )
|
||||
fprintf( pFile, " o%02d", i );
|
||||
fprintf( pFile, "\n" );
|
||||
for ( i = 0; i < nBits; i++ )
|
||||
if ( (Weight >> i) & 1 )
|
||||
fprintf( pFile, ".names i o%02d\n1 1\n", i );
|
||||
else
|
||||
fprintf( pFile, ".names o%02d\n", i );
|
||||
fprintf( pFile, ".end\n\n" );
|
||||
}
|
||||
|
||||
Vec_Int_t * Abc_GenTreeFindGroups( char * pTree, int iPos )
|
||||
{
|
||||
Vec_Int_t * vRes = NULL;
|
||||
int Counter = 1;
|
||||
assert( pTree[iPos] == '(' );
|
||||
while ( pTree[++iPos] ) {
|
||||
if ( pTree[iPos] == '(' ) {
|
||||
if ( Counter++ == 1 ) {
|
||||
if ( vRes == NULL )
|
||||
vRes = Vec_IntAlloc( 4 );
|
||||
Vec_IntPush( vRes, iPos );
|
||||
}
|
||||
}
|
||||
if ( pTree[iPos] == ')' )
|
||||
Counter--;
|
||||
if ( Counter == 0 )
|
||||
return vRes;
|
||||
}
|
||||
assert( 0 );
|
||||
return NULL;
|
||||
}
|
||||
int Abc_GenTree_rec( FILE * pFile, int nBits, char * pTree, int iPos, int * pSig, int * pUsed )
|
||||
{
|
||||
Vec_Int_t * vGroups = Abc_GenTreeFindGroups( pTree, iPos );
|
||||
if ( vGroups == NULL )
|
||||
return atoi(pTree+iPos+1);
|
||||
int i, g, Group;
|
||||
Vec_IntForEachEntry( vGroups, Group, g ) {
|
||||
Group = Abc_GenTree_rec( pFile, nBits, pTree, Group, pSig, pUsed );
|
||||
Vec_IntWriteEntry( vGroups, g, Group );
|
||||
}
|
||||
if ( Vec_IntSize(vGroups) == 3 )
|
||||
Vec_IntPush(vGroups, 0);
|
||||
if ( Vec_IntSize(vGroups) == 4 )
|
||||
fprintf( pFile, ".subckt A%02d_4x", nBits ), *pUsed = 1;
|
||||
else if ( Vec_IntSize(vGroups) == 2 )
|
||||
fprintf( pFile, ".subckt A%02d c=zero", nBits );
|
||||
else assert( 0 );
|
||||
Vec_IntForEachEntry( vGroups, Group, g ) {
|
||||
fprintf( pFile, " \\\n" );
|
||||
for ( i = 0; i < nBits; i++ )
|
||||
fprintf( pFile, " %c%02d=%02d_%02d", 'a'+g, i, Group, i );
|
||||
}
|
||||
fprintf( pFile, " \\\n" );
|
||||
for ( i = 0; i < nBits; i++ )
|
||||
fprintf( pFile, " s%02d=%02d_%02d", i, *pSig, i );
|
||||
fprintf( pFile, "\n\n" );
|
||||
return (*pSig)++;
|
||||
}
|
||||
void Abc_GenThreshAdder( FILE * pFile, int nBits, int A, int B, int S, int fOne )
|
||||
{
|
||||
if ( A > B ) ABC_SWAP( int, A, B ); int i;
|
||||
fprintf( pFile, ".subckt A%02d c=%s", nBits, fOne ? "one" : "zero" );
|
||||
fprintf( pFile, " \\\n" );
|
||||
for ( i = 0; i < nBits; i++ )
|
||||
fprintf( pFile, " a%02d=%02d_%02d", i, A, i );
|
||||
fprintf( pFile, " \\\n" );
|
||||
for ( i = 0; i < nBits; i++ )
|
||||
fprintf( pFile, " b%02d=%02d_%02d", i, B, i );
|
||||
fprintf( pFile, " \\\n" );
|
||||
for ( i = 0; i <= nBits; i++ )
|
||||
fprintf( pFile, " s%02d=%02d_%02d", i, S, i );
|
||||
fprintf( pFile, "\n" );
|
||||
}
|
||||
void Abc_GenThresh( char * pFileName, int nBits, Vec_Int_t * vNums, int nLutSize, char * pArch )
|
||||
{
|
||||
FILE * pFile = fopen( pFileName, "w" );
|
||||
int c, i, k, Temp, iPrev = 1, nNums = 1, nSigs = 1, fUsed = 0;
|
||||
fprintf( pFile, "# %d-bit threshold function with %d variables generated by ABC on %s\n",
|
||||
nBits, Vec_IntSize(vNums)-1, Extra_TimeStamp() );
|
||||
fprintf( pFile, "# Weights:" );
|
||||
Vec_IntForEachEntryStop( vNums, Temp, i, Vec_IntSize(vNums)-1 )
|
||||
fprintf( pFile, " %d", Temp );
|
||||
fprintf( pFile, "\n# Threshold: %d\n", Vec_IntEntryLast(vNums) );
|
||||
fprintf( pFile, ".model TF%d_%d\n", Vec_IntSize(vNums)-1, nBits );
|
||||
fprintf( pFile, ".inputs" );
|
||||
for ( i = 0; i < Vec_IntSize(vNums)-1; i++ )
|
||||
fprintf( pFile, " x%02d", i );
|
||||
fprintf( pFile, "\n" );
|
||||
fprintf( pFile, ".outputs F\n" );
|
||||
for ( i = 0; i < nBits; i++ )
|
||||
fprintf( pFile, ".names %02d_%02d\n", 0, i );
|
||||
fprintf( pFile, ".names zero\n" );
|
||||
fprintf( pFile, ".names one\n 1\n" );
|
||||
Vec_IntForEachEntry( vNums, Temp, k ) {
|
||||
fprintf( pFile, ".subckt W%02d", k );
|
||||
if ( k < Vec_IntSize(vNums)-1 )
|
||||
fprintf( pFile, " i=x%02d", k );
|
||||
else
|
||||
fprintf( pFile, " i=one" );
|
||||
for ( i = 0; i < nBits; i++ )
|
||||
fprintf( pFile, " o%02d=%02d_%02d", i, nSigs, i );
|
||||
fprintf( pFile, "\n" );
|
||||
nSigs++;
|
||||
}
|
||||
fprintf( pFile, "\n" );
|
||||
if ( pArch == NULL )
|
||||
{
|
||||
Vec_IntForEachEntryStart( vNums, Temp, k, 1 ) {
|
||||
Abc_GenThreshAdder( pFile, nBits, iPrev, k+1, nSigs, k == Vec_IntSize(vNums)-1 );
|
||||
iPrev = nSigs++;
|
||||
}
|
||||
fprintf( pFile, ".names %02d_%02d F\n0 1\n", iPrev, nBits-1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
Vec_Str_t * vArch = Vec_StrAlloc( 100 );
|
||||
for ( c = 0; c < strlen(pArch); c++ ) {
|
||||
if ( pArch[c] == '(' || pArch[c] == ')' ) {
|
||||
Vec_StrPush( vArch, pArch[c] );
|
||||
continue;
|
||||
}
|
||||
Temp = pArch[c] >= '0' && pArch[c] <= '9' ? pArch[c] - '0' : pArch[c] - 'A' + 10;
|
||||
assert( Temp > 0 );
|
||||
if ( Temp == 1 ) {
|
||||
if ( nNums + Temp == Vec_IntSize(vNums) )
|
||||
Abc_GenThreshAdder( pFile, nBits, nNums, nNums+1, iPrev = nSigs++, 1 );
|
||||
else
|
||||
iPrev = nNums++;
|
||||
}
|
||||
else {
|
||||
int kLast = 0;
|
||||
assert( nNums + Temp <= Vec_IntSize(vNums) );
|
||||
if ( nNums + Temp == Vec_IntSize(vNums) )
|
||||
kLast = Temp++;
|
||||
iPrev = nNums++;
|
||||
for ( k = 1; k < Temp; k++ ) {
|
||||
Abc_GenThreshAdder( pFile, nBits, iPrev, nNums++, nSigs, k == kLast );
|
||||
iPrev = nSigs++;
|
||||
}
|
||||
fprintf( pFile, "\n" );
|
||||
}
|
||||
Vec_StrPrintF( vArch, "(%d)", iPrev );
|
||||
}
|
||||
Vec_StrPush( vArch, '\0' );
|
||||
Temp = Abc_GenTree_rec( pFile, nBits, Vec_StrArray(vArch), 0, &nSigs, &fUsed );
|
||||
fprintf( pFile, ".names %02d_%02d F\n0 1\n", Temp, nBits-1 );
|
||||
Vec_StrFree( vArch );
|
||||
}
|
||||
fprintf( pFile, ".end\n\n" );
|
||||
Vec_IntForEachEntry( vNums, Temp, k )
|
||||
Abc_WriteWeight( pFile, k, nBits, k == Vec_IntSize(vNums)-1 ? ~Temp : Temp );
|
||||
Abc_WriteAdder2( pFile, nBits );
|
||||
if ( fUsed )
|
||||
Abc_GenAdder4( pFile, nBits, nLutSize == 4 ? 4 : 6 );
|
||||
fclose( pFile );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adder tree generation.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
// Based on the paper: E. Demenkov, A. Kojevnikov, A. Kulikov, and G. Yaroslavtsev,
|
||||
// "New upper bounds on the Boolean circuit complexity of symmetric functions".
|
||||
// Information Processing Letters, Vol 110(7), March 2010, Pages 264-267.
|
||||
// https://grigory.us/files/publications/2010_upper_bounds_symmetric_ipl.pdf
|
||||
|
||||
void Abc_WriteMDFA( FILE * pFile )
|
||||
{
|
||||
fprintf( pFile, ".model MDFA\n" );
|
||||
fprintf( pFile, ".inputs z x1 y1 x2 y2\n" );
|
||||
fprintf( pFile, ".outputs s c1 c2\n" );
|
||||
fprintf( pFile, ".names x1 z g1\n" );
|
||||
fprintf( pFile, "10 1\n" );
|
||||
fprintf( pFile, "01 1\n" );
|
||||
fprintf( pFile, ".names y1 g1 g2\n" );
|
||||
fprintf( pFile, "00 0\n" );
|
||||
fprintf( pFile, ".names y1 z g3\n" );
|
||||
fprintf( pFile, "10 1\n" );
|
||||
fprintf( pFile, "01 1\n" );
|
||||
fprintf( pFile, ".names g2 g3 g4\n" );
|
||||
fprintf( pFile, "10 1\n" );
|
||||
fprintf( pFile, "01 1\n" );
|
||||
fprintf( pFile, ".names x2 g3 g5\n" );
|
||||
fprintf( pFile, "10 1\n" );
|
||||
fprintf( pFile, "01 1\n" );
|
||||
fprintf( pFile, ".names g3 y2 g6\n" );
|
||||
fprintf( pFile, "10 1\n" );
|
||||
fprintf( pFile, "01 1\n" );
|
||||
fprintf( pFile, ".names g5 y2 g7\n" );
|
||||
fprintf( pFile, "10 1\n" );
|
||||
fprintf( pFile, ".names g2 g7 g8\n" );
|
||||
fprintf( pFile, "10 1\n" );
|
||||
fprintf( pFile, "01 1\n" );
|
||||
fprintf( pFile, ".names g6 s\n" );
|
||||
fprintf( pFile, "1 1\n" );
|
||||
fprintf( pFile, ".names g4 c1\n" );
|
||||
fprintf( pFile, "1 1\n" );
|
||||
fprintf( pFile, ".names g8 c2\n" );
|
||||
fprintf( pFile, "1 1\n" );
|
||||
fprintf( pFile, ".end\n" );
|
||||
}
|
||||
|
||||
void Abc_GenAT( char * pFileName, Vec_Int_t * vNums )
|
||||
{
|
||||
word Sum = 0; int i, k, Num, nBits = 0;
|
||||
Vec_IntForEachEntry( vNums, Num, i )
|
||||
Sum += ((word)1 << i) * Num;
|
||||
while ( Sum )
|
||||
nBits++, Sum >>= 1;
|
||||
|
||||
Vec_Int_t * vTemp; int nFAs = 0, nHAs = 0, nItem = 0;
|
||||
Vec_Wec_t * vItems = Vec_WecStart( nBits );
|
||||
Vec_IntForEachEntry( vNums, Num, i )
|
||||
for ( k = 0; k < Num; k++ )
|
||||
Vec_WecPush( vItems, i, nItem++ );
|
||||
|
||||
FILE * pFile = fopen( pFileName, "w" );
|
||||
fprintf( pFile, "# %d-bit %d-input adder tree generated by ABC on %s\n", nBits, nItem, Extra_TimeStamp() );
|
||||
fprintf( pFile, "# Profile:" );
|
||||
Vec_IntForEachEntry( vNums, Num, i )
|
||||
fprintf( pFile, " %d", Num );
|
||||
fprintf( pFile, "\n" );
|
||||
|
||||
fprintf( pFile, ".model AT%d_%d\n", nItem, nBits );
|
||||
Vec_WecForEachLevel( vItems, vTemp, i ) {
|
||||
if ( Vec_IntSize(vTemp) == 0 )
|
||||
continue;
|
||||
fprintf( pFile, ".inputs" );
|
||||
Vec_IntForEachEntry( vTemp, Num, k )
|
||||
fprintf( pFile, " %02d", Num );
|
||||
fprintf( pFile, "\n" );
|
||||
}
|
||||
fprintf( pFile, ".outputs" );
|
||||
for ( k = 0; k < nBits; k++ )
|
||||
fprintf( pFile, " o%02d", k );
|
||||
fprintf( pFile, "\n\n" );
|
||||
|
||||
assert( nItem == Vec_IntSum(vNums) );
|
||||
Vec_WecForEachLevel( vItems, vTemp, i ) {
|
||||
fprintf( pFile, "# Rank %d:\n", i );
|
||||
Vec_IntForEachEntry( vTemp, Num, k ) {
|
||||
if ( Vec_IntSize(vTemp) < 2 )
|
||||
continue;
|
||||
while ( Vec_IntSize(vTemp) > 2 ) {
|
||||
int i1 = Vec_IntPop(vTemp);
|
||||
int i2 = Vec_IntPop(vTemp);
|
||||
int i3 = Vec_IntPop(vTemp);
|
||||
int i4 = nItem++;
|
||||
int i5 = nItem++;
|
||||
fprintf( pFile, ".subckt FA a=%02d b=%02d cin=%02d s=%02d cout=%02d\n", i3, i2, i1, i4, i5 ); nFAs++;
|
||||
Vec_IntPush( vTemp, i4 );
|
||||
if ( i+1 < Vec_WecSize(vItems) )
|
||||
Vec_WecPush( vItems, i+1, i5 );
|
||||
}
|
||||
if ( Vec_IntSize(vTemp) == 2 ) {
|
||||
int i1 = Vec_IntPop(vTemp);
|
||||
int i2 = Vec_IntPop(vTemp);
|
||||
int i4 = nItem++;
|
||||
int i5 = nItem++;
|
||||
fprintf( pFile, ".subckt HA a=%02d b=%02d s=%02d cout=%02d\n", i2, i1, i4, i5 ); nHAs++;
|
||||
Vec_IntPush( vTemp, i4 );
|
||||
if ( i+1 < Vec_WecSize(vItems) )
|
||||
Vec_WecPush( vItems, i+1, i5 );
|
||||
}
|
||||
assert( Vec_IntSize(vTemp) == 1 );
|
||||
}
|
||||
}
|
||||
Vec_WecForEachLevel( vItems, vTemp, i )
|
||||
if ( Vec_IntSize(vTemp) == 0 )
|
||||
fprintf( pFile, ".names o%02d\n", i );
|
||||
else if ( Vec_IntSize(vTemp) == 1 )
|
||||
fprintf( pFile, ".names %02d o%02d\n1 1\n", Vec_IntEntry(vTemp, 0), i );
|
||||
else assert( 0 );
|
||||
fprintf( pFile, ".end\n\n" );
|
||||
Abc_WriteHalfAdder( pFile );
|
||||
Abc_WriteFullAdder( pFile );
|
||||
printf( "Created %d-bit %d-input AT with %d FAs and %d HAs.\n", nBits, Vec_IntSum(vNums), nFAs, nHAs );
|
||||
fclose( pFile );
|
||||
Vec_WecFree( vItems );
|
||||
}
|
||||
void Abc_GenATDual( char * pFileName, Vec_Int_t * vNums )
|
||||
{
|
||||
word Sum = 0; int i, k, Num, nBits = 0, Iter = 0, fUsed = 0;
|
||||
Vec_IntForEachEntry( vNums, Num, i )
|
||||
Sum += ((word)1 << i) * Num;
|
||||
while ( Sum )
|
||||
nBits++, Sum >>= 1;
|
||||
|
||||
Vec_Int_t * vTemp; int nFAs = 0, nHAs = 0, nXors = 0, nItem = 1;
|
||||
Vec_Wec_t * vItems = Vec_WecStart( nBits );
|
||||
Vec_IntForEachEntry( vNums, Num, i )
|
||||
for ( k = 0; k < Num; k++ )
|
||||
Vec_WecPush( vItems, i, nItem++ );
|
||||
|
||||
FILE * pFile = fopen( pFileName, "w" );
|
||||
fprintf( pFile, "# %d-bit %d-input adder tree generated by ABC on %s\n", nBits, Vec_IntSum(vNums), Extra_TimeStamp() );
|
||||
fprintf( pFile, "# Profile:" );
|
||||
Vec_IntForEachEntry( vNums, Num, i )
|
||||
fprintf( pFile, " %d", Num );
|
||||
fprintf( pFile, "\n" );
|
||||
|
||||
fprintf( pFile, ".model AT%d_%d\n", nItem, nBits );
|
||||
Vec_WecForEachLevel( vItems, vTemp, i ) {
|
||||
if ( Vec_IntSize(vTemp) == 0 )
|
||||
continue;
|
||||
fprintf( pFile, ".inputs" );
|
||||
Vec_IntForEachEntry( vTemp, Num, k )
|
||||
fprintf( pFile, " %02d", Num );
|
||||
fprintf( pFile, "\n" );
|
||||
}
|
||||
fprintf( pFile, ".outputs" );
|
||||
for ( k = 0; k < nBits; k++ )
|
||||
fprintf( pFile, " o%02d", k );
|
||||
fprintf( pFile, "\n\n" );
|
||||
|
||||
fprintf( pFile, ".names %02d\n", 0 );
|
||||
while ( Vec_WecMaxLevelSize(vItems) > 2 )
|
||||
{
|
||||
fprintf( pFile, "# Iter %d:\n", Iter++ );
|
||||
Vec_Wec_t * vItems2 = Vec_WecStart( nBits );
|
||||
Vec_WecForEachLevel( vItems, vTemp, i ) {
|
||||
while ( Vec_IntSize(vTemp) > 3 ) {
|
||||
int i0 = Vec_IntEntry(vTemp, 0); Vec_IntDrop(vTemp, 0);
|
||||
int i1 = Vec_IntEntry(vTemp, 0); Vec_IntDrop(vTemp, 0);
|
||||
int i2 = Vec_IntEntry(vTemp, 0); Vec_IntDrop(vTemp, 0);
|
||||
int i3 = Vec_IntEntry(vTemp, 0); Vec_IntDrop(vTemp, 0);
|
||||
int i4 = (Vec_IntSize(vTemp) > 0 && Vec_IntEntryLast(vTemp) > 0) ? Vec_IntPop(vTemp) : 0;
|
||||
assert( (i0 < 0) == (i1 < 0) );
|
||||
assert( (i2 < 0) == (i3 < 0) );
|
||||
if ( i1 > 0 )
|
||||
fprintf( pFile, ".names %02d %02d %02d\n01 1\n10 1\n", i0, i1, nItem ), i1 = nItem++, nXors++;
|
||||
else
|
||||
i1 = -i1, i0 = -i0;
|
||||
if ( i3 > 0 )
|
||||
fprintf( pFile, ".names %02d %02d %02d\n01 1\n10 1\n", i2, i3, nItem ), i3 = nItem++, nXors++;
|
||||
else
|
||||
i3 = -i3, i2 = -i2;
|
||||
int o0 = nItem++;
|
||||
int o1 = nItem++;
|
||||
int o2 = nItem++;
|
||||
fprintf( pFile, ".subckt MDFA z=%02d x1=%02d y1=%02d x2=%02d y2=%02d s=%02d c1=%02d c2=%02d\n", i4, i0, i1, i2, i3, o0, o1, o2 ); nFAs += 2, fUsed = 1;
|
||||
Vec_WecPush( vItems2, i, o0 );
|
||||
if ( i+1 < Vec_WecSize(vItems2) ) {
|
||||
Vec_WecPush( vItems2, i+1, -o1 );
|
||||
Vec_WecPush( vItems2, i+1, -o2 );
|
||||
}
|
||||
}
|
||||
if ( Vec_IntSize(vTemp) == 3 ) {
|
||||
int i2 = Vec_IntPop(vTemp);
|
||||
int i1 = Vec_IntPop(vTemp);
|
||||
int i0 = Vec_IntPop(vTemp);
|
||||
assert( (i0 < 0) == (i1 < 0) );
|
||||
assert( i2 > 0 );
|
||||
if ( i1 < 0 )
|
||||
fprintf( pFile, ".names %02d %02d %02d\n01 1\n10 1\n", -i0, -i1, nItem ), i0 = -i0, i1 = nItem++, nXors++;
|
||||
int o0 = nItem++;
|
||||
int o1 = nItem++;
|
||||
fprintf( pFile, ".subckt FA a=%02d b=%02d cin=%02d s=%02d cout=%02d\n", i0, i1, i2, o0, o1 ); nFAs++;
|
||||
Vec_WecPush( vItems2, i, o0 );
|
||||
if ( i+1 < Vec_WecSize(vItems2) )
|
||||
Vec_WecPush( vItems2, i+1, o1 );
|
||||
}
|
||||
if ( Vec_IntSize(vTemp) == 2 ) {
|
||||
int i1 = Vec_IntPop(vTemp);
|
||||
int i0 = Vec_IntPop(vTemp);
|
||||
assert( (i0 < 0) == (i1 < 0) );
|
||||
if ( i1 < 0 ) {
|
||||
Vec_IntInsert( Vec_WecEntry(vItems2, i), 0, i1 );
|
||||
Vec_IntInsert( Vec_WecEntry(vItems2, i), 0, i0 );
|
||||
}
|
||||
else {
|
||||
Vec_WecPush( vItems2, i, i0 );
|
||||
Vec_WecPush( vItems2, i, i1 );
|
||||
}
|
||||
}
|
||||
if ( Vec_IntSize(vTemp) == 1 ) {
|
||||
int i0 = Vec_IntPop(vTemp);
|
||||
assert( i0 > 0 );
|
||||
Vec_WecPush( vItems2, i, i0 );
|
||||
}
|
||||
assert( Vec_IntSize(vTemp) == 0 );
|
||||
}
|
||||
Vec_WecFree( vItems );
|
||||
vItems = vItems2;
|
||||
}
|
||||
Vec_WecForEachLevel( vItems, vTemp, i ) {
|
||||
if ( Vec_IntSize(vTemp) == 2 ) {
|
||||
int i1 = Vec_IntPop(vTemp);
|
||||
int i0 = Vec_IntPop(vTemp);
|
||||
assert( (i0 < 0) == (i1 < 0) );
|
||||
if ( i1 < 0 )
|
||||
fprintf( pFile, ".names %02d %02d %02d\n01 1\n10 1\n", -i0, -i1, nItem ), i0 = -i0, i1 = nItem++, nXors++;
|
||||
Vec_IntPush( vTemp, i0 );
|
||||
Vec_IntPush( vTemp, i1 );
|
||||
}
|
||||
if ( Vec_IntSize(vTemp) == 1 ) {
|
||||
int i0 = Vec_IntPop(vTemp);
|
||||
assert( i0 > 0 );
|
||||
Vec_IntPush( vTemp, i0 );
|
||||
Vec_IntPush( vTemp, 0 );
|
||||
}
|
||||
if ( Vec_IntSize(vTemp) == 0 ) {
|
||||
Vec_IntPush( vTemp, 0 );
|
||||
Vec_IntPush( vTemp, 0 );
|
||||
}
|
||||
assert( Vec_IntSize(vTemp) == 2 );
|
||||
}
|
||||
int cin = 0;
|
||||
Vec_WecForEachLevel( vItems, vTemp, i ) {
|
||||
int i1 = Vec_IntPop(vTemp);
|
||||
int i0 = Vec_IntPop(vTemp);
|
||||
assert( i0 >= 0 && i1 >= 0 );
|
||||
fprintf( pFile, ".subckt FA a=%02d b=%02d cin=%02d s=o%02d cout=%02d\n", i0, i1, cin, i, nItem ); nFAs++;
|
||||
cin = nItem++;
|
||||
}
|
||||
fprintf( pFile, ".end\n\n" );
|
||||
Abc_WriteFullAdder( pFile );
|
||||
if ( fUsed )
|
||||
Abc_WriteMDFA( pFile );
|
||||
printf( "Created %d-bit %d-input AT with %d FAs, %d HAs, and %d XORs.\n", nBits, Vec_IntSum(vNums), nFAs, nHAs, nXors );
|
||||
fclose( pFile );
|
||||
Vec_WecFree( vItems );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -465,10 +465,14 @@ void Abc_DecRecordToHop( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Cut_t * pCut
|
|||
{
|
||||
val = acd_decompose( pTruth, pCutBest->nLeaves, pIfMan->pPars->nLutDecSize, &(delayProfile), decompArray );
|
||||
}
|
||||
else
|
||||
else if ( pIfMan->pPars->fUserLut2D )
|
||||
{
|
||||
val = acd2_decompose( pTruth, pCutBest->nLeaves, pIfMan->pPars->nLutDecSize, &(delayProfile), decompArray );
|
||||
}
|
||||
else
|
||||
{
|
||||
val = acdXX_decompose( pTruth, pIfMan->pPars->nLutDecSize, pCutBest->nLeaves, decompArray );
|
||||
}
|
||||
assert( val == 0 );
|
||||
|
||||
// convert the LUT-structure into a set of logic nodes in Abc_Ntk_t
|
||||
|
|
@ -593,7 +597,7 @@ Abc_Obj_t * Abc_NodeFromIf_rec( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Obj_t
|
|||
If_CutForEachLeafReverse( pIfMan, pCutBest, pIfLeaf, i )
|
||||
Abc_ObjAddFanin( pNodeNew, Abc_NodeFromIf_rec(pNtkNew, pIfMan, pIfLeaf, vCover) );
|
||||
}
|
||||
else if ( pIfMan->pPars->fUserLutDec || pIfMan->pPars->fUserLut2D )
|
||||
else if ( pIfMan->pPars->fUserLutDec || pIfMan->pPars->fUserLut2D || pIfMan->pPars->fDeriveLuts )
|
||||
{
|
||||
If_CutForEachLeaf( pIfMan, pCutBest, pIfLeaf, i )
|
||||
Abc_NodeFromIf_rec(pNtkNew, pIfMan, pIfLeaf, vCover);
|
||||
|
|
@ -651,7 +655,7 @@ 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 )
|
||||
else if ( pIfMan->pPars->fUserLutDec || pIfMan->pPars->fUserLut2D || pIfMan->pPars->fDeriveLuts )
|
||||
{
|
||||
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 );
|
||||
|
|
|
|||
|
|
@ -574,6 +574,49 @@ Abc_Obj_t * Abc_NtkBddFindCofactor( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, int
|
|||
return pNodeTop;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkBddDecExploreOne( DdManager * dd, DdNode * bFunc, int iOrder )
|
||||
{
|
||||
DdManager * ddNew = Cudd_Init( dd->size, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
|
||||
int i, * pProfile = ABC_CALLOC( int, dd->size + 100 );
|
||||
Cudd_AutodynEnable( ddNew, CUDD_REORDER_SYMM_SIFT );
|
||||
Vec_Int_t * vPerm = Vec_IntStartNatural( dd->size ); if ( iOrder ) Vec_IntRandomizeOrder( vPerm );
|
||||
DdNode * bFuncNew = Extra_TransferPermute( dd, ddNew, bFunc, Vec_IntArray(vPerm) ); Cudd_Ref(bFuncNew);
|
||||
if ( iOrder ) Cudd_ReduceHeap( ddNew, CUDD_REORDER_SYMM_SIFT, 1 );
|
||||
Vec_IntFree( vPerm );
|
||||
DdNode * aFuncNew = Cudd_BddToAdd( ddNew, bFuncNew ); Cudd_Ref( aFuncNew );
|
||||
Extra_ProfileWidth( ddNew, aFuncNew, pProfile, -1 );
|
||||
if ( iOrder )
|
||||
printf( "Random order %d:\n", iOrder );
|
||||
else
|
||||
printf( "Natural order:\n" );
|
||||
for ( i = 0; i <= dd->size; i++ )
|
||||
printf( " %d=%d(%d)[%d]", i, pProfile[i], i-Abc_Base2Log(pProfile[i]), ddNew->perm[i] );
|
||||
printf( "\n" );
|
||||
Cudd_RecursiveDeref( ddNew, aFuncNew );
|
||||
Cudd_RecursiveDeref( ddNew, bFuncNew );
|
||||
Cudd_Quit( ddNew );
|
||||
}
|
||||
void Abc_NtkBddDecExplore( Abc_Obj_t * pNode )
|
||||
{
|
||||
DdManager * dd = (DdManager *)pNode->pNtk->pManFunc;
|
||||
DdNode * bFunc = (DdNode *)pNode->pData;
|
||||
int i; Abc_Random(1);
|
||||
if ( Abc_ObjIsNode(pNode) )
|
||||
for ( i = 0; i < 16; i++ )
|
||||
Abc_NtkBddDecExploreOne( dd, bFunc, i );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Decompose the function once.]
|
||||
|
|
@ -612,14 +655,14 @@ Abc_Obj_t * Abc_NtkBddDecompose( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, int nLu
|
|||
vCofs = Abc_NtkBddCofactors( dd, (DdNode *)pNode->pData, nLutSize );
|
||||
vUniq = Vec_PtrDup( vCofs );
|
||||
Vec_PtrUniqify( vUniq, (int (*)(const void *, const void *))Vec_PtrSortCompare );
|
||||
// only perform decomposition with it is support reduring with two less vars
|
||||
// only perform decomposition which it is support reducing with two less vars
|
||||
if( Vec_PtrSize(vUniq) > (1 << (nLutSize-2)) )
|
||||
{
|
||||
Vec_PtrFree( vCofs );
|
||||
vCofs = Abc_NtkBddCofactors( dd, (DdNode *)pNode->pData, 2 );
|
||||
if ( fVerbose )
|
||||
printf( "Decomposing %d-input node %d using cofactoring with %d cofactors.\n",
|
||||
Abc_ObjFaninNum(pNode), Abc_ObjId(pNode), Vec_PtrSize(vCofs) );
|
||||
printf( "Decomposing %d-input node %d using cofactoring with %d cofactors (myu = %d).\n",
|
||||
Abc_ObjFaninNum(pNode), Abc_ObjId(pNode), Vec_PtrSize(vCofs), Vec_PtrSize(vUniq) );
|
||||
// implement the cofactors
|
||||
pCofs[0] = Abc_ObjFanin(pNode, 0)->pCopy;
|
||||
pCofs[1] = Abc_ObjFanin(pNode, 1)->pCopy;
|
||||
|
|
@ -688,13 +731,13 @@ void Abc_NtkLutminConstruct( Abc_Ntk_t * pNtkClp, Abc_Ntk_t * pNtkDec, int nLutS
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Abc_NtkLutminInt( Abc_Ntk_t * pNtk, int nLutSize, int fVerbose )
|
||||
Abc_Ntk_t * Abc_NtkLutminInt( Abc_Ntk_t * pNtk, int nLutSize, int fReorder, int fVerbose )
|
||||
{
|
||||
extern void Abc_NtkBddReorder( Abc_Ntk_t * pNtk, int fVerbose );
|
||||
Abc_Ntk_t * pNtkDec;
|
||||
// minimize BDDs
|
||||
// Abc_NtkBddReorder( pNtk, fVerbose );
|
||||
Abc_NtkBddReorder( pNtk, 0 );
|
||||
if ( fReorder )
|
||||
Abc_NtkBddReorder( pNtk, 0 );
|
||||
// decompose one output at a time
|
||||
pNtkDec = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_BDD );
|
||||
// make sure the new manager has enough inputs
|
||||
|
|
@ -719,7 +762,7 @@ Abc_Ntk_t * Abc_NtkLutminInt( Abc_Ntk_t * pNtk, int nLutSize, int fVerbose )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Abc_NtkLutmin( Abc_Ntk_t * pNtkInit, int nLutSize, int fVerbose )
|
||||
Abc_Ntk_t * Abc_NtkLutmin( Abc_Ntk_t * pNtkInit, int nLutSize, int fReorder, int fVerbose )
|
||||
{
|
||||
extern int Abc_NtkFraigSweep( Abc_Ntk_t * pNtk, int fUseInv, int fExdc, int fVerbose, int fVeryVerbose );
|
||||
Abc_Ntk_t * pNtkNew, * pTemp;
|
||||
|
|
@ -740,7 +783,7 @@ Abc_Ntk_t * Abc_NtkLutmin( Abc_Ntk_t * pNtkInit, int nLutSize, int fVerbose )
|
|||
else
|
||||
pNtkNew = Abc_NtkStrash( pNtkInit, 0, 1, 0 );
|
||||
// collapse the network
|
||||
pNtkNew = Abc_NtkCollapse( pTemp = pNtkNew, 10000, 0, 1, 0, 0, 0 );
|
||||
pNtkNew = Abc_NtkCollapse( pTemp = pNtkNew, 10000, 0, fReorder, 0, 0, 0 );
|
||||
Abc_NtkDelete( pTemp );
|
||||
if ( pNtkNew == NULL )
|
||||
return NULL;
|
||||
|
|
@ -755,7 +798,7 @@ Abc_Ntk_t * Abc_NtkLutmin( Abc_Ntk_t * pNtkInit, int nLutSize, int fVerbose )
|
|||
if ( fVerbose )
|
||||
printf( "Decomposing network with %d nodes and %d max fanin count for K = %d.\n",
|
||||
Abc_NtkNodeNum(pNtkNew), Abc_NtkGetFaninMax(pNtkNew), nLutSize );
|
||||
pNtkNew = Abc_NtkLutminInt( pTemp = pNtkNew, nLutSize, fVerbose );
|
||||
pNtkNew = Abc_NtkLutminInt( pTemp = pNtkNew, nLutSize, fReorder, fVerbose );
|
||||
Abc_NtkDelete( pTemp );
|
||||
}
|
||||
// fix the problem with complemented and duplicated CO edges
|
||||
|
|
@ -773,7 +816,8 @@ Abc_Ntk_t * Abc_NtkLutmin( Abc_Ntk_t * pNtkInit, int nLutSize, int fVerbose )
|
|||
|
||||
#else
|
||||
|
||||
Abc_Ntk_t * Abc_NtkLutmin( Abc_Ntk_t * pNtkInit, int nLutSize, int fVerbose ) { return NULL; }
|
||||
Abc_Ntk_t * Abc_NtkLutmin( Abc_Ntk_t * pNtkInit, int nLutSize, int fReorder, int fVerbose ) { return NULL; }
|
||||
void Abc_NtkBddDecExplore( Abc_Obj_t * pNode ) {}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include "map/mapper/mapper.h"
|
||||
#include "misc/util/utilNam.h"
|
||||
#include "map/scl/sclCon.h"
|
||||
#include "map/scl/sclLib.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -275,6 +276,7 @@ Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, f
|
|||
Map_ManSetAreaRecovery( pMan, fRecovery );
|
||||
Map_ManSetOutputNames( pMan, Abc_NtkCollectCioNames(pNtk, 1) );
|
||||
Map_ManSetDelayTarget( pMan, (float)DelayTarget );
|
||||
Map_ManCreateAigIds( pMan, Abc_NtkObjNumMax(pNtk) );
|
||||
|
||||
// set arrival and requireds
|
||||
if ( Scl_ConIsRunning() && Scl_ConHasInArrs() )
|
||||
|
|
@ -297,6 +299,7 @@ Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, f
|
|||
pNode->pCopy = (Abc_Obj_t *)pNodeMap;
|
||||
if ( pSwitching )
|
||||
Map_NodeSetSwitching( pNodeMap, pSwitching[pNode->Id] );
|
||||
Map_NodeSetAigId( pNodeMap, pNode->Id );
|
||||
}
|
||||
|
||||
// load the AIG into the mapper
|
||||
|
|
@ -327,6 +330,7 @@ Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, f
|
|||
Map_NodeSetNextE( (Map_Node_t *)pPrev->pCopy, (Map_Node_t *)pFanin->pCopy );
|
||||
Map_NodeSetRepr( (Map_Node_t *)pFanin->pCopy, (Map_Node_t *)pNode->pCopy );
|
||||
}
|
||||
Map_NodeSetAigId( pNodeMap, pNode->Id );
|
||||
}
|
||||
assert( Map_ManReadBufNum(pMan) == pNtk->nBarBufs );
|
||||
Vec_PtrFree( vNodes );
|
||||
|
|
@ -419,6 +423,7 @@ Abc_Obj_t * Abc_NodeFromMapPhase_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap
|
|||
uPhaseBest = Map_CutReadPhaseBest( pCutBest, fPhase );
|
||||
nLeaves = Map_CutReadLeavesNum( pCutBest );
|
||||
ppLeaves = Map_CutReadLeaves( pCutBest );
|
||||
//Vec_Ptr_t * vAnds = Map_CutInternalNodes( pNodeMap, pCutBest );
|
||||
|
||||
// collect the PI nodes
|
||||
for ( i = 0; i < nLeaves; i++ )
|
||||
|
|
@ -430,6 +435,7 @@ Abc_Obj_t * Abc_NodeFromMapPhase_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap
|
|||
|
||||
// implement the supergate
|
||||
pNodeNew = Abc_NodeFromMapSuper_rec( pNtkNew, pNodeMap, pSuperBest, pNodePIs, nLeaves );
|
||||
Vec_IntWriteEntry( pNtkNew->vOrigNodeIds, pNodeNew->Id, Abc_Var2Lit( Map_NodeReadAigId(pNodeMap), fPhase ) );
|
||||
Map_NodeSetData( pNodeMap, fPhase, (char *)pNodeNew );
|
||||
return pNodeNew;
|
||||
}
|
||||
|
|
@ -461,6 +467,7 @@ Abc_Obj_t * Abc_NodeFromMap_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int
|
|||
|
||||
// add the inverter
|
||||
pNodeInv = Abc_NtkCreateNode( pNtkNew );
|
||||
Vec_IntWriteEntry( pNtkNew->vOrigNodeIds, pNodeInv->Id, Abc_Var2Lit( Map_NodeReadAigId(pNodeMap), fPhase ) );
|
||||
Abc_ObjAddFanin( pNodeInv, pNodeNew );
|
||||
pNodeInv->pData = Mio_LibraryReadInv((Mio_Library_t *)Abc_FrameReadLibGen());
|
||||
|
||||
|
|
@ -477,6 +484,7 @@ Abc_Ntk_t * Abc_NtkFromMap( Map_Man_t * pMan, Abc_Ntk_t * pNtk, int fUseBuffs )
|
|||
assert( Map_ManReadBufNum(pMan) == pNtk->nBarBufs );
|
||||
// create the new network
|
||||
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_MAP );
|
||||
pNtkNew->vOrigNodeIds = Vec_IntStartFull( 2 * Abc_NtkObjNumMax(pNtk) );
|
||||
// make the mapper point to the new network
|
||||
Map_ManCleanData( pMan );
|
||||
Abc_NtkForEachCi( pNtk, pNode, i )
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@ clkV = Abc_Clock() - clkV;
|
|||
int nZeros = Vec_IntCountZero( vPiValues );
|
||||
printf( "Parameters: " );
|
||||
Abc_NtkVectorPrintPars( vPiValues, nPars );
|
||||
printf( " Statistics: 0=%d 1=%d\n", nZeros, Vec_IntSize(vPiValues) - nZeros );
|
||||
printf( " Statistics: 0=%d 1=%d\n", nZeros, nPars - nZeros );
|
||||
printf( "Solved after %d iterations. ", nIters );
|
||||
}
|
||||
else if ( nIters == nItersMax )
|
||||
|
|
|
|||
|
|
@ -558,6 +558,44 @@ void Abc_ManResubPrintDivs( Abc_ManRes_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vLe
|
|||
printf( "\n" );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Dumps one resub instance.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_ManResubDumpInstance( Vec_Ptr_t * vDivs, int nLeaves, int nDivs, int nWords )
|
||||
{
|
||||
Abc_Obj_t * pRoot = (Abc_Obj_t *)Vec_PtrEntryLast(vDivs);
|
||||
char pFileName[1000];
|
||||
sprintf( pFileName, "%s_%05d.pla", pRoot->pNtk->pName, pRoot->Id );
|
||||
FILE * pFile = fopen( pFileName, "wb" );
|
||||
if ( pFile == NULL ) {
|
||||
printf( "Cannot open file \"%s\" for writing.\n", pFileName );
|
||||
return;
|
||||
}
|
||||
fprintf( pFile, "// Resub instance generated for node %d in network \"%s\" on %s\n", pRoot->Id, pRoot->pNtk->pName, Extra_TimeStamp() );
|
||||
fprintf( pFile, ".i %d\n", nDivs );
|
||||
fprintf( pFile, ".o %d\n", 1 );
|
||||
fprintf( pFile, ".p %d\n", 1 << nLeaves );
|
||||
Abc_Obj_t * pObj; int i, n;
|
||||
for ( n = 0; n < (1 << nLeaves); n++ ) {
|
||||
Vec_PtrForEachEntryStop( Abc_Obj_t *, vDivs, pObj, i, nDivs ) {
|
||||
fprintf( pFile, "%d", Abc_InfoHasBit((unsigned *)pObj->pData, n) );
|
||||
if ( i == nLeaves-1 )
|
||||
fprintf( pFile, " " );
|
||||
}
|
||||
fprintf( pFile, " %d\n", Abc_InfoHasBit((unsigned *)pRoot->pData, n) );
|
||||
}
|
||||
fprintf( pFile, ".e\n" );
|
||||
fclose( pFile );
|
||||
printf( "Finished dumping file \"%s\" with %d divisors and %d patterns.\n", pFileName, nDivs, (1 << nLeaves) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
@ -1929,6 +1967,9 @@ p->timeRes1 += Abc_Clock() - clk;
|
|||
// get the one level divisors
|
||||
Abc_ManResubDivsS( p, Required );
|
||||
|
||||
// if ( Vec_PtrSize(vLeaves) >= 6 )
|
||||
// Abc_ManResubDumpInstance( p->vDivs, Vec_PtrSize(vLeaves), p->nDivs, p->nWords );
|
||||
|
||||
// consider one node
|
||||
if ( (pGraph = Abc_ManResubDivs1( p, Required )) )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ char * pLibStr2[25] = {
|
|||
};
|
||||
void Acb_IntallLibrary( int f2Ins )
|
||||
{
|
||||
extern Mio_Library_t * Mio_LibraryReadBuffer( char * pBuffer, int fExtendedFormat, st__table * tExcludeGate, int fVerbose );
|
||||
extern Mio_Library_t * Mio_LibraryReadBuffer( char * pBuffer, int fExtendedFormat, st__table * tExcludeGate, int nFaninLimit, int fVerbose );
|
||||
Mio_Library_t * pLib;
|
||||
int i;
|
||||
// create library string
|
||||
|
|
@ -169,7 +169,7 @@ void Acb_IntallLibrary( int f2Ins )
|
|||
Vec_StrAppend( vLibStr, ppLibStr[i] );
|
||||
Vec_StrPush( vLibStr, '\0' );
|
||||
// create library
|
||||
pLib = Mio_LibraryReadBuffer( Vec_StrArray(vLibStr), 0, NULL, 0 );
|
||||
pLib = Mio_LibraryReadBuffer( Vec_StrArray(vLibStr), 0, NULL, 0, 0 );
|
||||
Mio_LibrarySetName( pLib, Abc_UtilStrsav("iccad17.genlib") );
|
||||
Mio_UpdateGenlib( pLib );
|
||||
Vec_StrFree( vLibStr );
|
||||
|
|
|
|||
|
|
@ -436,7 +436,7 @@ int CmdCommandAbcrc( Abc_Frame_t * pAbc, int argc, char **argv )
|
|||
******************************************************************************/
|
||||
int CmdCommandHistory( Abc_Frame_t * pAbc, int argc, char **argv )
|
||||
{
|
||||
char * pName;
|
||||
char * pName, * pStr = NULL;
|
||||
int i, c;
|
||||
int nPrints = 20;
|
||||
Extra_UtilGetoptReset();
|
||||
|
|
@ -453,11 +453,19 @@ int CmdCommandHistory( Abc_Frame_t * pAbc, int argc, char **argv )
|
|||
if ( argc > globalUtilOptind + 1 )
|
||||
goto usage;
|
||||
// get the number from the command line
|
||||
if ( argc == globalUtilOptind + 1 )
|
||||
nPrints = atoi(argv[globalUtilOptind]);
|
||||
pStr = argc == globalUtilOptind+1 ? argv[globalUtilOptind] : NULL;
|
||||
if ( pStr && pStr[0] >= '1' && pStr[0] <= '9' )
|
||||
nPrints = atoi(pStr), pStr = NULL;
|
||||
// print the commands
|
||||
Vec_PtrForEachEntryStart( char *, pAbc->aHistory, pName, i, Abc_MaxInt(0, Vec_PtrSize(pAbc->aHistory)-nPrints) )
|
||||
fprintf( pAbc->Out, "%2d : %s\n", Vec_PtrSize(pAbc->aHistory)-i, pName );
|
||||
if ( pStr == NULL ) {
|
||||
Vec_PtrForEachEntryStart( char *, pAbc->aHistory, pName, i, Abc_MaxInt(0, Vec_PtrSize(pAbc->aHistory)-nPrints) )
|
||||
fprintf( pAbc->Out, "%2d : %s\n", Vec_PtrSize(pAbc->aHistory)-i, pName );
|
||||
}
|
||||
else {
|
||||
Vec_PtrForEachEntry( char *, pAbc->aHistory, pName, i )
|
||||
if ( strstr(pName, pStr) )
|
||||
fprintf( pAbc->Out, "%2d : %s\n", Vec_PtrSize(pAbc->aHistory)-i, pName );
|
||||
}
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
|
|
|
|||
|
|
@ -49,8 +49,8 @@ ABC_NAMESPACE_IMPL_START
|
|||
***********************************************************************/
|
||||
void Cmd_HistoryAddCommand( Abc_Frame_t * p, const char * command )
|
||||
{
|
||||
int nLastLooked = 10; // do not add history if the same entry appears among the last entries
|
||||
int nLastSaved = 1000; // when saving a file, save no more than this number of last entries
|
||||
int nLastLooked = 10; // do not add history if the same entry appears among the last entries
|
||||
int nLastSaved = 10000; // when saving a file, save no more than this number of last entries
|
||||
char Buffer[ABC_MAX_STR];
|
||||
int Len;
|
||||
if ( p->fBatchMode )
|
||||
|
|
|
|||
|
|
@ -54,38 +54,34 @@ ABC_NAMESPACE_HEADER_START
|
|||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// the number of bits per integer (can be 16, 32, 64 - tested for 32)
|
||||
#define BPI 32
|
||||
#define BPIMASK 31
|
||||
#define LOGBPI 5
|
||||
enum {
|
||||
// the number of bits per integer
|
||||
BPI = 32,
|
||||
BPIMASK = 31,
|
||||
LOGBPI = 5,
|
||||
|
||||
// the maximum number of input variables
|
||||
#define MAXVARS 1000
|
||||
// the maximum number of input variables
|
||||
MAXVARS = 1000,
|
||||
|
||||
// the number of cubes that are allocated additionally
|
||||
#define ADDITIONAL_CUBES 33
|
||||
// the number of cubes that are allocated additionally
|
||||
ADDITIONAL_CUBES = 33,
|
||||
|
||||
// the factor showing how many cube pairs will be allocated
|
||||
#define CUBE_PAIR_FACTOR 20
|
||||
// the following number of cube pairs are allocated:
|
||||
// nCubesAlloc/CUBE_PAIR_FACTOR
|
||||
// the factor showing how many cube pairs will be allocated
|
||||
CUBE_PAIR_FACTOR = 20,
|
||||
// the following number of cube pairs are allocated:
|
||||
// nCubesAlloc/CUBE_PAIR_FACTOR
|
||||
|
||||
#if BPI == 64
|
||||
#define DIFFERENT 0x5555555555555555
|
||||
#define BIT_COUNT(w) (BitCount[(w)&0xffff] + BitCount[((w)>>16)&0xffff] + BitCount[((w)>>32)&0xffff] + BitCount[(w)>>48])
|
||||
#elif BPI == 32
|
||||
#define DIFFERENT 0x55555555
|
||||
#define BIT_COUNT(w) (BitCount[(w)&0xffff] + BitCount[(w)>>16])
|
||||
#else
|
||||
#define DIFFERENT 0x5555
|
||||
#define BIT_COUNT(w) (BitCount[(w)])
|
||||
#endif
|
||||
DIFFERENT = 0x55555555,
|
||||
};
|
||||
|
||||
extern unsigned char BitCount[];
|
||||
|
||||
#define VarWord(element) ((element)>>LOGBPI)
|
||||
#define VarBit(element) ((element)&BPIMASK)
|
||||
static inline int BIT_COUNT(int w) { return BitCount[(w)&0xffff] + BitCount[(w)>>16]; }
|
||||
|
||||
#define TICKS_TO_SECONDS(time) ((float)(time)/(float)(CLOCKS_PER_SEC))
|
||||
static inline int VarWord(int element) { return element>>LOGBPI; }
|
||||
static inline int VarBit(int element) { return element&BPIMASK; }
|
||||
|
||||
static inline float TICKS_TO_SECONDS(abctime time) { return (float)time/(float)CLOCKS_PER_SEC; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// CUBE COVER and CUBE typedefs ///
|
||||
|
|
|
|||
|
|
@ -40,6 +40,11 @@
|
|||
|
||||
#include "exor.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# include <intrin.h>
|
||||
# define __builtin_popcount __popcnt
|
||||
#endif
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -80,18 +85,6 @@ void ExorVar( Cube * pC, int Var, varvalue Val );
|
|||
/// STATIC VARIABLES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// the bit count for the first 256 integer numbers
|
||||
static unsigned char BitCount8[256] = {
|
||||
0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
|
||||
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
|
||||
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
|
||||
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
|
||||
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
|
||||
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
|
||||
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
|
||||
3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8
|
||||
};
|
||||
|
||||
static int SparseNumbers[163] = {
|
||||
0,1,4,5,16,17,20,21,64,65,68,69,80,81,84,85,256,257,260,
|
||||
261,272,273,276,277,320,321,324,325,336,337,340,1024,1025,
|
||||
|
|
@ -158,7 +151,7 @@ void PrepareBitSetModule()
|
|||
nLimit = FULL16BITS;
|
||||
for ( i = 0; i < nLimit; i++ )
|
||||
{
|
||||
BitCount[i] = BitCount8[ i & 0xff ] + BitCount8[ i>>8 ];
|
||||
BitCount[i] = __builtin_popcount( i & 0xffff );
|
||||
BitGroupNumbers[i] = MARKNUMBER;
|
||||
}
|
||||
// prepare bit groups
|
||||
|
|
|
|||
|
|
@ -1387,7 +1387,15 @@ usage:
|
|||
fprintf( pAbc->Err, "\t-x : toggle reading Exclusive SOP rather than SOP [default = %s]\n", fSkipPrepro? "yes":"no" );
|
||||
fprintf( pAbc->Err, "\t-c : toggle network check after reading [default = %s]\n", fCheck? "yes":"no" );
|
||||
fprintf( pAbc->Err, "\t-h : prints the command summary\n" );
|
||||
fprintf( pAbc->Err, "\tfile : the name of a file to read\n" );
|
||||
fprintf( pAbc->Err, "\tfile : the name of a file to read\n\n" );
|
||||
fprintf( pAbc->Err, "\t Please note that the PLA parser is somewhat slow for large SOPs.\n" );
|
||||
fprintf( pAbc->Err, "\t On the other hand, BLIF parser reads a 3M SOP and converts it into a 7.5K AIG in 1 sec:\n" );
|
||||
fprintf( pAbc->Err, "\t abc 16> read test.blif; ps; bdd -s; ps; muxes; strash; ps\n" );
|
||||
fprintf( pAbc->Err, "\t test : i/o = 25/ 1 lat = 0 nd = 1 edge = 25 cube = 2910537 lev = 1\n" );
|
||||
fprintf( pAbc->Err, "\t test : i/o = 25/ 1 lat = 0 nd = 1 edge = 25 bdd = 2937 lev = 1\n" );
|
||||
fprintf( pAbc->Err, "\t test : i/o = 25/ 1 lat = 0 and = 7514 lev = 48\n" );
|
||||
fprintf( pAbc->Err, "\t abc 19> time\n" );
|
||||
fprintf( pAbc->Err, "\t elapse: 1.05 seconds, total: 1.05 seconds\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ extern void Io_WriteBook( Abc_Ntk_t * pNtk, char * FileName );
|
|||
extern int Io_WriteCnf( Abc_Ntk_t * pNtk, char * FileName, int fAllPrimes );
|
||||
/*=== abcWriteDot.c ===========================================================*/
|
||||
extern void Io_WriteDot( Abc_Ntk_t * pNtk, char * FileName );
|
||||
extern void Io_WriteDotNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow, char * pFileName, int fGateNames, int fUseReverse );
|
||||
extern void Io_WriteDotNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow, char * pFileName, int fGateNames, int fUseReverse, int fAigIds );
|
||||
extern void Io_WriteDotSeq( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow, char * pFileName, int fGateNames, int fUseReverse );
|
||||
/*=== abcWriteEqn.c ===========================================================*/
|
||||
extern void Io_WriteEqn( Abc_Ntk_t * pNtk, char * pFileName );
|
||||
|
|
|
|||
|
|
@ -1411,14 +1411,14 @@ static int Io_MvParseLineSubckt( Io_MvMod_t * p, char * pLine )
|
|||
Last = k+Last+1;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
|
||||
if ( k == nEquals )
|
||||
{
|
||||
sprintf( p->pMan->sError, "Line %d: Cannot find PI \"%s\" of the model \"%s\" as a formal input of the subcircuit.",
|
||||
Io_MvGetLine(p->pMan, pToken), pName, Abc_NtkName(pModel) );
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
if ( pName2 == NULL )
|
||||
{
|
||||
Abc_Obj_t * pNode = Abc_NtkCreateNodeConst0( p->pNtk );
|
||||
|
|
|
|||
|
|
@ -0,0 +1,344 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [ioResub.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Command processing package.]
|
||||
|
||||
Synopsis [External declarations.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: ioResub.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef ABC__base__io__ioResub_h
|
||||
#define ABC__base__io__ioResub_h
|
||||
|
||||
|
||||
ABC_NAMESPACE_HEADER_START
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Abc_RData_t_ Abc_RData_t;
|
||||
struct Abc_RData_t_
|
||||
{
|
||||
int nIns; // the number of inputs
|
||||
int nOuts; // the number of outputs
|
||||
int nPats; // the number of patterns
|
||||
int nSimWords; // the number of words needed to store the patterns
|
||||
Vec_Wrd_t * vSimsIn; // input simulation signatures
|
||||
Vec_Wrd_t * vSimsOut; // output simulation signatures
|
||||
Vec_Int_t * vDivs; // divisors
|
||||
Vec_Int_t * vSol; // solution
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline int Abc_RDataGetIn ( Abc_RData_t * p, int i, int b ) { return Abc_InfoHasBit((unsigned *)Vec_WrdEntryP(p->vSimsIn, i*p->nSimWords), b); }
|
||||
static inline int Abc_RDataGetOut( Abc_RData_t * p, int i, int b ) { return Abc_InfoHasBit((unsigned *)Vec_WrdEntryP(p->vSimsOut, i*p->nSimWords), b); }
|
||||
|
||||
static inline void Abc_RDataSetIn ( Abc_RData_t * p, int i, int b ) { Abc_InfoSetBit((unsigned *)Vec_WrdEntryP(p->vSimsIn, i*p->nSimWords), b); }
|
||||
static inline void Abc_RDataSetOut( Abc_RData_t * p, int i, int b ) { Abc_InfoSetBit((unsigned *)Vec_WrdEntryP(p->vSimsOut, i*p->nSimWords), b); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern void Extra_BitMatrixTransposeP( Vec_Wrd_t * vSimsIn, int nWordsIn, Vec_Wrd_t * vSimsOut, int nWordsOut );
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [File interface to read/write resub data.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Abc_RData_t * Abc_RDataStart( int nIns, int nOuts, int nPats )
|
||||
{
|
||||
Abc_RData_t * p = ABC_CALLOC( Abc_RData_t, 1 );
|
||||
p->nIns = nIns;
|
||||
p->nOuts = nOuts;
|
||||
p->nPats = nPats;
|
||||
p->nSimWords = Abc_Bit6WordNum(nPats);
|
||||
p->vSimsIn = Vec_WrdStart( p->nIns * p->nSimWords );
|
||||
p->vSimsOut = Vec_WrdStart( 2*p->nOuts * p->nSimWords );
|
||||
p->vDivs = Vec_IntAlloc( 16 );
|
||||
p->vSol = Vec_IntAlloc( 16 );
|
||||
return p;
|
||||
}
|
||||
static inline void Abc_RDataStop( Abc_RData_t * p )
|
||||
{
|
||||
Vec_IntFree( p->vSol );
|
||||
Vec_IntFree( p->vDivs );
|
||||
Vec_WrdFree( p->vSimsIn );
|
||||
Vec_WrdFree( p->vSimsOut );
|
||||
ABC_FREE( p );
|
||||
}
|
||||
static inline int Abc_ReadPlaResubParams( char * pFileName, int * pnIns, int * pnOuts, int * pnPats )
|
||||
{
|
||||
FILE * pFile = fopen( pFileName, "rb" );
|
||||
if ( pFile == NULL ) {
|
||||
printf( "Cannot open file \"%s\" for reading.\n", pFileName );
|
||||
return 0;
|
||||
}
|
||||
int nLineSize = 1000000, iLine = 0;
|
||||
char * pBuffer = ABC_ALLOC( char, nLineSize );
|
||||
*pnIns = *pnOuts = *pnPats = 0;
|
||||
while ( fgets( pBuffer, nLineSize, pFile ) != NULL ) {
|
||||
iLine += (pBuffer[0] == '0' || pBuffer[0] == '1' || pBuffer[0] == '-');
|
||||
if ( pBuffer[0] != '.' )
|
||||
continue;
|
||||
if ( pBuffer[1] == 'i' )
|
||||
*pnIns = atoi(pBuffer+2);
|
||||
else if ( pBuffer[1] == 'o' )
|
||||
*pnOuts = atoi(pBuffer+2);
|
||||
else if ( pBuffer[1] == 'p' )
|
||||
*pnPats = atoi(pBuffer+2);
|
||||
else if ( pBuffer[1] == 'e' )
|
||||
break;
|
||||
}
|
||||
if ( *pnPats == 0 )
|
||||
*pnPats = iLine;
|
||||
else if ( *pnPats != iLine )
|
||||
printf( "The number of lines in the file (%d) does not match the number listed in .p (%d).\n", iLine, *pnPats );
|
||||
fclose(pFile);
|
||||
free( pBuffer );
|
||||
return 1;
|
||||
}
|
||||
static inline int Abc_ReadPlaResubData( Abc_RData_t * p, char * pFileName )
|
||||
{
|
||||
FILE * pFile = fopen( pFileName, "rb" );
|
||||
if ( pFile == NULL ) {
|
||||
printf( "Cannot open file \"%s\" for reading.\n", pFileName );
|
||||
return 0;
|
||||
}
|
||||
int i, iLine = 0, nDashes = 0, MaxLineSize = p->nIns+p->nOuts+10000;
|
||||
char * pTemp, * pBuffer = ABC_ALLOC( char, MaxLineSize );
|
||||
while ( fgets( pBuffer, MaxLineSize, pFile ) != NULL ) {
|
||||
if ( pBuffer[0] == '0' || pBuffer[0] == '1' || pBuffer[0] == '-' ) {
|
||||
for ( pTemp = pBuffer, i = 0; *pTemp; pTemp++ ) {
|
||||
if ( i < p->nIns ) { // input part
|
||||
nDashes += (*pTemp == '-');
|
||||
if ( *pTemp == '1' )
|
||||
Abc_InfoSetBit( (unsigned *)Vec_WrdEntryP(p->vSimsIn, i*p->nSimWords), iLine );
|
||||
}
|
||||
else { // output part
|
||||
if ( *pTemp == '0' )
|
||||
Abc_InfoSetBit( (unsigned *)Vec_WrdEntryP(p->vSimsOut, (2*(i-p->nIns)+0)*p->nSimWords), iLine );
|
||||
else if ( *pTemp == '1' )
|
||||
Abc_InfoSetBit( (unsigned *)Vec_WrdEntryP(p->vSimsOut, (2*(i-p->nIns)+1)*p->nSimWords), iLine );
|
||||
//else if ( *pTemp == '-' ) {
|
||||
// Abc_InfoSetBit( (unsigned *)Vec_WrdEntryP(p->vSimsOut, (2*(i-p->nIns)+0)*p->nSimWords), iLine );
|
||||
// Abc_InfoSetBit( (unsigned *)Vec_WrdEntryP(p->vSimsOut, (2*(i-p->nIns)+1)*p->nSimWords), iLine );
|
||||
//}
|
||||
}
|
||||
i += (*pTemp == '0' || *pTemp == '1' || *pTemp == '-');
|
||||
}
|
||||
assert( i == p->nIns + p->nOuts );
|
||||
iLine++;
|
||||
}
|
||||
if ( pBuffer[0] == '.' && (pBuffer[1] == 's' || pBuffer[1] == 'a') ) {
|
||||
Vec_Int_t * vArray = pBuffer[1] == 'a' ? p->vSol : p->vDivs;
|
||||
if ( Vec_IntSize(vArray) > 0 )
|
||||
continue;
|
||||
char * pTemp = strtok( pBuffer+2, " \r\n\t" );
|
||||
do Vec_IntPush( vArray, atoi(pTemp) );
|
||||
while ( (pTemp = strtok( NULL, " \r\n\t" )) );
|
||||
}
|
||||
}
|
||||
if ( nDashes )
|
||||
printf( "Several (%d) don't-care literals in the input part are replaced by zeros \"%s\" \n", nDashes, pFileName );
|
||||
assert ( iLine == p->nPats );
|
||||
ABC_FREE(pBuffer);
|
||||
fclose(pFile);
|
||||
return 1;
|
||||
}
|
||||
static inline Abc_RData_t * Abc_ReadPla( char * pFileName )
|
||||
{
|
||||
int nIns, nOuts, nPats;
|
||||
int RetValue = Abc_ReadPlaResubParams( pFileName, &nIns, &nOuts, &nPats );
|
||||
if ( !RetValue ) return NULL;
|
||||
Abc_RData_t * p = Abc_RDataStart( nIns, nOuts, nPats );
|
||||
RetValue = Abc_ReadPlaResubData( p, pFileName );
|
||||
return p;
|
||||
}
|
||||
static inline void Abc_WritePla( Abc_RData_t * p, char * pFileName, int fRel )
|
||||
{
|
||||
FILE * pFile = fopen( pFileName, "wb" ); int i, k;
|
||||
if ( pFile == NULL ) {
|
||||
printf( "Cannot open file \"%s\" for writing.\n", pFileName );
|
||||
return;
|
||||
}
|
||||
assert( fRel || Vec_WrdSize(p->vSimsOut) == 2*p->nOuts*p->nSimWords );
|
||||
assert( !fRel || Vec_WrdSize(p->vSimsOut) == (1 << p->nOuts)*p->nSimWords );
|
||||
fprintf( pFile, ".i %d\n", p->nIns );
|
||||
fprintf( pFile, ".o %d\n", p->nOuts );
|
||||
if ( fRel == 2 ) {
|
||||
int n, iLine = 0, Count = 0; word Entry;
|
||||
Vec_WrdForEachEntry( p->vSimsOut, Entry, i )
|
||||
Count += Abc_TtCountOnes(Entry);
|
||||
fprintf( pFile, ".p %d\n", Count );
|
||||
for ( i = 0; i < p->nPats; i++ )
|
||||
for ( n = 0; n < (1 << p->nOuts); n++ ) {
|
||||
if ( !Abc_InfoHasBit((unsigned *)Vec_WrdEntryP(p->vSimsOut, n*p->nSimWords), i) )
|
||||
continue;
|
||||
for ( k = 0; k < p->nIns; k++ )
|
||||
fprintf( pFile, "%d", Abc_InfoHasBit((unsigned *)Vec_WrdEntryP(p->vSimsIn, k*p->nSimWords), i) );
|
||||
fprintf( pFile, " ");
|
||||
for ( k = 0; k < p->nOuts; k++ )
|
||||
fprintf( pFile, "%d", (n >> k) & 1 );
|
||||
fprintf( pFile, "\n");
|
||||
iLine++;
|
||||
}
|
||||
assert( iLine == Count );
|
||||
}
|
||||
else {
|
||||
fprintf( pFile, ".p %d\n", p->nPats );
|
||||
for ( i = 0; i < p->nPats; i++ ) {
|
||||
for ( k = 0; k < p->nIns; k++ )
|
||||
fprintf( pFile, "%d", Abc_InfoHasBit((unsigned *)Vec_WrdEntryP(p->vSimsIn, k*p->nSimWords), i) );
|
||||
fprintf( pFile, " ");
|
||||
if ( !fRel ) { // multi-output function
|
||||
for ( k = 0; k < p->nOuts; k++ ) {
|
||||
int Val0 = Abc_InfoHasBit((unsigned *)Vec_WrdEntryP(p->vSimsOut, (2*k+0)*p->nSimWords), i);
|
||||
int Val1 = Abc_InfoHasBit((unsigned *)Vec_WrdEntryP(p->vSimsOut, (2*k+1)*p->nSimWords), i);
|
||||
char Val = (Val0 && Val1) ? '-' : Val1 ? '1' : '0';
|
||||
fprintf( pFile, "%c", Val );
|
||||
}
|
||||
}
|
||||
else { // relation
|
||||
for ( k = 0; k < (1 << p->nOuts); k++ )
|
||||
fprintf( pFile, "%d", Abc_InfoHasBit((unsigned *)Vec_WrdEntryP(p->vSimsOut, k*p->nSimWords), i) );
|
||||
}
|
||||
fprintf( pFile, "\n");
|
||||
}
|
||||
}
|
||||
fprintf( pFile, ".e\n" );
|
||||
fclose(pFile);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Abc_RDataIsRel( Abc_RData_t * p )
|
||||
{
|
||||
assert( p->nIns < 64 );
|
||||
Vec_Wrd_t * vTransIn = Vec_WrdStart( 64*p->nSimWords );
|
||||
Extra_BitMatrixTransposeP( p->vSimsIn, p->nSimWords, vTransIn, 64*p->nSimWords );
|
||||
Vec_WrdShrink( vTransIn, p->nPats );
|
||||
Vec_WrdUniqify( vTransIn );
|
||||
int Value = Vec_WrdSize(vTransIn) < p->nPats;
|
||||
Vec_WrdFree( vTransIn );
|
||||
return Value;
|
||||
}
|
||||
static inline Abc_RData_t * Abc_RData2Rel( Abc_RData_t * p )
|
||||
{
|
||||
assert( p->nIns < 64 );
|
||||
assert( p->nOuts < 32 );
|
||||
int w;
|
||||
Vec_Wrd_t * vSimsIn2 = Vec_WrdStart( 64*p->nSimWords );
|
||||
Vec_Wrd_t * vSimsOut2 = Vec_WrdStart( 64*p->nSimWords );
|
||||
for ( w = 0; w < p->nIns; w++ )
|
||||
Abc_TtCopy( Vec_WrdEntryP(vSimsIn2, w*p->nSimWords), Vec_WrdEntryP(p->vSimsIn, w*p->nSimWords), p->nSimWords, 0 );
|
||||
for ( w = 0; w < p->nOuts; w++ )
|
||||
Abc_TtCopy( Vec_WrdEntryP(vSimsOut2, w*p->nSimWords), Vec_WrdEntryP(p->vSimsOut, (2*w+1)*p->nSimWords), p->nSimWords, 0 );
|
||||
Vec_Wrd_t * vTransIn = Vec_WrdStart( 64*p->nSimWords );
|
||||
Vec_Wrd_t * vTransOut = Vec_WrdStart( 64*p->nSimWords );
|
||||
Extra_BitMatrixTransposeP( vSimsIn2, p->nSimWords, vTransIn, 1 );
|
||||
Extra_BitMatrixTransposeP( vSimsOut2, p->nSimWords, vTransOut, 1 );
|
||||
Vec_WrdShrink( vTransIn, p->nPats );
|
||||
Vec_WrdShrink( vTransOut, p->nPats );
|
||||
Vec_Wrd_t * vTransInCopy = Vec_WrdDup(vTransIn);
|
||||
Vec_WrdUniqify( vTransInCopy );
|
||||
if ( Vec_WrdSize(vTransInCopy) == p->nPats )
|
||||
printf( "This resub problem is not a relation.\n" );
|
||||
// create the relation
|
||||
Abc_RData_t * pNew = Abc_RDataStart( p->nIns, 1 << (p->nOuts-1), Vec_WrdSize(vTransInCopy) );
|
||||
pNew->nOuts = p->nOuts;
|
||||
int i, k, n, iLine = 0; word Entry, Entry2;
|
||||
Vec_WrdForEachEntry( vTransInCopy, Entry, i ) {
|
||||
for ( n = 0; n < p->nIns; n++ )
|
||||
if ( (Entry >> n) & 1 )
|
||||
Abc_InfoSetBit( (unsigned *)Vec_WrdEntryP(pNew->vSimsIn, n*pNew->nSimWords), iLine );
|
||||
Vec_WrdForEachEntry( vTransIn, Entry2, k ) {
|
||||
if ( Entry != Entry2 )
|
||||
continue;
|
||||
Entry2 = Vec_WrdEntry( vTransOut, k );
|
||||
assert( Entry2 < (1 << p->nOuts) );
|
||||
Abc_InfoSetBit( (unsigned *)Vec_WrdEntryP(pNew->vSimsOut, Entry2*pNew->nSimWords), iLine );
|
||||
}
|
||||
iLine++;
|
||||
}
|
||||
assert( iLine == pNew->nPats );
|
||||
Vec_WrdFree( vTransOut );
|
||||
Vec_WrdFree( vTransInCopy );
|
||||
Vec_WrdFree( vTransIn );
|
||||
Vec_WrdFree( vSimsIn2 );
|
||||
Vec_WrdFree( vSimsOut2 );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
/*
|
||||
void Abc_ReadPlaTest( char * pFileName )
|
||||
{
|
||||
Abc_RData_t * p = Abc_ReadPla( pFileName );
|
||||
Abc_WritePla( p, "resub_out.pla", 0 );
|
||||
Abc_RData_t * p2 = Abc_RData2Rel( p );
|
||||
Abc_WritePla( p2, "resub_out1.pla", 1 );
|
||||
Abc_WritePla( p2, "resub_out2.pla", 2 );
|
||||
Abc_RDataStop( p2 );
|
||||
Abc_RDataStop( p );
|
||||
}
|
||||
*/
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -52,7 +52,7 @@ void Io_WriteDot( Abc_Ntk_t * pNtk, char * FileName )
|
|||
{
|
||||
Vec_Ptr_t * vNodes;
|
||||
vNodes = Abc_NtkCollectObjects( pNtk );
|
||||
Io_WriteDotNtk( pNtk, vNodes, NULL, FileName, 0, 0 );
|
||||
Io_WriteDotNtk( pNtk, vNodes, NULL, FileName, 0, 0, 0 );
|
||||
Vec_PtrFree( vNodes );
|
||||
}
|
||||
|
||||
|
|
@ -68,12 +68,12 @@ void Io_WriteDot( Abc_Ntk_t * pNtk, char * FileName )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Io_WriteDotNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow, char * pFileName, int fGateNames, int fUseReverse )
|
||||
void Io_WriteDotNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow, char * pFileName, int fGateNames, int fUseReverse, int fAigIds )
|
||||
{
|
||||
FILE * pFile;
|
||||
Abc_Obj_t * pNode, * pFanin;
|
||||
char * pSopString;
|
||||
int LevelMin, LevelMax, fHasCos, Level, i, k, fHasBdds, fCompl, Prev;
|
||||
char * pSopString, SopString[32];
|
||||
int LevelMin, LevelMax, fHasCos, Level, i, k, fHasBdds, fCompl, Prev, AigNodeId;
|
||||
int Limit = 500;
|
||||
|
||||
assert( Abc_NtkIsStrash(pNtk) || Abc_NtkIsLogic(pNtk) );
|
||||
|
|
@ -302,9 +302,22 @@ void Io_WriteDotNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho
|
|||
pSopString = Mio_GateReadName((Mio_Gate_t *)pNode->pData);
|
||||
else if ( Abc_NtkHasMapping(pNtk) )
|
||||
pSopString = Abc_NtkPrintSop(Mio_GateReadSop((Mio_Gate_t *)pNode->pData));
|
||||
else
|
||||
pSopString = Abc_NtkPrintSop((char *)pNode->pData);
|
||||
fprintf( pFile, " Node%d [label = \"%d\\n%s\"", pNode->Id, pNode->Id, pSopString );
|
||||
else {
|
||||
int nCubes = Abc_SopGetCubeNum((char *)pNode->pData);
|
||||
if ( nCubes <= 16 )
|
||||
pSopString = Abc_NtkPrintSop((char *)pNode->pData);
|
||||
else {
|
||||
sprintf( SopString, "%d cubes", nCubes );
|
||||
pSopString = SopString;
|
||||
}
|
||||
}
|
||||
//if ( pNtk->vOrigNodeIds )
|
||||
// printf( "%d = %d \n", pNode->Id, Vec_IntEntry(pNtk->vOrigNodeIds, pNode->Id) )
|
||||
AigNodeId = (fAigIds && pNtk->vOrigNodeIds) ? Vec_IntEntry(pNtk->vOrigNodeIds, pNode->Id) : -1;
|
||||
if ( AigNodeId > 0 )
|
||||
fprintf( pFile, " Node%d [label = \"%s%d\\n%s\"", pNode->Id, Abc_LitIsCompl(AigNodeId) ? "-":"+", Abc_Lit2Var(AigNodeId), pSopString );
|
||||
else
|
||||
fprintf( pFile, " Node%d [label = \"%d\\n%s\"", pNode->Id, pNode->Id, pSopString );
|
||||
// fprintf( pFile, " Node%d [label = \"%d\\n%s\"", pNode->Id,
|
||||
// SuppSize,
|
||||
// pSopString );
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ extern ABC_DLL void Abc_FrameGiaInputMiniLut2( Abc_Frame_t * pAbc, void * pMin
|
|||
extern ABC_DLL void * Abc_FrameGiaOutputMiniLut( Abc_Frame_t * pAbc );
|
||||
extern ABC_DLL char * Abc_FrameGiaOutputMiniLutAttr( Abc_Frame_t * pAbc, void * pMiniLut );
|
||||
extern ABC_DLL int * Abc_FrameReadMiniLutSwitching( Abc_Frame_t * pAbc );
|
||||
extern ABC_DLL int * Abc_FrameReadMiniLutSwitching2( Abc_Frame_t * pAbc, int nRandPiFactor );
|
||||
extern ABC_DLL int * Abc_FrameReadMiniLutSwitchingPo( Abc_Frame_t * pAbc );
|
||||
|
||||
// procedures to input/output NDR data-structure
|
||||
|
|
|
|||
|
|
@ -678,7 +678,6 @@ 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, 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;
|
||||
Vec_Wec_t * vProds; int i;
|
||||
|
|
@ -694,8 +693,6 @@ Gia_Man_t * Wlc_ManGenProd( int nInputs, int fVerbose )
|
|||
|
||||
Gia_ManHashAlloc( pNew );
|
||||
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 );
|
||||
Gia_ManHashStop( pNew );
|
||||
Vec_WecFree( vProds );
|
||||
|
|
|
|||
|
|
@ -1886,8 +1886,8 @@ int Wlc_NtkAbsCore( Wlc_Ntk_t * p, Wlc_Par_t * pPars )
|
|||
Vec_IntFree( vRefine );
|
||||
Abc_CexFree( pCex );
|
||||
}
|
||||
Vec_IntFree( vBlacks );
|
||||
Vec_BitFree( vUnmark );
|
||||
Vec_IntFreeP( &vBlacks );
|
||||
Vec_BitFreeP( &vUnmark );
|
||||
// report the result
|
||||
if ( pPars->fVerbose )
|
||||
printf( "\n" );
|
||||
|
|
|
|||
|
|
@ -891,7 +891,7 @@ void Wlc_BlastReduceMatrix( Gia_Man_t * pNew, Vec_Wec_t * vProds, Vec_Wec_t * vL
|
|||
{
|
||||
Vec_Int_t * vLevel, * vProd;
|
||||
int i, NodeS, NodeC, LevelS, LevelC, Node1, Node2, Node3, Level1, Level2, Level3;
|
||||
int nSize = Vec_WecSize(vProds);
|
||||
int nSize = Vec_WecSize(vProds), nFAs = Vec_WecSize(vProds), nHAs = 0;
|
||||
assert( nSize == Vec_WecSize(vLevels) );
|
||||
for ( i = 0; i < nSize; i++ )
|
||||
{
|
||||
|
|
@ -911,6 +911,12 @@ void Wlc_BlastReduceMatrix( Gia_Man_t * pNew, Vec_Wec_t * vProds, Vec_Wec_t * vL
|
|||
Level2 = Vec_IntPop( vLevel );
|
||||
Level3 = Vec_IntPop( vLevel );
|
||||
|
||||
int nInputs = (Node1 > 1) + (Node2 > 1) + (Node3 > 1);
|
||||
if ( nInputs == 3 )
|
||||
nFAs++;
|
||||
else if ( nInputs == 2 )
|
||||
nHAs++;
|
||||
|
||||
Wlc_BlastFullAdder( pNew, Node1, Node2, Node3, &NodeC, &NodeS );
|
||||
LevelS = Abc_MaxInt( Abc_MaxInt(Level1, Level2), Level3 ) + 2;
|
||||
LevelC = LevelS - 1;
|
||||
|
|
@ -929,7 +935,7 @@ void Wlc_BlastReduceMatrix( Gia_Man_t * pNew, Vec_Wec_t * vProds, Vec_Wec_t * vL
|
|||
{
|
||||
vProd = Vec_WecEntry( vProds, i );
|
||||
while ( Vec_IntSize(vProd) < 2 )
|
||||
Vec_IntPush( vProd, 0 );
|
||||
Vec_IntPush( vProd, 0 ), nFAs--, nHAs++;
|
||||
assert( Vec_IntSize(vProd) == 2 );
|
||||
}
|
||||
// Vec_WecPrint( vProds, 0 );
|
||||
|
|
@ -950,6 +956,7 @@ void Wlc_BlastReduceMatrix( Gia_Man_t * pNew, Vec_Wec_t * vProds, Vec_Wec_t * vL
|
|||
Wlc_BlastAdderCLA( pNew, Vec_IntArray(vRes), Vec_IntArray(vLevel), Vec_IntSize(vRes), fSigned, 0 );
|
||||
else
|
||||
Wlc_BlastAdder( pNew, Vec_IntArray(vRes), Vec_IntArray(vLevel), Vec_IntSize(vRes), 0 );
|
||||
//printf( "Created %d-bit %d-input AT with %d FAs and %d HAs.\n", Vec_WecSize(vProds), Vec_WecSizeSize(vProds), nFAs, nHAs );
|
||||
}
|
||||
|
||||
int Wlc_BlastAddLevel( Gia_Man_t * pNew, int Start )
|
||||
|
|
@ -1049,7 +1056,6 @@ void Wlc_BlastReduceMatrix2( Gia_Man_t * pNew, Vec_Wec_t * vProds, Vec_Int_t * v
|
|||
Vec_IntFree( vTemp );
|
||||
}
|
||||
|
||||
|
||||
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 );
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ void Rtl_NtkBlastNode( Gia_Man_t * pNew, int Type, int nIns, Vec_Int_t * vDatas,
|
|||
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, 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_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 );
|
||||
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 );
|
||||
extern void Wlc_BlastDividerSigned( Gia_Man_t * pNew, int * pNum, int nNum, int * pDiv, int nDiv, int fQuo, Vec_Int_t * vRes, int fNonRest );
|
||||
|
|
@ -305,7 +305,7 @@ void Rtl_NtkBlastNode( Gia_Man_t * pNew, int Type, int nIns, Vec_Int_t * vDatas,
|
|||
if ( fBooth )
|
||||
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 );
|
||||
Wlc_BlastMultiplier3( pNew, Vec_IntArray(vArg0), Vec_IntArray(vArg1), Vec_IntSize(vArg0), Vec_IntSize(vArg1), vRes, fSigned, fCla, NULL, 0 );
|
||||
if ( nRange > Vec_IntSize(vRes) )
|
||||
Vec_IntFillExtra( vRes, nRange, fSigned ? Vec_IntEntryLast(vRes) : 0 );
|
||||
else
|
||||
|
|
|
|||
|
|
@ -460,18 +460,6 @@ void Experiment2( BFunc * pFunc )
|
|||
/// SINGLE OUTPUT FUNCTION ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// the bit count for the first 256 integer numbers
|
||||
//static unsigned char BitCount8[256] = {
|
||||
// 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
|
||||
// 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
|
||||
// 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
|
||||
// 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
|
||||
// 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
|
||||
// 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
|
||||
// 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
|
||||
// 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8
|
||||
//};
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
static int s_SuppSize[MAXOUTPUTS];
|
||||
int CompareSupports( int *ptrX, int *ptrY )
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ extern int Dsd_TreeCountPrimeNodesOne( Dsd_Node_t * pRoot );
|
|||
extern int Dsd_TreeCollectDecomposableVars( Dsd_Manager_t * dMan, int * pVars );
|
||||
extern Dsd_Node_t ** Dsd_TreeCollectNodesDfs( Dsd_Manager_t * dMan, int * pnNodes );
|
||||
extern Dsd_Node_t ** Dsd_TreeCollectNodesDfsOne( Dsd_Manager_t * pDsdMan, Dsd_Node_t * pNode, int * pnNodes );
|
||||
extern void Dsd_TreePrint( FILE * pFile, Dsd_Manager_t * dMan, char * pInputNames[], char * pOutputNames[], int fShortNames, int Output );
|
||||
extern void Dsd_TreePrint( FILE * pFile, Dsd_Manager_t * dMan, char * pInputNames[], char * pOutputNames[], int fShortNames, int Output, int OffSet );
|
||||
extern void Dsd_TreePrint2( FILE * pFile, Dsd_Manager_t * dMan, char * pInputNames[], char * pOutputNames[], int Output );
|
||||
extern void Dsd_NodePrint( FILE * pFile, Dsd_Node_t * pNode );
|
||||
/*=== dsdLocal.c =======================================================*/
|
||||
|
|
|
|||
|
|
@ -638,7 +638,7 @@ void Dsd_TreeCollectNodesDfs_rec( Dsd_Node_t * pNode, Dsd_Node_t * ppNodes[], in
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Dsd_TreePrint( FILE * pFile, Dsd_Manager_t * pDsdMan, char * pInputNames[], char * pOutputNames[], int fShortNames, int Output )
|
||||
void Dsd_TreePrint( FILE * pFile, Dsd_Manager_t * pDsdMan, char * pInputNames[], char * pOutputNames[], int fShortNames, int Output, int OffSet )
|
||||
{
|
||||
Dsd_Node_t * pNode;
|
||||
int SigCounter;
|
||||
|
|
@ -650,14 +650,14 @@ void Dsd_TreePrint( FILE * pFile, Dsd_Manager_t * pDsdMan, char * pInputNames[],
|
|||
for ( i = 0; i < pDsdMan->nRoots; i++ )
|
||||
{
|
||||
pNode = Dsd_Regular( pDsdMan->pRoots[i] );
|
||||
Dsd_TreePrint_rec( pFile, pNode, (pNode != pDsdMan->pRoots[i]), pInputNames, pOutputNames[i], 0, &SigCounter, fShortNames );
|
||||
Dsd_TreePrint_rec( pFile, pNode, (pNode != pDsdMan->pRoots[i]), pInputNames, pOutputNames[i], OffSet, &SigCounter, fShortNames );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( Output >= 0 && Output < pDsdMan->nRoots );
|
||||
pNode = Dsd_Regular( pDsdMan->pRoots[Output] );
|
||||
Dsd_TreePrint_rec( pFile, pNode, (pNode != pDsdMan->pRoots[Output]), pInputNames, pOutputNames[Output], 0, &SigCounter, fShortNames );
|
||||
Dsd_TreePrint_rec( pFile, pNode, (pNode != pDsdMan->pRoots[Output]), pInputNames, pOutputNames[Output], OffSet, &SigCounter, fShortNames );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -686,7 +686,7 @@ void Dsd_TreePrint_rec( FILE * pFile, Dsd_Node_t * pNode, int fComp, char * pInp
|
|||
if ( !fComp )
|
||||
fprintf( pFile, "%s = ", pOutputName );
|
||||
else
|
||||
fprintf( pFile, "NOT(%s) = ", pOutputName );
|
||||
fprintf( pFile, "~%s = ", pOutputName );
|
||||
pInputNums = ABC_ALLOC( int, pNode->nDecs );
|
||||
if ( pNode->Type == DSD_NODE_CONST1 )
|
||||
{
|
||||
|
|
@ -711,7 +711,7 @@ void Dsd_TreePrint_rec( FILE * pFile, Dsd_Node_t * pNode, int fComp, char * pInp
|
|||
if ( i )
|
||||
fprintf( pFile, "," );
|
||||
if ( fCompNew )
|
||||
fprintf( pFile, " NOT(" );
|
||||
fprintf( pFile, " ~" );
|
||||
else
|
||||
fprintf( pFile, " " );
|
||||
if ( pInput->Type == DSD_NODE_BUF )
|
||||
|
|
@ -727,8 +727,8 @@ void Dsd_TreePrint_rec( FILE * pFile, Dsd_Node_t * pNode, int fComp, char * pInp
|
|||
pInputNums[i] = (*pSigCounter)++;
|
||||
fprintf( pFile, "<%d>", pInputNums[i] );
|
||||
}
|
||||
if ( fCompNew )
|
||||
fprintf( pFile, ")" );
|
||||
//if ( fCompNew )
|
||||
// fprintf( pFile, "" );
|
||||
}
|
||||
fprintf( pFile, " )\n" );
|
||||
// call recursively for the following blocks
|
||||
|
|
@ -751,7 +751,7 @@ void Dsd_TreePrint_rec( FILE * pFile, Dsd_Node_t * pNode, int fComp, char * pInp
|
|||
if ( i )
|
||||
fprintf( pFile, "," );
|
||||
if ( fCompNew )
|
||||
fprintf( pFile, " NOT(" );
|
||||
fprintf( pFile, " ~" );
|
||||
else
|
||||
fprintf( pFile, " " );
|
||||
if ( pInput->Type == DSD_NODE_BUF )
|
||||
|
|
@ -767,8 +767,8 @@ void Dsd_TreePrint_rec( FILE * pFile, Dsd_Node_t * pNode, int fComp, char * pInp
|
|||
pInputNums[i] = (*pSigCounter)++;
|
||||
fprintf( pFile, "<%d>", pInputNums[i] );
|
||||
}
|
||||
if ( fCompNew )
|
||||
fprintf( pFile, ")" );
|
||||
//if ( fCompNew )
|
||||
// fprintf( pFile, "" );
|
||||
}
|
||||
fprintf( pFile, " )\n" );
|
||||
// call recursively for the following blocks
|
||||
|
|
@ -791,7 +791,7 @@ void Dsd_TreePrint_rec( FILE * pFile, Dsd_Node_t * pNode, int fComp, char * pInp
|
|||
if ( i )
|
||||
fprintf( pFile, "," );
|
||||
if ( fCompNew )
|
||||
fprintf( pFile, " NOT(" );
|
||||
fprintf( pFile, " ~" );
|
||||
else
|
||||
fprintf( pFile, " " );
|
||||
if ( pInput->Type == DSD_NODE_BUF )
|
||||
|
|
@ -807,8 +807,8 @@ void Dsd_TreePrint_rec( FILE * pFile, Dsd_Node_t * pNode, int fComp, char * pInp
|
|||
pInputNums[i] = (*pSigCounter)++;
|
||||
fprintf( pFile, "<%d>", pInputNums[i] );
|
||||
}
|
||||
if ( fCompNew )
|
||||
fprintf( pFile, ")" );
|
||||
//if ( fCompNew )
|
||||
// fprintf( pFile, "" );
|
||||
}
|
||||
fprintf( pFile, " )\n" );
|
||||
// call recursively for the following blocks
|
||||
|
|
@ -979,7 +979,7 @@ void Dsd_NodePrint_rec( FILE * pFile, Dsd_Node_t * pNode, int fComp, char * pOut
|
|||
if ( !fComp )
|
||||
fprintf( pFile, "%s = ", pOutputName );
|
||||
else
|
||||
fprintf( pFile, "NOT(%s) = ", pOutputName );
|
||||
fprintf( pFile, "~%s = ", pOutputName );
|
||||
pInputNums = ABC_ALLOC( int, pNode->nDecs );
|
||||
if ( pNode->Type == DSD_NODE_CONST1 )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [extraLutCas.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [extra]
|
||||
|
||||
Synopsis [LUT cascade decomposition.]
|
||||
|
||||
Description [LUT cascade decomposition.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - August 6, 2024.]
|
||||
|
||||
Revision [$Id: extraLutCas.h,v 1.00 2024/08/06 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef ABC__misc__extra__extra_lutcas_h
|
||||
#define ABC__misc__extra__extra_lutcas_h
|
||||
|
||||
#ifdef _WIN32
|
||||
#define inline __inline // compatible with MS VS 6.0
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "bdd/cudd/cuddInt.h"
|
||||
|
||||
ABC_NAMESPACE_HEADER_START
|
||||
|
||||
/*
|
||||
The decomposed structure of the LUT cascade is represented as an array of 64-bit integers (words).
|
||||
The first word in the record is the number of LUT info blocks in the record, which follow one by one.
|
||||
Each LUT info block contains the following:
|
||||
- the number of words in this block
|
||||
- the number of fanins
|
||||
- the list of fanins
|
||||
- the variable ID of the output (can be one of the fanin variables)
|
||||
- truth tables (one word for 6 vars or less; more words as needed for more than 6 vars)
|
||||
For a 6-input node, the LUT info block takes 10 words (block size, fanin count, 6 fanins, output ID, truth table).
|
||||
For a 4-input node, the LUT info block takes 8 words (block size, fanin count, 4 fanins, output ID, truth table).
|
||||
If the LUT cascade contains a 6-LUT followed by a 4-LUT, the record contains 1+10+8=19 words.
|
||||
*/
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline word * Abc_LutCascade( Mini_Aig_t * p, int nLutSize, int fVerbose )
|
||||
{
|
||||
word * pLuts = NULL;
|
||||
return pLuts;
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
||||
#endif /* __EXTRA_H__ */
|
||||
|
|
@ -40,6 +40,11 @@
|
|||
#include "kitty_operators.hpp"
|
||||
#include "kitty_static_tt.hpp"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# include <intrin.h>
|
||||
# define __builtin_popcount __popcnt
|
||||
#endif
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
namespace acd
|
||||
|
|
@ -459,7 +464,7 @@ private:
|
|||
if ( free_set_size == offset )
|
||||
{
|
||||
best_cost = fn( tt );
|
||||
return { tt, permutations, best_cost };
|
||||
return std::make_tuple( tt, permutations, best_cost );
|
||||
}
|
||||
|
||||
/* works up to 16 input truth tables */
|
||||
|
|
|
|||
|
|
@ -118,32 +118,25 @@ int acd2_decompose( word * pTruth, unsigned nVars, int lutSize, unsigned *pdelay
|
|||
return 0;
|
||||
}
|
||||
|
||||
inline int acd66_decompose( word * pTruth, unsigned nVars, unsigned char *decomposition )
|
||||
inline int acd66_evaluate( word * pTruth, unsigned nVars )
|
||||
{
|
||||
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 )
|
||||
int acdXX_evaluate( word * pTruth, unsigned lutSize, unsigned nVars )
|
||||
{
|
||||
using namespace acd;
|
||||
|
||||
if ( lutSize == 6 )
|
||||
{
|
||||
return acd66_decompose( pTruth, nVars, decomposition );
|
||||
return acd66_evaluate( pTruth, nVars );
|
||||
}
|
||||
|
||||
acdXX_params ps;
|
||||
|
|
@ -153,14 +146,29 @@ int acdXX_decompose( word * pTruth, unsigned lutSize, unsigned nVars, unsigned c
|
|||
|
||||
if ( acd.run( pTruth ) == 0 )
|
||||
return 0;
|
||||
if ( decomposition == NULL )
|
||||
return 1;
|
||||
int val = acd.compute_decomposition();
|
||||
if ( val != 0 )
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int acdXX_decompose( word * pTruth, unsigned lutSize, unsigned nVars, unsigned char *decomposition )
|
||||
{
|
||||
using namespace acd;
|
||||
|
||||
acdXX_params ps;
|
||||
ps.lut_size = lutSize;
|
||||
|
||||
for ( int i = 0; i <= lutSize - 2; ++i )
|
||||
{
|
||||
ps.max_shared_vars = i;
|
||||
ps.min_shared_vars = i;
|
||||
acdXX_impl acd( nVars, ps );
|
||||
|
||||
if ( acd.run( pTruth ) == 0 )
|
||||
continue;
|
||||
acd.compute_decomposition();
|
||||
acd.get_decomposition( decomposition );
|
||||
return 0;
|
||||
}
|
||||
acd.get_decomposition( decomposition );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ int acd_decompose( word * pTruth, unsigned nVars, int lutSize, unsigned *pdelay,
|
|||
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_evaluate( word * pTruth, unsigned lutSize, unsigned nVars );
|
||||
int acdXX_decompose( word * pTruth, unsigned lutSize, unsigned nVars, unsigned char *decomposition );
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
|
|
|||
|
|
@ -39,6 +39,11 @@
|
|||
#include "kitty_operators.hpp"
|
||||
#include "kitty_static_tt.hpp"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# include <intrin.h>
|
||||
# define __builtin_popcount __popcnt
|
||||
#endif
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
namespace acd
|
||||
|
|
|
|||
|
|
@ -39,6 +39,11 @@
|
|||
#include "kitty_operators.hpp"
|
||||
#include "kitty_static_tt.hpp"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# include <intrin.h>
|
||||
# define __builtin_popcount __popcnt
|
||||
#endif
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
namespace acd
|
||||
|
|
@ -52,6 +57,9 @@ struct acdXX_params
|
|||
/* Maximum number of variables in the shared set */
|
||||
uint32_t max_shared_vars{ 4 };
|
||||
|
||||
/* Minimum number of variables in the shared set */
|
||||
uint32_t min_shared_vars{ 0 };
|
||||
|
||||
/* Run verification */
|
||||
bool verify{ false };
|
||||
};
|
||||
|
|
@ -795,7 +803,7 @@ private:
|
|||
uint32_t max_shared_vars = std::min( ps.lut_size - best_free_set - 1, ps.max_shared_vars );
|
||||
|
||||
/* search for a feasible shared set */
|
||||
for ( uint32_t i = target_num_ss; i <= max_shared_vars; ++i )
|
||||
for ( uint32_t i = std::max( target_num_ss, ps.min_shared_vars ); i <= max_shared_vars; ++i )
|
||||
{
|
||||
for ( uint32_t i = 0; i < 6; ++i )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
#include <cassert>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <optional>
|
||||
#include <iostream>
|
||||
|
||||
#include "kitty_algorithm.hpp"
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
#include <cassert>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <optional>
|
||||
|
||||
#include "kitty_constants.hpp"
|
||||
#include "kitty_dynamic_tt.hpp"
|
||||
|
|
|
|||
|
|
@ -563,6 +563,8 @@ extern int If_CluCheckExt( void * p, word * pTruth, int nVars, int n
|
|||
char * pLut0, char * pLut1, word * pFunc0, word * pFunc1 );
|
||||
extern int If_CluCheckExt3( void * p, word * pTruth, int nVars, int nLutLeaf, int nLutLeaf2, int nLutRoot,
|
||||
char * pLut0, char * pLut1, char * pLut2, word * pFunc0, word * pFunc1, word * pFunc2 );
|
||||
extern int If_CluCheckXXExt( void * p, word * pTruth, int nVars, int nLutLeaf, int nLutRoot,
|
||||
char * pLut0, char * pLut1, word * pFunc0, word * pFunc1 );
|
||||
extern int If_MatchCheck1( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr );
|
||||
extern int If_MatchCheck2( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr );
|
||||
/*=== ifDelay.c =============================================================*/
|
||||
|
|
|
|||
|
|
@ -29,17 +29,6 @@ ABC_NAMESPACE_IMPL_START
|
|||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// the bit count for the first 256 integer numbers
|
||||
static int BitCount8[256] = {
|
||||
0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
|
||||
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
|
||||
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
|
||||
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
|
||||
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
|
||||
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
|
||||
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
|
||||
3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8
|
||||
};
|
||||
// variable swapping code
|
||||
static word PMasks[5][3] = {
|
||||
{ ABC_CONST(0x9999999999999999), ABC_CONST(0x2222222222222222), ABC_CONST(0x4444444444444444) },
|
||||
|
|
@ -208,7 +197,7 @@ static inline int If_Dec6CofCount2( word t )
|
|||
int i, Mask = 0;
|
||||
for ( i = 0; i < 16; i++ )
|
||||
Mask |= (1 << ((t >> (i<<2)) & 15));
|
||||
return BitCount8[((unsigned char*)&Mask)[0]] + BitCount8[((unsigned char*)&Mask)[1]];
|
||||
return __builtin_popcount( Mask & 0xffff );
|
||||
}
|
||||
// count the number of unique cofactors (up to 3)
|
||||
static inline int If_Dec7CofCount3( word t[2] )
|
||||
|
|
@ -696,7 +685,7 @@ static inline word If_Dec5CofCount2( word t, int x, int y, int * Pla2Var, word t
|
|||
for ( Mask = i = 0; i < 16; i++ )
|
||||
if ( ((i >> x) & 1) == ((m >> 0) & 1) && ((i >> y) & 1) == ((m >> 1) & 1) )
|
||||
Mask |= (1 << ((t >> (i<<1)) & 3));
|
||||
if ( BitCount8[Mask & 0xF] > 2 )
|
||||
if ( __builtin_popcount( Mask & 0xF ) > 2 )
|
||||
return 0;
|
||||
}
|
||||
// Kit_DsdPrintFromTruth( (unsigned *)&t, 5 ); printf( "\n" );
|
||||
|
|
@ -726,12 +715,12 @@ static inline word If_Dec5CofCount2( word t, int x, int y, int * Pla2Var, word t
|
|||
if ( ((i >> x) & 1) == ((m >> 0) & 1) && ((i >> y) & 1) == ((m >> 1) & 1) )
|
||||
Mask |= (1 << ((t >> (i<<1)) & 3));
|
||||
// find the values
|
||||
if ( BitCount8[Mask & 0xF] == 1 )
|
||||
if ( __builtin_popcount( Mask & 0xF ) == 1 )
|
||||
{
|
||||
C2[m] = F[Abc_Tt6FirstBit( Mask )];
|
||||
D2[m] = ~(word)0;
|
||||
}
|
||||
else if ( BitCount8[Mask & 0xF] == 2 )
|
||||
else if ( __builtin_popcount( Mask & 0xF ) == 2 )
|
||||
{
|
||||
int Bit0 = Abc_Tt6FirstBit( Mask );
|
||||
int Bit1 = Abc_Tt6FirstBit( Mask ^ (((word)1)<<Bit0) );
|
||||
|
|
|
|||
|
|
@ -22,6 +22,11 @@
|
|||
#include "misc/extra/extra.h"
|
||||
#include "bool/kit/kit.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# include <intrin.h>
|
||||
# define __builtin_popcount __popcnt
|
||||
#endif
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
|
|
@ -29,17 +34,6 @@ ABC_NAMESPACE_IMPL_START
|
|||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// the bit count for the first 256 integer numbers
|
||||
static int BitCount8[256] = {
|
||||
0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
|
||||
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
|
||||
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
|
||||
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
|
||||
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
|
||||
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
|
||||
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
|
||||
3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8
|
||||
};
|
||||
// variable swapping code
|
||||
static word PMasks[5][3] = {
|
||||
{ ABC_CONST(0x9999999999999999), ABC_CONST(0x2222222222222222), ABC_CONST(0x4444444444444444) },
|
||||
|
|
@ -374,7 +368,7 @@ void If_Dec08Cofactors( word * pF, int nVars, int iVar, word * pCof0, word * pCo
|
|||
static inline int If_Dec08Count16( int Num16 )
|
||||
{
|
||||
assert( Num16 < (1<<16)-1 );
|
||||
return BitCount8[Num16 & 255] + BitCount8[(Num16 >> 8) & 255];
|
||||
return __builtin_popcount( Num16 & 0xffff );
|
||||
}
|
||||
static inline void If_DecVerifyPerm( int Pla2Var[10], int Var2Pla[10], int nVars )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -22,6 +22,11 @@
|
|||
#include "misc/extra/extra.h"
|
||||
#include "bool/kit/kit.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# include <intrin.h>
|
||||
# define __builtin_popcount __popcnt
|
||||
#endif
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
|
|
@ -29,17 +34,6 @@ ABC_NAMESPACE_IMPL_START
|
|||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// the bit count for the first 256 integer numbers
|
||||
static int BitCount8[256] = {
|
||||
0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
|
||||
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
|
||||
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
|
||||
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
|
||||
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
|
||||
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
|
||||
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
|
||||
3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8
|
||||
};
|
||||
// variable swapping code
|
||||
static word PMasks[5][3] = {
|
||||
{ ABC_CONST(0x9999999999999999), ABC_CONST(0x2222222222222222), ABC_CONST(0x4444444444444444) },
|
||||
|
|
@ -371,7 +365,7 @@ void If_Dec10Cofactors( word * pF, int nVars, int iVar, word * pCof0, word * pCo
|
|||
static inline int If_Dec10Count16( int Num16 )
|
||||
{
|
||||
assert( Num16 < (1<<16)-1 );
|
||||
return BitCount8[Num16 & 255] + BitCount8[(Num16 >> 8) & 255];
|
||||
return __builtin_popcount( Num16 & 0xffff );
|
||||
}
|
||||
static inline void If_DecVerifyPerm( int Pla2Var[10], int Var2Pla[10], int nVars )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -104,6 +104,27 @@ static inline int If_CluWordNum2( int nVars )
|
|||
return nVars <= 6 ? 1 : 1 << (nVars-6);
|
||||
}
|
||||
|
||||
static inline word If_CluAdjust2( word t, int nVars )
|
||||
{
|
||||
assert( nVars >= 0 && nVars <= 6 );
|
||||
if ( nVars == 6 )
|
||||
return t;
|
||||
t &= (((word)1) << (1 << nVars)) - 1;
|
||||
if ( nVars == 0 )
|
||||
t |= t << (1<<nVars++);
|
||||
if ( nVars == 1 )
|
||||
t |= t << (1<<nVars++);
|
||||
if ( nVars == 2 )
|
||||
t |= t << (1<<nVars++);
|
||||
if ( nVars == 3 )
|
||||
t |= t << (1<<nVars++);
|
||||
if ( nVars == 4 )
|
||||
t |= t << (1<<nVars++);
|
||||
if ( nVars == 5 )
|
||||
t |= t << (1<<nVars++);
|
||||
return t;
|
||||
}
|
||||
|
||||
int If_CluHashFindMedian2( If_Man_t * p, int t )
|
||||
{
|
||||
If_Hte_t * pEntry;
|
||||
|
|
@ -267,7 +288,7 @@ int If_CluCheckXX( If_Man_t * p, word * pTruth0, int lutSize, int nVars, int fHa
|
|||
/* new entry */
|
||||
if ( G1.nVars == 0 )
|
||||
{
|
||||
G1.nVars = acdXX_decompose( pTruth0, lutSize, nVars, NULL );
|
||||
G1.nVars = acdXX_evaluate( pTruth0, lutSize, nVars );
|
||||
}
|
||||
|
||||
if ( pHashed )
|
||||
|
|
@ -276,6 +297,58 @@ int If_CluCheckXX( If_Man_t * p, word * pTruth0, int lutSize, int nVars, int fHa
|
|||
return G1.nVars;
|
||||
}
|
||||
|
||||
// returns the best group found
|
||||
int If_CluCheckXXExt( void * pMan, word * pTruth, int nVars, int nLutLeaf, int nLutRoot,
|
||||
char * pLut0, char * pLut1, word * pFunc0, word * pFunc1 )
|
||||
{
|
||||
(void)pMan;
|
||||
assert( nLutLeaf == nLutRoot );
|
||||
unsigned char result[32];
|
||||
int i;
|
||||
|
||||
if ( acdXX_decompose( pTruth, nLutRoot, nVars, result ) )
|
||||
{
|
||||
/* decomposition failed */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* copy LUT bound set */
|
||||
unsigned char * pResult = result + 2;
|
||||
int Lut1Size = (int) (*pResult++);
|
||||
pLut1[0] = Lut1Size;
|
||||
pLut1[1] = 0; /* not used */
|
||||
for (i = 0; i < Lut1Size; ++i)
|
||||
{
|
||||
pLut1[2+i] = *pResult++;
|
||||
}
|
||||
int func_num_bytes = ( Lut1Size <= 3 ) ? 1 : ( 1 << ( Lut1Size - 3 ) );
|
||||
*pFunc1 = 0;
|
||||
for (i = 0; i < func_num_bytes; ++i)
|
||||
{
|
||||
*pFunc1 |= ( ( (word) *pResult++ ) & 0xFF ) << 8*i;
|
||||
}
|
||||
|
||||
/* copy LUT composition */
|
||||
int Lut0Size = (int) (*pResult++);
|
||||
pLut0[0] = Lut0Size;
|
||||
pLut0[1] = 0; /* not used */
|
||||
for (i = 0; i < Lut0Size; ++i)
|
||||
{
|
||||
pLut0[2+i] = *pResult++;
|
||||
}
|
||||
func_num_bytes = ( Lut0Size <= 3 ) ? 1 : ( 1 << ( Lut0Size - 3 ) );
|
||||
*pFunc0 = 0;
|
||||
for (i = 0; i < func_num_bytes; ++i)
|
||||
{
|
||||
*pFunc0 |= ( ( (word) *pResult++ ) & 0xFF ) << 8*i;
|
||||
}
|
||||
|
||||
*pFunc1 = If_CluAdjust2( *pFunc1, Lut1Size );
|
||||
*pFunc0 = If_CluAdjust2( *pFunc0, Lut0Size );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs ACD into 66 cascade.]
|
||||
|
|
|
|||
|
|
@ -110,11 +110,13 @@ extern void Map_ManSetVerbose( Map_Man_t * p, int fVerbose );
|
|||
extern void Map_ManSetSwitching( Map_Man_t * p, int fSwitching );
|
||||
extern void Map_ManSetSkipFanout( Map_Man_t * p, int fSkipFanout );
|
||||
extern void Map_ManSetUseProfile( Map_Man_t * p );
|
||||
extern void Map_ManCreateAigIds( Map_Man_t * p, int nObjs );
|
||||
|
||||
extern Map_Man_t * Map_NodeReadMan( Map_Node_t * p );
|
||||
extern char * Map_NodeReadData( Map_Node_t * p, int fPhase );
|
||||
extern int Map_NodeReadNum( Map_Node_t * p );
|
||||
extern int Map_NodeReadLevel( Map_Node_t * p );
|
||||
extern int Map_NodeReadAigId( Map_Node_t * p );
|
||||
extern Map_Cut_t * Map_NodeReadCuts( Map_Node_t * p );
|
||||
extern Map_Cut_t * Map_NodeReadCutBest( Map_Node_t * p, int fPhase );
|
||||
extern Map_Node_t * Map_NodeReadOne( Map_Node_t * p );
|
||||
|
|
@ -123,6 +125,7 @@ extern void Map_NodeSetData( Map_Node_t * p, int fPhase, char * pData
|
|||
extern void Map_NodeSetNextE( Map_Node_t * p, Map_Node_t * pNextE );
|
||||
extern void Map_NodeSetRepr( Map_Node_t * p, Map_Node_t * pRepr );
|
||||
extern void Map_NodeSetSwitching( Map_Node_t * p, float Switching );
|
||||
extern void Map_NodeSetAigId( Map_Node_t * p, int Id );
|
||||
|
||||
extern int Map_NodeIsConst( Map_Node_t * p );
|
||||
extern int Map_NodeIsVar( Map_Node_t * p );
|
||||
|
|
@ -167,6 +170,7 @@ extern Map_Cut_t * Map_CutAlloc( Map_Man_t * p );
|
|||
/*=== mapperCutUtils.c =============================================================*/
|
||||
extern void Map_CutCreateFromNode( Map_Man_t * p, Map_Super_t * pSuper, int iRoot, unsigned uPhaseRoot,
|
||||
int * pLeaves, int nLeaves, unsigned uPhaseLeaves );
|
||||
extern Vec_Ptr_t * Map_CutInternalNodes( Map_Node_t * pObj, Map_Cut_t * pCut );
|
||||
/*=== mapperCore.c =============================================================*/
|
||||
extern int Map_Mapping( Map_Man_t * p );
|
||||
/*=== mapperLib.c =============================================================*/
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ void Map_ManSetVerbose( Map_Man_t * p, int fVerbose ) { p->
|
|||
void Map_ManSetSwitching( Map_Man_t * p, int fSwitching ) { p->fSwitching = fSwitching; }
|
||||
void Map_ManSetSkipFanout( Map_Man_t * p, int fSkipFanout ) { p->fSkipFanout = fSkipFanout; }
|
||||
void Map_ManSetUseProfile( Map_Man_t * p ) { p->fUseProfile = 1; }
|
||||
void Map_ManCreateAigIds( Map_Man_t * p, int nObjs ) { p->pAigNodeIDs = ABC_CALLOC( int, nObjs ); }
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
@ -91,6 +92,7 @@ Map_Man_t * Map_NodeReadMan( Map_Node_t * p ) { return p
|
|||
char * Map_NodeReadData( Map_Node_t * p, int fPhase ) { return fPhase? p->pData1 : p->pData0; }
|
||||
int Map_NodeReadNum( Map_Node_t * p ) { return p->Num; }
|
||||
int Map_NodeReadLevel( Map_Node_t * p ) { return Map_Regular(p)->Level; }
|
||||
int Map_NodeReadAigId( Map_Node_t * p ) { return p->p->pAigNodeIDs[p->Num]; }
|
||||
Map_Cut_t * Map_NodeReadCuts( Map_Node_t * p ) { return p->pCuts; }
|
||||
Map_Cut_t * Map_NodeReadCutBest( Map_Node_t * p, int fPhase ) { return p->pCutBest[fPhase]; }
|
||||
Map_Node_t * Map_NodeReadOne( Map_Node_t * p ) { return p->p1; }
|
||||
|
|
@ -99,6 +101,10 @@ void Map_NodeSetData( Map_Node_t * p, int fPhase, char * pData ) { if
|
|||
void Map_NodeSetNextE( Map_Node_t * p, Map_Node_t * pNextE ) { p->pNextE = pNextE; }
|
||||
void Map_NodeSetRepr( Map_Node_t * p, Map_Node_t * pRepr ) { p->pRepr = pRepr; }
|
||||
void Map_NodeSetSwitching( Map_Node_t * p, float Switching ) { p->Switching = Switching; }
|
||||
void Map_NodeSetAigId( Map_Node_t * p, int Id ) { p->p->pAigNodeIDs[p->Num] = Id; }
|
||||
|
||||
;
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
@ -261,6 +267,7 @@ void Map_ManFree( Map_Man_t * p )
|
|||
if ( p->pCounters ) ABC_FREE( p->pCounters );
|
||||
Extra_MmFixedStop( p->mmNodes );
|
||||
Extra_MmFixedStop( p->mmCuts );
|
||||
ABC_FREE( p->pAigNodeIDs );
|
||||
ABC_FREE( p->pNodeDelays );
|
||||
ABC_FREE( p->pInputArrivals );
|
||||
ABC_FREE( p->pOutputRequireds );
|
||||
|
|
|
|||
|
|
@ -219,6 +219,51 @@ int Map_CutListCount( Map_Cut_t * pSets )
|
|||
return i;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_CutInternalNodes_rec( Map_Node_t * pObj, Vec_Ptr_t * vAnds )
|
||||
{
|
||||
if ( pObj->TravId == pObj->p->nTravIds )
|
||||
return;
|
||||
pObj->TravId = pObj->p->nTravIds;
|
||||
Map_CutInternalNodes_rec( Map_Regular(pObj->p1), vAnds );
|
||||
Map_CutInternalNodes_rec( Map_Regular(pObj->p2), vAnds );
|
||||
Vec_PtrPush( vAnds, pObj );
|
||||
}
|
||||
Vec_Ptr_t * Map_CutInternalNodes( Map_Node_t * pObj, Map_Cut_t * pCut )
|
||||
{
|
||||
Vec_Ptr_t * vAnds = Vec_PtrAlloc( 4 );
|
||||
Map_Node_t * pTemp; int i;
|
||||
pObj->p->nTravIds++;
|
||||
for ( i = 0; i < pCut->nLeaves; i++ )
|
||||
pCut->ppLeaves[i]->TravId = pObj->p->nTravIds;
|
||||
Map_CutInternalNodes_rec( pObj, vAnds );
|
||||
if ( 0 )
|
||||
{
|
||||
printf( "Leaves:\n" );
|
||||
for ( i = 0; i < pCut->nLeaves; i++ )
|
||||
printf( " %d", pCut->ppLeaves[i]->Num );
|
||||
printf( "\n" );
|
||||
printf( "Nodes:\n" );
|
||||
Vec_PtrForEachEntry( Map_Node_t *, vAnds, pTemp, i )
|
||||
printf( "%d = %s%d & %s%d\n", pTemp->Num,
|
||||
Map_IsComplement(pTemp->p1) ? "~" : " ", Map_Regular(pTemp->p1)->Num,
|
||||
Map_IsComplement(pTemp->p2) ? "~" : " ", Map_Regular(pTemp->p2)->Num );
|
||||
printf( "\n" );
|
||||
}
|
||||
return vAnds;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
/**function*************************************************************
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@ struct Map_ManStruct_t_
|
|||
char ** ppOutputNames; // the primary output names
|
||||
Map_Time_t * pInputArrivals;// the PI arrival times
|
||||
Map_Time_t * pOutputRequireds;// the PI arrival times
|
||||
int * pAigNodeIDs; // IDs of the original AIG nodes
|
||||
|
||||
// mapping parameters
|
||||
int nVarsMax; // the max number of variables
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ int Map_LibraryReadFile( Map_SuperLib_t * pLib, FILE * pFile )
|
|||
fclose( pFileGen );
|
||||
|
||||
// read the genlib library
|
||||
pLib->pGenlib = Mio_LibraryRead( pLibName, NULL, 0, 0 );
|
||||
pLib->pGenlib = Mio_LibraryRead( pLibName, NULL, 0, 0, 0 );
|
||||
if ( pLib->pGenlib == NULL )
|
||||
{
|
||||
printf( "Cannot read genlib file \"%s\".\n", pLibName );
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ int Mio_UpdateGenlib2( Vec_Str_t * vStr, Vec_Str_t * vStr2, char * pFileName, in
|
|||
{
|
||||
Mio_Library_t * pLib;
|
||||
// set the new network
|
||||
pLib = Mio_LibraryRead( pFileName, Vec_StrArray(vStr), NULL, fVerbose );
|
||||
pLib = Mio_LibraryRead( pFileName, Vec_StrArray(vStr), NULL, 0, fVerbose );
|
||||
if ( pLib == NULL )
|
||||
return 0;
|
||||
|
||||
|
|
@ -291,12 +291,13 @@ int Mio_CommandReadGenlib( Abc_Frame_t * pAbc, int argc, char **argv )
|
|||
char * pExcludeFile = NULL;
|
||||
double WireDelay = 0.0;
|
||||
int fShortNames = 0;
|
||||
int nFaninLimit = 0;
|
||||
int c, fVerbose = 1;
|
||||
|
||||
pOut = Abc_FrameReadOut(pAbc);
|
||||
pErr = Abc_FrameReadErr(pAbc);
|
||||
Extra_UtilGetoptReset();
|
||||
while ( (c = Extra_UtilGetopt(argc, argv, "WEnvh")) != EOF )
|
||||
while ( (c = Extra_UtilGetopt(argc, argv, "WEKnvh")) != EOF )
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
|
|
@ -320,6 +321,15 @@ int Mio_CommandReadGenlib( Abc_Frame_t * pAbc, int argc, char **argv )
|
|||
pExcludeFile = argv[globalUtilOptind];
|
||||
globalUtilOptind++;
|
||||
break;
|
||||
case 'K':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-K\" should be followed by a file name.\n" );
|
||||
goto usage;
|
||||
}
|
||||
nFaninLimit = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
break;
|
||||
case 'n':
|
||||
fShortNames ^= 1;
|
||||
break;
|
||||
|
|
@ -351,7 +361,7 @@ int Mio_CommandReadGenlib( Abc_Frame_t * pAbc, int argc, char **argv )
|
|||
fclose( pFile );
|
||||
|
||||
// set the new network
|
||||
pLib = Mio_LibraryRead( pFileName, NULL, pExcludeFile, fVerbose );
|
||||
pLib = Mio_LibraryRead( pFileName, NULL, pExcludeFile, nFaninLimit, fVerbose );
|
||||
if ( pLib == NULL )
|
||||
{
|
||||
fprintf( pErr, "Reading genlib library has failed.\n" );
|
||||
|
|
@ -382,13 +392,14 @@ int Mio_CommandReadGenlib( Abc_Frame_t * pAbc, int argc, char **argv )
|
|||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pErr, "usage: read_genlib [-W float] [-E filename] [-nvh]\n");
|
||||
fprintf( pErr, "usage: read_genlib [-W float] [-E filename] [-K num] [-nvh]\n");
|
||||
fprintf( pErr, "\t read the library from a genlib file\n" );
|
||||
fprintf( pErr, "\t (if the library contains more than one gate\n" );
|
||||
fprintf( pErr, "\t with the same Boolean function, only the gate\n" );
|
||||
fprintf( pErr, "\t with the smallest area will be used)\n" );
|
||||
fprintf( pErr, "\t-W float : wire delay (added to pin-to-pin gate delays) [default = %g]\n", WireDelay );
|
||||
fprintf( pErr, "\t-E file : the file name with gates to be excluded [default = none]\n" );
|
||||
fprintf( pErr, "\t-E file : the file name with gates to be excluded [default = none]\n" );
|
||||
fprintf( pErr, "\t-K num : the max number of gate fanins (0 = no limit) [default = %d]\n", nFaninLimit );
|
||||
fprintf( pErr, "\t-n : toggle replacing gate/pin names by short strings [default = %s]\n", fShortNames? "yes": "no" );
|
||||
fprintf( pErr, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" );
|
||||
fprintf( pErr, "\t-h : enable verbose output\n");
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ extern double Mio_PinReadDelayBlockMax ( Mio_Pin_t * pPin );
|
|||
extern Mio_Pin_t * Mio_PinReadNext ( Mio_Pin_t * pPin );
|
||||
/*=== mioRead.c =============================================================*/
|
||||
extern char * Mio_ReadFile( char * FileName, int fAddEnd );
|
||||
extern Mio_Library_t * Mio_LibraryRead( char * FileName, char * pBuffer, char * ExcludeFile, int fVerbose );
|
||||
extern Mio_Library_t * Mio_LibraryRead( char * FileName, char * pBuffer, char * ExcludeFile, int nFaninLimit, int fVerbose );
|
||||
extern int Mio_LibraryReadExclude( char * ExcludeFile, st__table * tExcludeGate );
|
||||
/*=== mioFunc.c =============================================================*/
|
||||
extern int Mio_LibraryParseFormulas( Mio_Library_t * pLib );
|
||||
|
|
@ -230,8 +230,6 @@ extern void Mio_LibraryMatches2Fetch( Mio_Library_t * pLib, Vec_Ptr
|
|||
/*=== sclUtil.c =========================================================*/
|
||||
extern Mio_Library_t * Abc_SclDeriveGenlibSimple( void * pScl );
|
||||
extern Mio_Library_t * Abc_SclDeriveGenlib( void * pScl, void * pMio, float Slew, float Gain, int nGatesMin, int fVerbose );
|
||||
extern int Abc_SclHasDelayInfo( void * pScl );
|
||||
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
||||
|
|
|
|||
|
|
@ -31,9 +31,9 @@ ABC_NAMESPACE_IMPL_START
|
|||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static Mio_Library_t * Mio_LibraryReadOne( char * FileName, int fExtendedFormat, st__table * tExcludeGate, int fVerbose );
|
||||
Mio_Library_t * Mio_LibraryReadBuffer( char * pBuffer, int fExtendedFormat, st__table * tExcludeGate, int fVerbose );
|
||||
static int Mio_LibraryReadInternal( Mio_Library_t * pLib, char * pBuffer, int fExtendedFormat, st__table * tExcludeGate, int fVerbose );
|
||||
static Mio_Library_t * Mio_LibraryReadOne( char * FileName, int fExtendedFormat, st__table * tExcludeGate, int nFaninLimit, int fVerbose );
|
||||
Mio_Library_t * Mio_LibraryReadBuffer( char * pBuffer, int fExtendedFormat, st__table * tExcludeGate, int nFaninLimit, int fVerbose );
|
||||
static int Mio_LibraryReadInternal( Mio_Library_t * pLib, char * pBuffer, int fExtendedFormat, st__table * tExcludeGate, int nFaninLimit, int fVerbose );
|
||||
static Mio_Gate_t * Mio_LibraryReadGate( char ** ppToken, int fExtendedFormat );
|
||||
static Mio_Pin_t * Mio_LibraryReadPin( char ** ppToken, int fExtendedFormat );
|
||||
static char * chomp( char *s );
|
||||
|
|
@ -51,7 +51,7 @@ static void Io_ReadFileRemoveComments( char * pBuffer, int * pnDots,
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Mio_Library_t * Mio_LibraryRead( char * FileName, char * pBuffer, char * ExcludeFile, int fVerbose )
|
||||
Mio_Library_t * Mio_LibraryRead( char * FileName, char * pBuffer, char * ExcludeFile, int nFaninLimit, int fVerbose )
|
||||
{
|
||||
Mio_Library_t * pLib;
|
||||
int num;
|
||||
|
|
@ -73,20 +73,20 @@ Mio_Library_t * Mio_LibraryRead( char * FileName, char * pBuffer, char * Exclude
|
|||
|
||||
pBufferCopy = Abc_UtilStrsav(pBuffer);
|
||||
if ( pBuffer == NULL )
|
||||
pLib = Mio_LibraryReadOne( FileName, 0, tExcludeGate, fVerbose ); // try normal format first ..
|
||||
pLib = Mio_LibraryReadOne( FileName, 0, tExcludeGate, nFaninLimit, fVerbose ); // try normal format first ..
|
||||
else
|
||||
{
|
||||
pLib = Mio_LibraryReadBuffer( pBuffer, 0, tExcludeGate, fVerbose ); // try normal format first ..
|
||||
pLib = Mio_LibraryReadBuffer( pBuffer, 0, tExcludeGate, nFaninLimit, fVerbose ); // try normal format first ..
|
||||
if ( pLib )
|
||||
pLib->pName = Abc_UtilStrsav( Extra_FileNameGenericAppend(FileName, ".genlib") );
|
||||
}
|
||||
if ( pLib == NULL )
|
||||
{
|
||||
if ( pBuffer == NULL )
|
||||
pLib = Mio_LibraryReadOne( FileName, 1, tExcludeGate, fVerbose ); // try normal format first ..
|
||||
pLib = Mio_LibraryReadOne( FileName, 1, tExcludeGate, nFaninLimit, fVerbose ); // try normal format first ..
|
||||
else
|
||||
{
|
||||
pLib = Mio_LibraryReadBuffer( pBufferCopy, 1, tExcludeGate, fVerbose ); // try normal format first ..
|
||||
pLib = Mio_LibraryReadBuffer( pBufferCopy, 1, tExcludeGate, nFaninLimit, fVerbose ); // try normal format first ..
|
||||
if ( pLib )
|
||||
pLib->pName = Abc_UtilStrsav( Extra_FileNameGenericAppend(FileName, ".genlib") );
|
||||
}
|
||||
|
|
@ -152,7 +152,7 @@ char * Mio_ReadFile( char * FileName, int fAddEnd )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Mio_Library_t * Mio_LibraryReadBuffer( char * pBuffer, int fExtendedFormat, st__table * tExcludeGate, int fVerbose )
|
||||
Mio_Library_t * Mio_LibraryReadBuffer( char * pBuffer, int fExtendedFormat, st__table * tExcludeGate, int nFaninLimit, int fVerbose )
|
||||
{
|
||||
Mio_Library_t * pLib;
|
||||
|
||||
|
|
@ -165,7 +165,7 @@ Mio_Library_t * Mio_LibraryReadBuffer( char * pBuffer, int fExtendedFormat, st__
|
|||
Io_ReadFileRemoveComments( pBuffer, NULL, NULL );
|
||||
|
||||
// parse the contents of the file
|
||||
if ( Mio_LibraryReadInternal( pLib, pBuffer, fExtendedFormat, tExcludeGate, fVerbose ) )
|
||||
if ( Mio_LibraryReadInternal( pLib, pBuffer, fExtendedFormat, tExcludeGate, nFaninLimit, fVerbose ) )
|
||||
{
|
||||
Mio_LibraryDelete( pLib );
|
||||
return NULL;
|
||||
|
|
@ -196,7 +196,7 @@ Mio_Library_t * Mio_LibraryReadBuffer( char * pBuffer, int fExtendedFormat, st__
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Mio_Library_t * Mio_LibraryReadOne( char * FileName, int fExtendedFormat, st__table * tExcludeGate, int fVerbose )
|
||||
Mio_Library_t * Mio_LibraryReadOne( char * FileName, int fExtendedFormat, st__table * tExcludeGate, int nFaninLimit, int fVerbose )
|
||||
{
|
||||
Mio_Library_t * pLib;
|
||||
char * pBuffer;
|
||||
|
|
@ -207,7 +207,7 @@ Mio_Library_t * Mio_LibraryReadOne( char * FileName, int fExtendedFormat, st__ta
|
|||
pBuffer = Mio_ReadFile( FileName, 1 );
|
||||
if ( pBuffer == NULL )
|
||||
return NULL;
|
||||
pLib = Mio_LibraryReadBuffer( pBuffer, fExtendedFormat, tExcludeGate, fVerbose );
|
||||
pLib = Mio_LibraryReadBuffer( pBuffer, fExtendedFormat, tExcludeGate, nFaninLimit, fVerbose );
|
||||
ABC_FREE( pBuffer );
|
||||
if ( pLib )
|
||||
pLib->pName = Abc_UtilStrsav( FileName );
|
||||
|
|
@ -225,7 +225,7 @@ Mio_Library_t * Mio_LibraryReadOne( char * FileName, int fExtendedFormat, st__ta
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Mio_LibraryReadInternal( Mio_Library_t * pLib, char * pBuffer, int fExtendedFormat, st__table * tExcludeGate, int fVerbose )
|
||||
int Mio_LibraryReadInternal( Mio_Library_t * pLib, char * pBuffer, int fExtendedFormat, st__table * tExcludeGate, int nFaninLimit, int fVerbose )
|
||||
{
|
||||
Mio_Gate_t * pGate, ** ppGate;
|
||||
char * pToken;
|
||||
|
|
@ -262,6 +262,19 @@ int Mio_LibraryReadInternal( Mio_Library_t * pLib, char * pBuffer, int fExtended
|
|||
if ( pGate == NULL )
|
||||
return 1;
|
||||
|
||||
// consider the fanin limit
|
||||
if ( nFaninLimit )
|
||||
{
|
||||
Mio_Pin_t * pPin; int nIns = 0;
|
||||
for ( pPin = Mio_GateReadPins(pGate); pPin; pPin = Mio_PinReadNext(pPin) )
|
||||
nIns++;
|
||||
if ( nIns > nFaninLimit )
|
||||
{
|
||||
Mio_GateDelete( pGate );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// skip the gate if its formula has problems
|
||||
if ( !Mio_ParseCheckFormula(pGate, pGate->pForm) )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -846,7 +846,7 @@ Mio_Library_t * Abc_SclDeriveGenlibSimple( void * pScl )
|
|||
{
|
||||
SC_Lib * p = (SC_Lib *)pScl;
|
||||
Vec_Str_t * vStr = Abc_SclProduceGenlibStrSimple( p );
|
||||
Mio_Library_t * pLib = Mio_LibraryRead( p->pFileName, Vec_StrArray(vStr), NULL, 0 );
|
||||
Mio_Library_t * pLib = Mio_LibraryRead( p->pFileName, Vec_StrArray(vStr), NULL, 0, 0 );
|
||||
Vec_StrFree( vStr );
|
||||
if ( pLib )
|
||||
printf( "Derived GENLIB library \"%s\" with %d gates.\n", p->pName, SC_LibCellNum(p) );
|
||||
|
|
@ -1029,7 +1029,7 @@ Mio_Library_t * Abc_SclDeriveGenlib( void * pScl, void * pMio, float SlewInit, f
|
|||
vStr = Abc_SclProduceGenlibStr( p, Slew, Gain, nGatesMin, &nCellCount );
|
||||
else
|
||||
vStr = Abc_SclProduceGenlibStrProfile( p, (Mio_Library_t *)pMio, Slew, Gain, nGatesMin, &nCellCount );
|
||||
pLib = Mio_LibraryRead( p->pFileName, Vec_StrArray(vStr), NULL, 0 );
|
||||
pLib = Mio_LibraryRead( p->pFileName, Vec_StrArray(vStr), NULL, 0, 0 );
|
||||
Vec_StrFree( vStr );
|
||||
if ( !pLib )
|
||||
printf( "Reading library has filed.\n" );
|
||||
|
|
|
|||
|
|
@ -267,7 +267,7 @@ int Super_CommandSupergates( Abc_Frame_t * pAbc, int argc, char **argv )
|
|||
fclose( pFile );
|
||||
|
||||
// set the new network
|
||||
pLib = Mio_LibraryRead( FileName, NULL, ExcludeFile, fVerbose );
|
||||
pLib = Mio_LibraryRead( FileName, NULL, ExcludeFile, nVarsMax, fVerbose );
|
||||
if ( pLib == NULL )
|
||||
{
|
||||
fprintf( pErr, "Reading library has failed.\n" );
|
||||
|
|
|
|||
|
|
@ -549,6 +549,9 @@ extern int * Abc_QuickSortCost( int * pCosts, int nSize, int fDecrease );
|
|||
extern unsigned Abc_Random( int fReset );
|
||||
extern word Abc_RandomW( int fReset );
|
||||
|
||||
// pthreads
|
||||
extern void Util_ProcessThreads( int (*pUserFunc)(void *), void * vData, int nProcs, int TimeOut, int fVerbose );
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -4,5 +4,6 @@ SRC += src/misc/util/utilBridge.c \
|
|||
src/misc/util/utilFile.c \
|
||||
src/misc/util/utilIsop.c \
|
||||
src/misc/util/utilNam.c \
|
||||
src/misc/util/utilPth.c \
|
||||
src/misc/util/utilSignal.c \
|
||||
src/misc/util/utilSort.c
|
||||
|
|
|
|||
|
|
@ -0,0 +1,191 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [utilPth.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Generic interface to pthreads.]
|
||||
|
||||
Synopsis [Generic interface to pthreads.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - August 3, 2024.]
|
||||
|
||||
Revision [$Id: utilPth.c,v 1.00 2024/08/03 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef ABC_USE_PTHREADS
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "../lib/pthread.h"
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <atomic>
|
||||
using namespace std;
|
||||
#else
|
||||
#include <stdatomic.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#include "misc/vec/vec.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef ABC_USE_PTHREADS
|
||||
|
||||
void Util_ProcessThreads( int (*pUserFunc)(void *), void * vData, int nProcs, int TimeOut, int fVerbose )
|
||||
{
|
||||
void * pData; int i;
|
||||
Vec_PtrForEachEntry( void *, (Vec_Ptr_t *)vData, pData, i )
|
||||
pUserFunc( pData );
|
||||
}
|
||||
|
||||
#else // pthreads are used
|
||||
|
||||
#define PAR_THR_MAX 100
|
||||
typedef struct Util_ThData_t_
|
||||
{
|
||||
void * pUserData;
|
||||
int (*pUserFunc)(void *);
|
||||
int iThread;
|
||||
int nTimeOut;
|
||||
atomic_bool fWorking;
|
||||
} Util_ThData_t;
|
||||
|
||||
void * Util_Thread( void * pArg )
|
||||
{
|
||||
struct timespec pause_duration;
|
||||
pause_duration.tv_sec = 0;
|
||||
pause_duration.tv_nsec = 10000000L; // 10 milliseconds
|
||||
|
||||
Util_ThData_t * pThData = (Util_ThData_t *)pArg;
|
||||
while ( 1 )
|
||||
{
|
||||
while ( !atomic_load_explicit((atomic_bool *)&pThData->fWorking, memory_order_acquire) )
|
||||
nanosleep(&pause_duration, NULL);
|
||||
if ( pThData->pUserData == NULL )
|
||||
{
|
||||
pthread_exit( NULL );
|
||||
assert( 0 );
|
||||
return NULL;
|
||||
}
|
||||
pThData->pUserFunc( pThData->pUserData );
|
||||
atomic_store_explicit(&pThData->fWorking, 0, memory_order_release);
|
||||
}
|
||||
assert( 0 );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Util_ProcessThreads( int (*pUserFunc)(void *), void * vData, int nProcs, int TimeOut, int fVerbose )
|
||||
{
|
||||
//abctime clkStart = Abc_Clock();
|
||||
Util_ThData_t ThData[PAR_THR_MAX];
|
||||
pthread_t WorkerThread[PAR_THR_MAX];
|
||||
Vec_Ptr_t * vStack = NULL;
|
||||
int i, status;
|
||||
fflush( stdout );
|
||||
if ( nProcs <= 2 ) {
|
||||
void * pData; int i;
|
||||
Vec_PtrForEachEntry( void *, (Vec_Ptr_t *)vData, pData, i )
|
||||
pUserFunc( pData );
|
||||
return;
|
||||
}
|
||||
// subtract manager thread
|
||||
nProcs--;
|
||||
assert( nProcs >= 1 && nProcs <= PAR_THR_MAX );
|
||||
// start threads
|
||||
for ( i = 0; i < nProcs; i++ )
|
||||
{
|
||||
ThData[i].pUserData = NULL;
|
||||
ThData[i].pUserFunc = pUserFunc;
|
||||
ThData[i].iThread = i;
|
||||
ThData[i].nTimeOut = TimeOut;
|
||||
atomic_store_explicit(&ThData[i].fWorking, 0, memory_order_release);
|
||||
status = pthread_create( WorkerThread + i, NULL, Util_Thread, (void *)(ThData + i) ); assert( status == 0 );
|
||||
}
|
||||
|
||||
struct timespec pause_duration;
|
||||
pause_duration.tv_sec = 0;
|
||||
pause_duration.tv_nsec = 10000000L; // 10 milliseconds
|
||||
|
||||
// look at the threads
|
||||
vStack = Vec_PtrDup( (Vec_Ptr_t *)vData );
|
||||
while ( Vec_PtrSize(vStack) > 0 )
|
||||
{
|
||||
for ( i = 0; i < nProcs; i++ )
|
||||
{
|
||||
if ( atomic_load_explicit(&ThData[i].fWorking, memory_order_acquire) )
|
||||
continue;
|
||||
ThData[i].pUserData = Vec_PtrPop( vStack );
|
||||
atomic_store_explicit(&ThData[i].fWorking, 1, memory_order_release);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Vec_PtrFree( vStack );
|
||||
|
||||
// wait till threads finish
|
||||
for ( i = 0; i < nProcs; i++ )
|
||||
{
|
||||
if ( atomic_load_explicit(&ThData[i].fWorking, memory_order_acquire) )
|
||||
i = -1; // Start from the beginning again
|
||||
nanosleep(&pause_duration, NULL);
|
||||
}
|
||||
|
||||
// stop threads
|
||||
for ( i = 0; i < nProcs; i++ )
|
||||
{
|
||||
ThData[i].pUserData = NULL;
|
||||
atomic_store_explicit(&ThData[i].fWorking, 1, memory_order_release);
|
||||
}
|
||||
|
||||
// Join threads
|
||||
for ( i = 0; i < nProcs; i++ )
|
||||
pthread_join( WorkerThread[i], NULL );
|
||||
|
||||
//if ( fVerbose )
|
||||
// Abc_PrintTime( 1, "Time", Abc_Clock() - clkStart );
|
||||
}
|
||||
|
||||
#endif // pthreads are used
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
@ -1003,8 +1003,13 @@ void Abc_QuickSortTest()
|
|||
|
||||
unsigned Abc_Random( int fReset )
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
static unsigned int m_z = NUMBER1;
|
||||
static unsigned int m_w = NUMBER2;
|
||||
#else
|
||||
static __thread unsigned int m_z = NUMBER1;
|
||||
static __thread unsigned int m_w = NUMBER2;
|
||||
#endif
|
||||
if ( fReset )
|
||||
{
|
||||
m_z = NUMBER1;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,11 @@
|
|||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# include <intrin.h>
|
||||
# define __builtin_popcount __popcnt
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -129,18 +134,7 @@ static word s_PPMasks[5][6][3] = {
|
|||
}
|
||||
};
|
||||
|
||||
// the bit count for the first 256 integer numbers
|
||||
static int Abc_TtBitCount8[256] = {
|
||||
0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
|
||||
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
|
||||
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
|
||||
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
|
||||
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
|
||||
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
|
||||
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
|
||||
3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8
|
||||
};
|
||||
static inline int Abc_TtBitCount16( int i ) { return Abc_TtBitCount8[i & 0xFF] + Abc_TtBitCount8[i >> 8]; }
|
||||
static inline int Abc_TtBitCount16( int i ) { return __builtin_popcount( i & 0xffff ); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
|
|
|
|||
|
|
@ -1368,6 +1368,27 @@ static inline void Vec_WrdDumpBool( char * pFileName, Vec_Wrd_t * p, int nWords,
|
|||
printf( "Written %d bits of simulation data for %d objects into file \"%s\".\n", nBits, Vec_WrdSize(p)/nWords, pFileName );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Vec_WrdPrintBin( Vec_Wrd_t * p, int nWords )
|
||||
{
|
||||
int i, k, nNodes = Vec_WrdSize(p) / nWords;
|
||||
assert( Vec_WrdSize(p) % nWords == 0 );
|
||||
printf( "The array contains %d bit-strings of %d bits:\n", nNodes, 64*nWords );
|
||||
for ( i = 0; i < nNodes; i++, printf("\n") )
|
||||
for ( k = 0; k < 64*nWords; k++ )
|
||||
printf( "%d", Abc_InfoHasBit((unsigned*)Vec_WrdEntryP(p, i*nWords), k) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -1396,6 +1417,7 @@ static inline void Vec_WrdPrintHex( Vec_Wrd_t * p, int nWords )
|
|||
{
|
||||
int i, nNodes = Vec_WrdSize(p) / nWords;
|
||||
assert( Vec_WrdSize(p) % nWords == 0 );
|
||||
printf( "The array contains %d bit-strings of %d bits:\n", nNodes, 64*nWords );
|
||||
for ( i = 0; i < nNodes; i++ )
|
||||
Vec_WrdDumpHexOne( stdout, Vec_WrdEntryP(p, i*nWords), nWords );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,11 @@
|
|||
#include "bool/lucky/lucky.h"
|
||||
#include <math.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# include <intrin.h>
|
||||
# define __builtin_popcount __popcnt
|
||||
#endif
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -380,7 +385,7 @@ static int Abc_TtScc6(word wTruth, int ck)
|
|||
if (!wTruth) return 0;
|
||||
for (i = 0; i < 64; i++)
|
||||
if (wTruth & (word)1 << i) {
|
||||
int ci = Abc_TtBitCount8[i] + ck;
|
||||
int ci = __builtin_popcount( i & 0xff ) + ck;
|
||||
sum += shiftFunc(ci);
|
||||
}
|
||||
return sum;
|
||||
|
|
@ -406,7 +411,7 @@ static inline void Abc_TtSccInCofs6(word wTruth, int nVars, int ck, int * pStore
|
|||
{
|
||||
if (wTruth & (word)1 << j)
|
||||
{
|
||||
int ci = Abc_TtBitCount8[i] + ck;
|
||||
int ci = __builtin_popcount( i & 0xff ) + ck;
|
||||
sum += shiftFunc(ci);
|
||||
}
|
||||
i++;
|
||||
|
|
|
|||
|
|
@ -800,6 +800,65 @@ void Dau_FunctionEnum( int nInputs, int nVars, int nNodeMax, int fUseTwo, int fR
|
|||
fflush(stdout);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Function enumeration.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Mem_t * Dau_CollectNpnFunctions( word * p, int nVars, int fVerbose )
|
||||
{
|
||||
abctime clkStart = Abc_Clock();
|
||||
Vec_Mem_t * vTtMem = Vec_MemAllocForTTSimple( nVars );
|
||||
int nWords = Abc_Truth6WordNum(nVars);
|
||||
word * pCopy = ABC_ALLOC( word, nWords );
|
||||
Abc_TtCopy( pCopy, p, nWords, p[0] & 1 );
|
||||
Vec_MemHashInsert( vTtMem, pCopy );
|
||||
int nPerms = Extra_Factorial( nVars );
|
||||
int nMints = 1 << nVars;
|
||||
int * pPerm = Extra_PermSchedule( nVars );
|
||||
int * pComp = Extra_GreyCodeSchedule( nVars );
|
||||
int m, i, k, nFuncs;
|
||||
for ( m = 0; m < nMints; m++ ) {
|
||||
Abc_TtFlip( pCopy, nWords, pComp[m] );
|
||||
if ( pCopy[0] & 1 ) {
|
||||
Abc_TtNot( pCopy, nWords );
|
||||
assert( (pCopy[0] & 1) == 0 );
|
||||
Vec_MemHashInsert( vTtMem, pCopy );
|
||||
Abc_TtNot( pCopy, nWords );
|
||||
}
|
||||
else
|
||||
Vec_MemHashInsert( vTtMem, pCopy );
|
||||
}
|
||||
assert( Abc_TtEqual(pCopy, Vec_MemReadEntry(vTtMem, 0), nWords) );
|
||||
nFuncs = Vec_MemEntryNum(vTtMem);
|
||||
if ( fVerbose )
|
||||
printf( "Collected %d NN functions and ", nFuncs ), fflush(stdout);
|
||||
for ( i = 0; i < nFuncs; i++ ) {
|
||||
Abc_TtCopy( pCopy, Vec_MemReadEntry(vTtMem, i), nWords, 0 );
|
||||
for ( k = 0; k < nPerms; k++ ) {
|
||||
Abc_TtSwapAdjacent( pCopy, nWords, pPerm[k] );
|
||||
assert( (pCopy[0] & 1) == 0 );
|
||||
Vec_MemHashInsert( vTtMem, pCopy );
|
||||
}
|
||||
assert( Abc_TtEqual(pCopy, Vec_MemReadEntry(vTtMem, i), nWords) );
|
||||
}
|
||||
ABC_FREE( pPerm );
|
||||
ABC_FREE( pComp );
|
||||
ABC_FREE( pCopy );
|
||||
nFuncs = Vec_MemEntryNum(vTtMem);
|
||||
if ( fVerbose )
|
||||
printf( "%d NPN functions. ", nFuncs ),
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clkStart ),
|
||||
fflush(stdout);
|
||||
return vTtMem;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -46,12 +46,12 @@ ABC_NAMESPACE_IMPL_START
|
|||
***********************************************************************/
|
||||
Abc_Ntk_t * Abc_NtkDecFromTruth( word * pTruth, int nVars, int nLutSize )
|
||||
{
|
||||
extern Abc_Ntk_t * Abc_NtkLutmin( Abc_Ntk_t * pNtk, int nLutSize, int fVerbose );
|
||||
extern Abc_Ntk_t * Abc_NtkLutmin( Abc_Ntk_t * pNtk, int nLutSize, int fReorder, int fVerbose );
|
||||
Vec_Int_t * vCover = Vec_IntAlloc( 1 << 16 );
|
||||
Abc_Ntk_t * pTemp = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 );
|
||||
char * pSopCover = Abc_SopCreateFromTruthIsop( (Mem_Flex_t *)pTemp->pManFunc, nVars, pTruth, vCover );
|
||||
Abc_Ntk_t * pNtk = Abc_NtkCreateWithNode( pSopCover );
|
||||
Abc_Ntk_t * pNew = Abc_NtkLutmin( pNtk, nLutSize, 0 );
|
||||
Abc_Ntk_t * pNew = Abc_NtkLutmin( pNtk, nLutSize, 1, 0 );
|
||||
Abc_NtkDelete( pTemp );
|
||||
Abc_NtkDelete( pNtk );
|
||||
Vec_IntFree( vCover );
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ struct Cec_ParFra_t_
|
|||
int iOutFail; // the failed output
|
||||
int fBMiterInfo; // printing BMiter information
|
||||
int nPO; // number of po in original design given a bmiter
|
||||
char * pDumpName; // file name to dump statistics
|
||||
};
|
||||
|
||||
// combinational equivalence checking parameters
|
||||
|
|
|
|||
|
|
@ -1269,6 +1269,171 @@ Gia_Man_t * Cec_ManLSCorrespondence( Gia_Man_t * pAig, Cec_ParCor_t * pPars )
|
|||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Wec_t * Gia_ManCreateRegSupps( Gia_Man_t * p, int fVerbose )
|
||||
{
|
||||
abctime clk = Abc_Clock();
|
||||
Gia_Obj_t * pObj; int i, Id;
|
||||
Vec_Wec_t * vSuppsR = Vec_WecStart( Gia_ManRegNum(p) );
|
||||
Vec_Wec_t * vSupps = Vec_WecStart( Gia_ManObjNum(p) );
|
||||
Gia_ManForEachRo( p, pObj, i )
|
||||
Vec_IntPush( Vec_WecEntry(vSupps, Gia_ObjId(p, pObj)), i );
|
||||
Gia_ManForEachAnd( p, pObj, Id )
|
||||
Vec_IntTwoMerge2( Vec_WecEntry(vSupps, Gia_ObjFaninId0(pObj, Id)),
|
||||
Vec_WecEntry(vSupps, Gia_ObjFaninId1(pObj, Id)),
|
||||
Vec_WecEntry(vSupps, Id) );
|
||||
Gia_ManForEachRi( p, pObj, i )
|
||||
Vec_IntAppend( Vec_WecEntry(vSuppsR, i), Vec_WecEntry(vSupps, Gia_ObjFaninId0p(p, pObj)) );
|
||||
Vec_WecFree( vSupps );
|
||||
if ( fVerbose )
|
||||
Abc_PrintTime( 1, "Support computation", Abc_Clock() - clk );
|
||||
return vSuppsR;
|
||||
}
|
||||
Vec_Int_t * Gia_ManFindStopFlops( Gia_Man_t * p, int nFlopIncFreq, int fVerbose )
|
||||
{
|
||||
Vec_Int_t * vRes = NULL, * vTemp; int i, k, Spot, Temp, nItems = 0;
|
||||
Vec_Wec_t * vSupps = Gia_ManCreateRegSupps( p, fVerbose );
|
||||
Vec_Int_t * vNexts = Vec_IntStartFull( Gia_ManRegNum(p) );
|
||||
Vec_Int_t * vAvail = Vec_IntStart( Gia_ManRegNum(p) );
|
||||
Vec_Int_t * vHeads = Vec_IntAlloc( 10 );
|
||||
Vec_WecForEachLevel( vSupps, vTemp, i ) {
|
||||
if ( Vec_IntSize(vTemp) > 2 )
|
||||
continue;
|
||||
if ( (Spot = Vec_IntFind(vTemp, i)) >= 0 )
|
||||
Vec_IntDrop( vTemp, Spot );
|
||||
if ( Vec_IntSize(vTemp) != 1 )
|
||||
continue;
|
||||
Vec_IntWriteEntry( vNexts, i, Vec_IntEntry(vTemp, 0) );
|
||||
Vec_IntWriteEntry( vAvail, Vec_IntEntry(vTemp, 0), 1 );
|
||||
}
|
||||
Vec_IntForEachEntry( vNexts, Spot, i )
|
||||
if ( Spot >= 0 && Vec_IntEntry(vAvail, i) == 0 )
|
||||
Vec_IntPush( vHeads, i );
|
||||
Vec_IntForEachEntry( vHeads, Spot, i ) {
|
||||
for ( k = 0, Temp = Spot; Vec_IntEntry(vNexts, Temp) >= 0; k++, Temp = Vec_IntEntry(vNexts, Temp) )
|
||||
;
|
||||
if ( k > 100 )
|
||||
{
|
||||
nItems++;
|
||||
if ( vRes == NULL )
|
||||
vRes = Vec_IntAlloc( 100 );
|
||||
for ( k = 0, Temp = Spot; Vec_IntEntry(vNexts, Temp) >= 0; k++, Temp = Vec_IntEntry(vNexts, Temp) )
|
||||
if ( k % nFlopIncFreq == 0 )
|
||||
Vec_IntPush( vRes, Temp );
|
||||
}
|
||||
while ( Vec_IntEntry(vNexts, Spot) >= 0 )
|
||||
{
|
||||
int Next = Vec_IntEntry(vNexts, Spot);
|
||||
Vec_IntWriteEntry( vNexts, Spot, -1 );
|
||||
Spot = Next;
|
||||
}
|
||||
}
|
||||
if ( fVerbose && vRes )
|
||||
printf( "Detected %d sequence%s containing %d flops.\n", nItems, nItems > 1 ? "s":"", Vec_IntSize(vRes) );
|
||||
Vec_IntFree( vNexts );
|
||||
Vec_IntFree( vAvail );
|
||||
Vec_IntFree( vHeads );
|
||||
Vec_WecFree( vSupps );
|
||||
return vRes;
|
||||
}
|
||||
Gia_Man_t * Gia_ManDupStopsAdd( Gia_Man_t * p, Vec_Int_t * vStops )
|
||||
{
|
||||
Gia_Man_t * pNew;
|
||||
Gia_Obj_t * pObj; int i, Stop;
|
||||
Vec_Int_t * vExtras = Vec_IntAlloc( Vec_IntSize(vStops) );
|
||||
pNew = Gia_ManStart( Gia_ManObjNum(p) );
|
||||
pNew->pName = Abc_UtilStrsav( p->pName );
|
||||
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
|
||||
Gia_ManFillValue( p );
|
||||
Gia_ManConst0(p)->Value = 0;
|
||||
Gia_ManForEachPi( p, pObj, i )
|
||||
pObj->Value = Gia_ManAppendCi(pNew);
|
||||
Vec_IntForEachEntry( vStops, Stop, i )
|
||||
Vec_IntPush( vExtras, Gia_ManAppendCi(pNew) );
|
||||
Gia_ManForEachRo( p, pObj, i )
|
||||
pObj->Value = Gia_ManAppendCi(pNew);
|
||||
Vec_IntForEachEntry( vStops, Stop, i )
|
||||
{
|
||||
int Lit = Gia_ManCi(p, Gia_ManPiNum(p)+Stop)->Value;
|
||||
Gia_ManCi(p, Gia_ManPiNum(p)+Stop)->Value = Vec_IntEntry(vExtras, i);
|
||||
Vec_IntWriteEntry( vExtras, i, Lit );
|
||||
}
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
Gia_ManForEachPo( p, pObj, i )
|
||||
Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
|
||||
Vec_IntForEachEntry( vExtras, Stop, i )
|
||||
Gia_ManAppendCo( pNew, Stop );
|
||||
Gia_ManForEachRi( p, pObj, i )
|
||||
Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
|
||||
Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
|
||||
Vec_IntFree( vExtras );
|
||||
return pNew;
|
||||
}
|
||||
void Gia_ManDupStopsRem_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
|
||||
{
|
||||
if ( ~pObj->Value )
|
||||
return;
|
||||
assert( Gia_ObjIsAnd(pObj) );
|
||||
Gia_ManDupStopsRem_rec( pNew, p, Gia_ObjFanin0(pObj) );
|
||||
Gia_ManDupStopsRem_rec( pNew, p, Gia_ObjFanin1(pObj) );
|
||||
pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
}
|
||||
Gia_Man_t * Gia_ManDupStopsRem( Gia_Man_t * p, Vec_Int_t * vStops )
|
||||
{
|
||||
Gia_Man_t * pNew;
|
||||
Gia_Obj_t * pObj; int i;
|
||||
pNew = Gia_ManStart( Gia_ManObjNum(p) );
|
||||
pNew->pName = Abc_UtilStrsav( p->pName );
|
||||
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
|
||||
Gia_ManFillValue( p );
|
||||
Gia_ManConst0(p)->Value = 0;
|
||||
Gia_ManForEachPi( p, pObj, i )
|
||||
if ( i < Gia_ManPiNum(p) - Vec_IntSize(vStops) )
|
||||
pObj->Value = Gia_ManAppendCi(pNew);
|
||||
Gia_ManForEachRo( p, pObj, i )
|
||||
pObj->Value = Gia_ManAppendCi(pNew);
|
||||
Gia_ManForEachPo( p, pObj, i )
|
||||
if ( i >= Gia_ManPoNum(p) - Vec_IntSize(vStops) )
|
||||
Gia_ManDupStopsRem_rec( pNew, p, Gia_ObjFanin0(pObj) );
|
||||
Gia_ManForEachPi( p, pObj, i )
|
||||
if ( i >= Gia_ManPiNum(p) - Vec_IntSize(vStops) )
|
||||
pObj->Value = Gia_ObjFanin0Copy( Gia_ManPo(p, i - Gia_ManPiNum(p) + Gia_ManPoNum(p)) );
|
||||
Gia_ManForEachPo( p, pObj, i )
|
||||
if ( i < Gia_ManPoNum(p) - Vec_IntSize(vStops) )
|
||||
Gia_ManDupStopsRem_rec( pNew, p, Gia_ObjFanin0(pObj) );
|
||||
Gia_ManForEachRi( p, pObj, i )
|
||||
Gia_ManDupStopsRem_rec( pNew, p, Gia_ObjFanin0(pObj) );
|
||||
Gia_ManForEachPo( p, pObj, i )
|
||||
if ( i < Gia_ManPoNum(p) - Vec_IntSize(vStops) )
|
||||
Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
|
||||
Gia_ManForEachRi( p, pObj, i )
|
||||
Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
|
||||
Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
|
||||
return pNew;
|
||||
}
|
||||
Gia_Man_t * Gia_ManDupStopsTest( Gia_Man_t * p )
|
||||
{
|
||||
Vec_Int_t * vStops = Gia_ManFindStopFlops( p, 1, 1 );
|
||||
if ( vStops == NULL )
|
||||
return Gia_ManDup(p);
|
||||
Gia_Man_t * pNew1 = Gia_ManDupStopsAdd( p, vStops );
|
||||
Gia_Man_t * pNew2 = Gia_ManDupStopsRem( pNew1, vStops );
|
||||
Gia_ManStop( pNew1 );
|
||||
Vec_IntFree( vStops );
|
||||
return pNew2;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -1783,6 +1783,48 @@ void Gia_ManRemoveWrongChoices( Gia_Man_t * p )
|
|||
//Abc_Print( 1, "Removed %d wrong choices.\n", Counter );
|
||||
}
|
||||
|
||||
void Cec4_ManSimulateDumpInfo( Cec4_Man_t * pMan )
|
||||
{
|
||||
Gia_Obj_t * pObj; int i, k, nWords = pMan->pAig->nSimWords, nOuts[2] = {0};
|
||||
Vec_Wrd_t * vSims = NULL, * vSimsPi = NULL;
|
||||
FILE * pFile = fopen( pMan->pPars->pDumpName, "wb" );
|
||||
if ( pFile == NULL ) {
|
||||
printf( "Cannot open file \"%s\" for writing primary output information.\n", pMan->pPars->pDumpName );
|
||||
return;
|
||||
}
|
||||
vSimsPi = Vec_WrdDup( pMan->pAig->vSimsPi );
|
||||
memmove( Vec_WrdArray(vSimsPi), Vec_WrdArray(vSimsPi) + nWords, Gia_ManCiNum(pMan->pAig) * nWords );
|
||||
Vec_WrdShrink( vSimsPi, Gia_ManCiNum(pMan->pAig) * nWords );
|
||||
if ( Abc_TtIsConst0(Vec_WrdArray(vSimsPi), Gia_ManCiNum(pMan->pAig) * nWords) ) {
|
||||
Vec_WrdFree( vSimsPi );
|
||||
vSimsPi = Vec_WrdStartRandom( Gia_ManCiNum(pMan->pAig) * nWords );
|
||||
}
|
||||
vSims = Gia_ManSimPatSimOut( pMan->pAig, vSimsPi, 1 );
|
||||
assert( nWords * Gia_ManCiNum(pMan->pAig) == Vec_WrdSize(vSimsPi) );
|
||||
Gia_ManForEachCo( pMan->pAig, pObj, i )
|
||||
{
|
||||
void Extra_PrintHex2( FILE * pFile, unsigned * pTruth, int nVars );
|
||||
word * pSims = Vec_WrdEntryP( vSims, nWords*i );
|
||||
//Extra_PrintHex2( stdout, (unsigned *)pSims, 8 ); printf( "\n" );
|
||||
fprintf( pFile, "%d ", i );
|
||||
if ( Gia_ObjFaninLit0p(pMan->pNew, Gia_ManCo(pMan->pNew, i)) == 0 )
|
||||
nOuts[0]++;
|
||||
else if ( Abc_TtIsConst0(pSims, nWords) )
|
||||
fprintf( pFile, "-" );
|
||||
else {
|
||||
int iPat = Abc_TtFindFirstBit2(pSims, nWords);
|
||||
for ( k = 0; k < Gia_ManPiNum(pMan->pAig); k++ )
|
||||
fprintf( pFile, "%d", Abc_TtGetBit(Vec_WrdEntryP(vSimsPi, nWords*k), iPat) );
|
||||
nOuts[1]++;
|
||||
}
|
||||
fprintf( pFile, "\n" );
|
||||
}
|
||||
printf( "Information about %d sat, %d unsat, and %d undecided primary outputs was written into file \"%s\".\n",
|
||||
nOuts[1], nOuts[0], Gia_ManCoNum(pMan->pAig)-nOuts[1]-nOuts[0], pMan->pPars->pDumpName );
|
||||
fclose( pFile );
|
||||
Vec_WrdFree( vSims );
|
||||
Vec_WrdFree( vSimsPi );
|
||||
}
|
||||
int Cec4_ManPerformSweeping( Gia_Man_t * p, Cec_ParFra_t * pPars, Gia_Man_t ** ppNew, int fSimOnly )
|
||||
{
|
||||
|
||||
|
|
@ -1954,6 +1996,8 @@ finalize:
|
|||
ABC_FREE( pBase );
|
||||
printf( "Dumped miter \"%s\" with %d pairs.\n", pFileName, pMan->vPairs ? Vec_IntSize(pMan->vPairs)/2 : -1 );
|
||||
}
|
||||
if ( pPars->pDumpName )
|
||||
Cec4_ManSimulateDumpInfo( pMan );
|
||||
Cec4_ManDestroy( pMan );
|
||||
//Gia_ManStaticFanoutStop( p );
|
||||
//Gia_ManEquivPrintClasses( p, 1, 0 );
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue