Merge remote-tracking branch 'upstream/master' into yosys-experimental

This commit is contained in:
Martin Povišer 2024-08-07 12:57:53 +02:00
commit bf64a92253
109 changed files with 6832 additions and 551 deletions

View File

@ -1,4 +1,8 @@
on: [push]
name: Build Posix CMake
on:
push:
pull_request:
jobs:

View File

@ -1,4 +1,8 @@
on: [push]
name: Build Posix
on:
push:
pull_request:
jobs:

View File

@ -1,4 +1,8 @@
on: [push]
name: Build Windows
on:
push:
pull_request:
jobs:

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

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

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

View File

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

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

478
src/aig/gia/giaMulFind.c Normal file
View File

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

View File

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

View File

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

View File

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

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

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

View 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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

344
src/base/io/ioResub.h Normal file
View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -6,7 +6,6 @@
#include <cassert>
#include <functional>
#include <iterator>
#include <optional>
#include <iostream>
#include "kitty_algorithm.hpp"

View File

@ -6,7 +6,6 @@
#include <cassert>
#include <functional>
#include <iterator>
#include <optional>
#include "kitty_constants.hpp"
#include "kitty_dynamic_tt.hpp"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

191
src/misc/util/utilPth.c Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View 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