Commit 8da52b6f by Alan Mishchenko

Version abc70202

parent 12578e62
......@@ -1697,6 +1697,18 @@ SOURCE=.\src\opt\res\resUpdate.c
SOURCE=.\src\opt\res\resWin.c
# End Source File
# End Group
# Begin Group "bdc"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\src\opt\bdc\bdc.h
# End Source File
# Begin Source File
SOURCE=.\src\opt\bdc\bdcInt.h
# End Source File
# End Group
# End Group
# Begin Group "map"
......
......@@ -102,6 +102,10 @@ alias src_rws "st; rw -l; rs -K 6 -N 2 -l; rwz -l; rs -K 9 -N 2 -l; rwz -l;
alias resyn2rs "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"
# experimental implementation of don't-cares
alias resyn2rsdc "b; rs -K 6 -F 2; rw; rs -K 6 -N 2 -F 2; rf; rs -K 8 -F 2; b; rs -K 8 -N 2 -F 2; rw; rs -K 10 -F 2; rwz; rs -K 10 -N 2 -F 2; b; rs -K 12 -F 2; rfz; rs -K 12 -N 2 -F 2; rwz; b"
alias compress2rsdc "b -l; rs -K 6 -F 2 -l; rw -l; rs -K 6 -N 2 -F 2 -l; rf -l; rs -K 8 -F 2 -l; b -l; rs -K 8 -N 2 -F 2 -l; rw -l; rs -K 10 -F 2 -l; rwz -l; rs -K 10 -N 2 -F 2 -l; b -l; rs -K 12 -F 2 -l; rfz -l; rs -K 12 -N 2 -F 2 -l; rwz -l; b -l"
# temporaries
#alias t "rvl th/lib.v; rvv th/t2.v"
#alias t "so c/pure_sat/test.c"
......
......@@ -152,6 +152,7 @@ struct Ivy_FraigParams_t_
typedef struct Ivy_Cut_t_ Ivy_Cut_t;
struct Ivy_Cut_t_
{
int nLatches;
short nSize;
short nSizeMax;
int pArray[IVY_CUT_INPUT];
......@@ -541,6 +542,7 @@ extern Ivy_Obj_t * Ivy_ObjRecognizeMux( Ivy_Obj_t * pObj, Ivy_Obj_t ** ppObj
extern Ivy_Obj_t * Ivy_ObjReal( Ivy_Obj_t * pObj );
extern void Ivy_ObjPrintVerbose( Ivy_Man_t * p, Ivy_Obj_t * pObj, int fHaig );
extern void Ivy_ManPrintVerbose( Ivy_Man_t * p, int fHaig );
extern int Ivy_CutTruthPrint( Ivy_Man_t * p, Ivy_Cut_t * pCut, unsigned uTruth );
#ifdef __cplusplus
}
......
......@@ -41,6 +41,11 @@ static inline int Ivy_CutHashValue( int NodeId ) { return 1 << (NodeId % 31); }
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
//int nMoves;
//int nMovesS;
//int nClauses;
//int timeInv;
/**Function*************************************************************
Synopsis [Performs incremental rewriting of the AIG.]
......@@ -58,6 +63,7 @@ int Ivy_ManRewriteSeq( Ivy_Man_t * p, int fUseZeroCost, int fVerbose )
Ivy_Obj_t * pNode;
int i, nNodes, nGain;
int clk, clkStart = clock();
// set the DC latch values
Ivy_ManForEachLatch( p, pNode, i )
pNode->Init = IVY_INIT_DC;
......@@ -81,7 +87,7 @@ int Ivy_ManRewriteSeq( Ivy_Man_t * p, int fUseZeroCost, int fVerbose )
// if ( Ivy_ObjIsBuf(pNode) )
// continue;
// stop if all nodes have been tried once
if ( i > nNodes )
if ( i > nNodes )
break;
// for each cut, try to resynthesize it
nGain = Ivy_NodeRewriteSeq( p, pManRwt, pNode, fUseZeroCost );
......@@ -114,6 +120,7 @@ Rwt_ManAddTimeTotal( pManRwt, clock() - clkStart );
return 1;
}
/**Function*************************************************************
Synopsis [Performs rewriting for one node.]
......@@ -140,11 +147,11 @@ int Ivy_NodeRewriteSeq( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pNode, int
Ivy_Cut_t * pCut;
Ivy_Obj_t * pFanin;//, * pFanout;
Vec_Ptr_t * vFanout;
unsigned uPhase, uTruthBest, uTruth;
unsigned uPhase, uTruthBest, uTruth;//, nNewClauses;
char * pPerm;
int nNodesSaved, nNodesSaveCur;
int i, c, GainCur, GainBest = -1;
int clk, clk2;
int clk, clk2;//, clk3;
p->nNodesConsidered++;
// get the node's cuts
......@@ -201,18 +208,6 @@ clk2 = clock();
Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i )
Ivy_ObjRefsDec( Ivy_Regular(pFanin) );
p->timeMffc += clock() - clk2;
/*
if ( pNode->Id == 8648 )
{
int i;
printf( "Trying cut : {" );
for ( i = 0; i < pCut->nSize; i++ )
printf( " %d(%d)", Ivy_LeafId(pCut->pArray[i]), Ivy_LeafLat(pCut->pArray[i]) );
// printf( " }\n" );
printf( " } " );
Extra_PrintBinary( stdout, &uTruth, 16 ); printf( "\n" );
}
*/
// evaluate the cut
clk2 = clock();
......@@ -252,6 +247,15 @@ p->timeRes += clock() - clk;
}
*/
//clk3 = clock();
//nNewClauses = Ivy_CutTruthPrint( pMan, p->pCut, uTruth );
//timeInv += clock() - clk;
// nClauses += nNewClauses;
// nMoves++;
// if ( nNewClauses > 0 )
// nMovesS++;
// copy the leaves
Ivy_GraphPrepare( p->pGraph, p->pCut, p->vFanins, p->pPerm );
......
......@@ -731,6 +731,86 @@ void Ivy_ManPrintVerbose( Ivy_Man_t * p, int fHaig )
printf( "\n" );
}
/**Function*************************************************************
Synopsis [Performs incremental rewriting of the AIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ivy_CutTruthPrint2( Ivy_Man_t * p, Ivy_Cut_t * pCut, unsigned uTruth )
{
int i;
printf( "Trying cut : {" );
for ( i = 0; i < pCut->nSize; i++ )
printf( " %6d(%d)", Ivy_LeafId(pCut->pArray[i]), Ivy_LeafLat(pCut->pArray[i]) );
printf( " } " );
Extra_PrintBinary( stdout, &uTruth, 16 ); printf( "\n" );
return 0;
}
/**Function*************************************************************
Synopsis [Performs incremental rewriting of the AIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ivy_CutTruthPrint( Ivy_Man_t * p, Ivy_Cut_t * pCut, unsigned uTruth )
{
Vec_Ptr_t * vArray;
Ivy_Obj_t * pObj, * pFanout;
int nLatches = 0;
int nPresent = 0;
int i, k;
int fVerbose = 0;
if ( fVerbose )
printf( "Trying cut : {" );
for ( i = 0; i < pCut->nSize; i++ )
{
if ( fVerbose )
printf( " %6d(%d)", Ivy_LeafId(pCut->pArray[i]), Ivy_LeafLat(pCut->pArray[i]) );
nLatches += Ivy_LeafLat(pCut->pArray[i]);
}
if ( fVerbose )
printf( " } " );
if ( fVerbose )
printf( "Latches = %d. ", nLatches );
// check if there are latches on the fanout edges
vArray = Vec_PtrAlloc( 100 );
for ( i = 0; i < pCut->nSize; i++ )
{
pObj = Ivy_ManObj( p, Ivy_LeafId(pCut->pArray[i]) );
Ivy_ObjForEachFanout( p, pObj, vArray, pFanout, k )
{
if ( Ivy_ObjIsLatch(pFanout) )
{
nPresent++;
break;
}
}
}
Vec_PtrSize( vArray );
if ( fVerbose )
{
printf( "Present = %d. ", nPresent );
if ( nLatches > nPresent )
printf( "Clauses = %d. ", 2*(nLatches - nPresent) );
printf( "\n" );
}
return ( nLatches > nPresent ) ? 2*(nLatches - nPresent) : 0;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......
......@@ -814,6 +814,7 @@ extern int Abc_NtkGetExorNum( Abc_Ntk_t * pNtk );
extern int Abc_NtkGetMuxNum( Abc_Ntk_t * pNtk );
extern int Abc_NtkGetChoiceNum( Abc_Ntk_t * pNtk );
extern int Abc_NtkGetFaninMax( Abc_Ntk_t * pNtk );
extern int Abc_NtkGetTotalFanins( Abc_Ntk_t * pNtk );
extern void Abc_NtkCleanCopy( Abc_Ntk_t * pNtk );
extern int Abc_NtkCountCopy( Abc_Ntk_t * pNtk );
extern Vec_Ptr_t * Abc_NtkSaveCopy( Abc_Ntk_t * pNtk );
......
......@@ -105,7 +105,7 @@ void Abc_NtkIncrementTravId( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pObj;
int i;
if ( pNtk->nTravIds == (1<<30)-1 )
if ( pNtk->nTravIds >= (1<<30)-1 )
{
pNtk->nTravIds = 0;
Abc_NtkForEachObj( pNtk, pObj, i )
......@@ -447,6 +447,26 @@ int Abc_NtkGetFaninMax( Abc_Ntk_t * pNtk )
/**Function*************************************************************
Synopsis [Reads the total number of all fanins.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkGetTotalFanins( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pNode;
int i, nFanins = 0;
Abc_NtkForEachNode( pNtk, pNode, i )
nFanins += Abc_ObjFaninNum(pNode);
return nFanins;
}
/**Function*************************************************************
Synopsis [Cleans the copy field of all objects.]
Description []
......
......@@ -2569,6 +2569,9 @@ int Abc_CommandMfs( Abc_Frame_t * pAbc, int argc, char ** argv )
Res_Par_t Pars, * pPars = &Pars;
int c;
// printf( "Implementation of this command is not finished.\n" );
// return 1;
pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
pErr = Abc_FrameReadErr(pAbc);
......@@ -2641,8 +2644,8 @@ int Abc_CommandMfs( Abc_Frame_t * pAbc, int argc, char ** argv )
usage:
fprintf( pErr, "usage: mfs [-W <NM>] [-S <num>] [-vwh]\n" );
fprintf( pErr, "\t performs resubstitution-based resynthesis with don't-cares\n" );
fprintf( pErr, "\t-W <NM> : specifies the windowing paramters (00 < NM <= 99) [default = %d%d]\n", pPars->nWindow/10, pPars->nWindow%10 );
fprintf( pErr, "\t-S <num> : specifies the number of simulation words (1 <= n <= 256) [default = %d]\n", pPars->nSimWords );
fprintf( pErr, "\t-W <NM> : Fanin/Fanout levels (NxM) of the window (00 <= NM <= 99) [default = %d%d]\n", pPars->nWindow/10, pPars->nWindow%10 );
fprintf( pErr, "\t-S <num> : the number of simulation words (1 <= n <= 256) [default = %d]\n", pPars->nSimWords );
fprintf( pErr, "\t-v : toggle verbose printout [default = %s]\n", pPars->fVerbose? "yes": "no" );
fprintf( pErr, "\t-w : toggle printout subgraph statistics [default = %s]\n", pPars->fVeryVerbose? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
......
......@@ -187,18 +187,44 @@ Abc_Ntk_t * Abc_NtkIvyHaig( Abc_Ntk_t * pNtk, int nIters, int fUseZeroCost, int
{
Abc_Ntk_t * pNtkAig;
Ivy_Man_t * pMan;
int clk;
// int i;
/*
extern int nMoves;
extern int nMovesS;
extern int nClauses;
extern int timeInv;
nMoves = 0;
nMovesS = 0;
nClauses = 0;
timeInv = 0;
*/
pMan = Abc_NtkIvyBefore( pNtk, 1, 1 );
if ( pMan == NULL )
return NULL;
//timeRetime = clock();
clk = clock();
Ivy_ManHaigStart( pMan, fVerbose );
// Ivy_ManRewriteSeq( pMan, 0, 0 );
// for ( i = 0; i < nIters; i++ )
// Ivy_ManRewriteSeq( pMan, fUseZeroCost, 0 );
//printf( "%d ", Ivy_ManNodeNum(pMan) );
Ivy_ManRewriteSeq( pMan, 0, 0 );
Ivy_ManRewriteSeq( pMan, 0, 0 );
Ivy_ManRewriteSeq( pMan, 1, 0 );
//printf( "%d ", Ivy_ManNodeNum(pMan) );
//printf( "%d ", Ivy_ManNodeNum(pMan->pHaig) );
//PRT( " ", clock() - clk );
//printf( "\n" );
/*
printf( "Moves = %d. ", nMoves );
printf( "MovesS = %d. ", nMovesS );
printf( "Clauses = %d. ", nClauses );
PRT( "Time", timeInv );
*/
// Ivy_ManRewriteSeq( pMan, 1, 0 );
//printf( "Haig size = %d.\n", Ivy_ManNodeNum(pMan->pHaig) );
// Ivy_ManHaigPostprocess( pMan, fVerbose );
......
......@@ -77,7 +77,10 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored )
// fprintf( pFile, " (other = %d)", Abc_NtkNodeNum(pNtk)-3*Num2 );
}
else
{
fprintf( pFile, " nd = %5d", Abc_NtkNodeNum(pNtk) );
fprintf( pFile, " net = %5d", Abc_NtkGetTotalFanins(pNtk) );
}
if ( Abc_NtkIsStrash(pNtk) || Abc_NtkIsNetlist(pNtk) )
{
......
......@@ -65,6 +65,10 @@ int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, sint64 nConfLimit, sint64 nInsLimit, int
pSat = Abc_NtkMiterSatCreate( pNtk, 0 );
if ( pSat == NULL )
return 1;
//printf( "%d \n", pSat->clauses.size );
//sat_solver_delete( pSat );
//return 1;
// printf( "Created SAT problem with %d variable and %d clauses. ", sat_solver_nvars(pSat), sat_solver_nclauses(pSat) );
// PRT( "Time", clock() - clk );
......@@ -619,7 +623,7 @@ void * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk, int fAllPrimes )
nMuxes = 0;
pSat = sat_solver_new();
sat_solver_store_alloc( pSat );
//sat_solver_store_alloc( pSat );
RetValue = Abc_NtkMiterSatCreateInt( pSat, pNtk );
sat_solver_store_mark_roots( pSat );
......
/**CFile****************************************************************
FileName [bdc.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Truth-table-based bi-decomposition engine.]
Synopsis [External declarations.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - January 30, 2007.]
Revision [$Id: bdc.h,v 1.00 2007/01/30 00:00:00 alanmi Exp $]
***********************************************************************/
#ifndef __BDC_H__
#define __BDC_H__
#ifdef __cplusplus
extern "C" {
#endif
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
typedef struct Bdc_Man_t_ Bdc_Man_t;
typedef struct Bdc_Par_t_ Bdc_Par_t;
struct Bdc_Par_t_
{
// general parameters
int nVarsMax; // the maximum support
int fVerbose; // enable basic stats
int fVeryVerbose; // enable detailed stats
};
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*=== bdcCore.c ==========================================================*/
extern Bdc_Man_t * Bdc_ManAlloc( Bdc_Par_t * pPars );
extern void Bdc_ManAlloc( Bdc_Man_t * p );
extern int Bdc_ManDecompose( Bdc_Man_t * p, unsigned * puFunc, unsigned * puCare, int nVars, Vec_Ptr_t * vDivs, int nNodeLimit );
#ifdef __cplusplus
}
#endif
#endif
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [bdcCore.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Truth-table-based bi-decomposition engine.]
Synopsis [The gateway to bi-decomposition.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - January 30, 2007.]
Revision [$Id: bdcCore.c,v 1.00 2007/01/30 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abc.h"
#include "bdcInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Allocate resynthesis manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Bdc_Man_t * Bdc_ManAlloc( Bdc_Par_t * pPars )
{
Bdc_Man_t * p;
int i;
p = ALLOC( Bdc_Man_t, 1 );
memset( p, 0, sizeof(Bdc_Man_t) );
assert( pPars->nVarsMax > 3 && pPars->nVarsMax < 16 );
p->pPars = pPars;
// memory
p->vMemory = Vec_IntStart( 1 << 16 );
// internal nodes
p->nNodesAlloc = 256;
p->pNodes = ALLOC( Bdc_Fun_t, p->nNodesAlloc );
// set up hash table
p->nTableSize = (1 << p->pPars->nVarsMax);
p->pTable = ALLOC( Bdc_Fun_t *, p->nTableSize );
memset( p->pTable, 0, sizeof(Bdc_Fun_t *) * p->nTableSize );
p->vSpots = Vec_IntAlloc( 256 );
// set up constant 1 and elementary variables
for ( i = 0; i < pPars->nVarsMax; i++ )
{
}
p->nNodes = pPars->nVarsMax + 1;
// remember the current place in memory
p->nMemStart = Vec_IntSize( p->vMemory );
return p;
}
/**Function*************************************************************
Synopsis [Deallocate resynthesis manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Bdc_ManAlloc( Bdc_Man_t * p )
{
}
/**Function*************************************************************
Synopsis [Sets up the divisors.]
Description [The first n+1 entries are const1 and elem variables.]
SideEffects []
SeeAlso []
***********************************************************************/
void Bdc_ManPrepare( Bdc_Man_t * p, Vec_Ptr_t * vDivs )
{
Bdc_Fun_t ** pSpot, * pFunc;
unsigned * puTruth;
int i;
// clean hash table
Vec_PtrForEachEntry( p->vSpots, pSpot, i )
*pSpot = NULL;
// reset nodes
p->nNodes = p->pPars->nVarsMax + 1;
// reset memory
Vec_IntShrink( p->vMemory, p->nMemStart );
// add new nodes to the hash table
Vec_PtrForEachEntry( vDivs, puTruth, i )
{
pFunc = Bdc_ManNewNode( p );
pFunc->Type = BDC_TYPE_PI;
pFunc->puFunc = puTruth;
pFunc->uSupp = Kit_TruthSupport( puTruth, p->nVars );
}
}
/**Function*************************************************************
Synopsis [Performs decomposition of one function.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Bdc_ManDecompose( Bdc_Man_t * p, unsigned * puFunc, unsigned * puCare, int nVars, Vec_Ptr_t * vDivs, int nNodeLimit )
{
Bdc_Isf_t Isf, * pIsf = &Isf;
// set current manager parameters
p->nVars = nVars;
p->nWords = Kit_TruthWordNum( nVars );
p->nNodeLimit = nNodeLimit;
Bdc_ManPrepare( p, vDivs );
// copy the function
pIsf->uSupp = Kit_TruthSupport( puFunc, p->nVars ) | Kit_TruthSupport( puCare, p->nVars );
pIsf->puOn = Vec_IntFetch( p->vMemory, p->nWords );
pIsf->puOff = Vec_IntFetch( p->vMemory, p->nWords );
Kit_TruthAnd( pIsf->puOn, puCare, puFunc, p->nVars );
Kit_TruthSharp( pIsf->puOff, puCare, puFunc, p->nVars );
// call decomposition
p->pRoot = Bdc_ManDecompose_rec( p, pIsf );
if ( p->pRoot == NULL )
return -1;
return p->nNodes - (p->pPars->nVarsMax + 1);
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [bdc_.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Truth-table-based bi-decomposition engine.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - January 30, 2007.]
Revision [$Id: bdc_.c,v 1.00 2007/01/30 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abc.h"
#include "bdcInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Performs one step of bi-decomposition.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Bdc_Fun_t * Bdc_ManDecompose_rec( Bdc_Man_t * p, Bdc_Isf_t * pIsf )
{
Bdc_Fun_t * pFunc;
Bdc_Isf_t IsfA, * pIsfA = &IsfA;
Bdc_Isf_t IsfB, * pIsfB = &IsfB;
int Type;
Bdc_SuppMinimize( p, pIsf );
if ( pFunc = Bdc_TableLookup( p, pIsf ) )
return pFunc;
pFunc = Bdc_ManNewNode( p );
pFunc->Type = Bdc_DecomposeStep( p, pIsf, pIsfA, pIsfB );
pFunc->pFan0 = Bdc_ManDecompose_rec( p, pIsfA );
if ( Bdc_DecomposeUpdateRight( p, pIsf, pIsfA, pIsfB, pFunc->pFan0->puFunc ) )
{
p->nNodes--;
return pFunc->pFan0;
}
pFunc->pFan1 = Bdc_ManDecompose_rec( p, pIsfA );
pFunc->puFunc = Vec_IntFetch( p->vMemory, p->nWords );
pFunc->puFunc =
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [bdcInt.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Truth-table-based bi-decomposition engine.]
Synopsis [Internal declarations.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - January 15, 2007.]
Revision [$Id: resInt.h,v 1.00 2007/01/15 00:00:00 alanmi Exp $]
***********************************************************************/
#ifndef __BDC_INT_H__
#define __BDC_INT_H__
#ifdef __cplusplus
extern "C" {
#endif
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
#include "dec.h"
#include "bdc.h"
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
// network types
typedef enum {
BDC_TYPE_NONE = 0, // 0: unknown
BDC_TYPE_CONST1, // 1: constant 1
BDC_TYPE_PI, // 2: primary input
BDC_TYPE_AND, // 4: AND-gate
BDC_TYPE_XOR, // 5: XOR-gate
BDC_TYPE_MUX, // 6: MUX-gate
BDC_TYPE_OTHER // 7: unused
} Bdc_Type_t;
typedef struct Bdc_Fun_t_ Bdc_Fun_t;
struct Bdc_Fun_t_
{
int Type; // Const1, PI, AND, XOR, MUX
Bdc_Fun_t * pFan0; // next function with same support
Bdc_Fun_t * pFan1; // next function with same support
Bdc_Fun_t * pFan2; // next function with same support
unsigned uSupp; // bit mask of current support
unsigned * puFunc; // the function of the node
Bdc_Fun_t * pNext; // next function with same support
void * pCopy; // the copy field
};
typedef struct Bdc_Isf_t_ Bdc_Isf_t;
struct Bdc_Isf_t_
{
unsigned uSupp; // bit mask of current support
unsigned uUnique; // bit mask of unique support
unsigned * puOn; // on-set
unsigned * puOff; // off-set
int Cost; // cost of this component
};
typedef struct Bdc_Man_t_ Bdc_Man_t;
struct Bdc_Man_t_
{
// external parameters
Bdc_Par_t * pPars; // parameter set
int nVars; // the number of variables
int nWords; // the number of words
int nNodeLimit; // the limit on the number of new nodes
// internal nodes
Bdc_Fun_t * pNodes; // storage for decomposition nodes
int nNodes; // the number of nodes used
int nNodesAlloc; // the number of nodes allocated
Bdc_Fun_t * pRoot; // the root node
// resub candidates
Bdc_Fun_t ** pTable; // hash table of candidates
int nTableSize; // hash table size (1 << nVarsMax)
// internal memory manager
Vec_Int_t * vMemory; // memory for internal truth tables
int nMemStart; // the starting memory size
};
// working with complemented attributes of objects
static inline bool Bdc_IsComplement( Bdc_Fun_t * p ) { return (bool)((unsigned long)p & (unsigned long)01); }
static inline Bdc_Fun_t * Bdc_Regular( Bdc_Fun_t * p ) { return (Bdc_Fun_t *)((unsigned long)p & ~(unsigned long)01); }
static inline Bdc_Fun_t * Bdc_Not( Bdc_Fun_t * p ) { return (Bdc_Fun_t *)((unsigned long)p ^ (unsigned long)01); }
static inline Bdc_Fun_t * Bdc_NotCond( Bdc_Fun_t * p, int c ) { return (Bdc_Fun_t *)((unsigned long)p ^ (unsigned long)(c!=0)); }
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*=== bdcSupp.c ==========================================================*/
extern int Bdc_SuppMinimize( Bdc_Man_t * p, Bdc_Isf_t * pIsf );
/*=== bdcTable.c ==========================================================*/
extern Bdc_Fun_t * Bdc_TableLookup( Bdc_Man_t * p, Bdc_Isf_t * pIsf );
#ifdef __cplusplus
}
#endif
#endif
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [bdc_.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Truth-table-based bi-decomposition engine.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - January 30, 2007.]
Revision [$Id: bdc_.c,v 1.00 2007/01/30 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abc.h"
#include "bdcInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
SRC += src/opt/res/resCore.c \
src/opt/res/resDivs.c \
src/opt/res/resFilter.c \
src/opt/res/resSat.c \
src/opt/res/resSim.c \
src/opt/res/resStrash.c \
src/opt/res/resUpdate.c \
src/opt/res/resWin.c
......@@ -39,15 +39,19 @@ struct Res_Man_t_
Sto_Man_t * pCnf; // the CNF of the SAT problem
Int_Man_t * pMan; // interpolation manager;
Vec_Int_t * vMem; // memory for intermediate SOPs
Vec_Vec_t * vResubs; // resubstitution candidates
Vec_Vec_t * vResubs; // resubstitution candidates of the AIG
Vec_Vec_t * vResubsW; // resubstitution candidates of the window
Vec_Vec_t * vLevels; // levelized structure for updating
// statistics
int nWins; // the number of windows tried
int nWinNodes; // the total number of window nodes
int nDivNodes; // the total number of divisors
int nWinsTriv; // the total number of trivial windows
int nWinsUsed; // the total number of useful windows (with at least one candidate)
int nCandSets; // the total number of candidates
int nProvedSets; // the total number of proved groups
int nSimEmpty; // the empty simulation info
int nTotalNets; // the total number of nets
// runtime
int timeWin; // windowing
int timeDiv; // divisors
......@@ -90,6 +94,7 @@ Res_Man_t * Res_ManAlloc( Res_Par_t * pPars )
p->pMan = Int_ManAlloc( 512 );
p->vMem = Vec_IntAlloc( 0 );
p->vResubs = Vec_VecStart( pPars->nCands );
p->vResubsW = Vec_VecStart( pPars->nCands );
p->vLevels = Vec_VecStart( 32 );
return p;
}
......@@ -113,9 +118,11 @@ void Res_ManFree( Res_Man_t * p )
printf( "Nodes = %d. (Ave = %5.1f) ", p->nWinNodes, 1.0*p->nWinNodes/p->nWins );
printf( "Divs = %d. (Ave = %5.1f) ", p->nDivNodes, 1.0*p->nDivNodes/p->nWins );
printf( "\n" );
printf( "SimEmpt = %d. ", p->nSimEmpty );
printf( "WinsTriv = %d. ", p->nWinsTriv );
printf( "SimsEmpt = %d. ", p->nSimEmpty );
printf( "WindUsed = %d. ", p->nWinsUsed );
printf( "Cands = %d. ", p->nCandSets );
printf( "Proved = %d. ", p->nProvedSets );
printf( "Proved = %d. (%.2f %%)", p->nProvedSets, 100.0*p->nProvedSets/p->nTotalNets );
printf( "\n" );
PRT( "Windowing ", p->timeWin );
......@@ -135,6 +142,7 @@ void Res_ManFree( Res_Man_t * p )
Int_ManFree( p->pMan );
Vec_IntFree( p->vMem );
Vec_VecFree( p->vResubs );
Vec_VecFree( p->vResubsW );
Vec_VecFree( p->vLevels );
free( p );
}
......@@ -164,6 +172,7 @@ int Abc_NtkResynthesize( Abc_Ntk_t * pNtk, Res_Par_t * pPars )
// start the manager
p = Res_ManAlloc( pPars );
p->nTotalNets = Abc_NtkGetTotalFanins(pNtk);
// set the number of levels
Abc_NtkLevel( pNtk );
......@@ -182,15 +191,32 @@ clk = clock();
p->timeWin += clock() - clk;
if ( !RetValue )
continue;
p->nWinsTriv += Res_WinIsTrivial( p->pWin );
p->nWins++;
p->nWinNodes += Vec_VecSizeSize( p->pWin->vLevels );
if ( p->pPars->fVeryVerbose )
{
printf( "%5d (lev=%2d) : ", pObj->Id, pObj->Level );
printf( "Win = %3d/%3d/%4d/%3d ",
Vec_PtrSize(p->pWin->vLeaves),
Vec_PtrSize(p->pWin->vBranches),
Vec_PtrSize(p->pWin->vNodes),
Vec_PtrSize(p->pWin->vRoots) );
}
// collect the divisors
clk = clock();
Res_WinDivisors( p->pWin, pObj->Level - 1 );
p->timeDiv += clock() - clk;
p->nDivNodes += Vec_PtrSize( p->pWin->vDivs );
p->nWins++;
p->nWinNodes += Vec_PtrSize(p->pWin->vNodes);
p->nDivNodes += Vec_PtrSize( p->pWin->vDivs);
if ( p->pPars->fVeryVerbose )
{
printf( "D = %3d ", Vec_PtrSize(p->pWin->vDivs) );
printf( "D+ = %3d ", p->pWin->nDivsPlus );
}
// create the AIG for the window
clk = clock();
......@@ -200,13 +226,6 @@ p->timeAig += clock() - clk;
if ( p->pPars->fVeryVerbose )
{
printf( "%5d (lev=%2d) : ", pObj->Id, pObj->Level );
printf( "Win = %3d/%3d/%4d/%3d ",
Vec_PtrSize(p->pWin->vLeaves) - p->pWin->nLeavesPlus,
p->pWin->nLeavesPlus, Vec_VecSizeSize(p->pWin->vLevels),
Vec_PtrSize(p->pWin->vRoots) );
printf( "D = %3d ", Vec_PtrSize(p->pWin->vDivs) );
printf( "D+ = %3d ", p->pWin->nDivsPlus );
printf( "AIG = %4d ", Abc_NtkNodeNum(p->pAig) );
printf( "\n" );
}
......@@ -223,12 +242,14 @@ p->timeSim += clock() - clk;
// find resub candidates for the node
clk = clock();
RetValue = Res_FilterCandidates( p->pWin, p->pAig, p->pSim, p->vResubs );
RetValue = Res_FilterCandidates( p->pWin, p->pAig, p->pSim, p->vResubs, p->vResubsW );
p->timeCand += clock() - clk;
p->nCandSets += RetValue;
if ( RetValue == 0 )
continue;
p->nWinsUsed++;
// iterate through candidate resubstitutions
Vec_VecForEachLevel( p->vResubs, vFanins, k )
{
......@@ -247,26 +268,19 @@ p->timeSat += clock() - clk;
}
p->nProvedSets++;
// printf( " Unsat\n" );
continue;
// continue;
// write it into a file
// Sto_ManDumpClauses( p->pCnf, "trace.cnf" );
// interplate the problem if it was UNSAT
// interpolate the problem if it was UNSAT
clk = clock();
RetValue = Int_ManInterpolate( p->pMan, p->pCnf, p->pPars->fVerbose, &puTruth );
nFanins = Int_ManInterpolate( p->pMan, p->pCnf, 0, &puTruth );
p->timeInt += clock() - clk;
assert( RetValue == Vec_PtrSize(vFanins) - 2 );
if ( puTruth )
{
Extra_PrintBinary( stdout, puTruth, 1 << RetValue );
printf( "\n" );
}
continue;
assert( nFanins == Vec_PtrSize(vFanins) - 2 );
assert( puTruth );
// Extra_PrintBinary( stdout, puTruth, 1 << nFanins ); printf( "\n" );
// transform interpolant into the AIG
pGraph = Kit_TruthToGraph( puTruth, nFanins, p->vMem );
......@@ -276,10 +290,11 @@ p->timeInt += clock() - clk;
// update the network
clk = clock();
Res_UpdateNetwork( pObj, vFanins, pFunc, p->vLevels );
Res_UpdateNetwork( pObj, Vec_VecEntry(p->vResubsW, k), pFunc, p->vLevels );
p->timeUpd += clock() - clk;
break;
}
}
// quit resubstitution manager
......
......@@ -25,6 +25,9 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static void Res_WinMarkTfi( Res_Win_t * p );
static int Res_WinVisitMffc( Res_Win_t * p );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
......@@ -43,84 +46,155 @@
void Res_WinDivisors( Res_Win_t * p, int nLevDivMax )
{
Abc_Obj_t * pObj, * pFanout, * pFanin;
int i, k, f, m;
int k, f, m;
// set the maximum level of the divisors
p->nLevDivMax = nLevDivMax;
// mark the leaves and the internal nodes
Vec_PtrForEachEntry( p->vLeaves, pObj, i )
pObj->fMarkA = 1;
Vec_VecForEachEntry( p->vLevels, pObj, i, k )
pObj->fMarkA = 1;
// mark the TFI with the current trav ID
Abc_NtkIncrementTravId( p->pNode->pNtk );
Res_WinMarkTfi( p );
// prepare the new trav ID
// mark with the current trav ID those nodes that should not be divisors:
// (1) the node and its TFO
// (2) the MFFC of the node
// (3) the node's fanins (these are treated as a special case)
Abc_NtkIncrementTravId( p->pNode->pNtk );
// mark the TFO of the node (does not increment trav ID)
Res_WinSweepLeafTfo_rec( p->pNode, p->nLevDivMax, NULL );
// mark the MFFC of the node (does not increment trav ID)
Res_WinSweepLeafTfo_rec( p->pNode, p->nLevDivMax );
Res_WinVisitMffc( p );
Abc_ObjForEachFanin( p->pNode, pObj, k )
Abc_NodeSetTravIdCurrent( pObj );
// what about the fanouts of the leaves!!!
// at this point the nodes are marked with two trav IDs:
// nodes to be collected as divisors are marked with previous trav ID
// nodes to be avoided as divisors are marked with current trav ID
// go through all the legal levels and check if their fanouts can be divisors
p->nDivsPlus = 0;
Vec_VecForEachEntryStartStop( p->vLevels, pObj, i, k, 0, p->nLevDivMax - 1 )
// start collecting the divisors
Vec_PtrClear( p->vDivs );
Vec_PtrForEachEntry( p->vLeaves, pObj, k )
{
assert( (int)pObj->Level >= p->nLevLeafMin );
if ( !Abc_NodeIsTravIdPrevious(pObj) )
continue;
if ( (int)pObj->Level > p->nLevDivMax )
continue;
Vec_PtrPush( p->vDivs, pObj );
}
// add the internal nodes to the data structure
Vec_PtrForEachEntry( p->vNodes, pObj, k )
{
// skip nodes in the TFO or in the MFFC of node
if ( Abc_NodeIsTravIdCurrent(pObj) )
if ( !Abc_NodeIsTravIdPrevious(pObj) )
continue;
if ( (int)pObj->Level > p->nLevDivMax )
continue;
Vec_PtrPush( p->vDivs, pObj );
}
// explore the fanouts of already collected divisors
p->nDivsPlus = 0;
Vec_PtrForEachEntry( p->vDivs, pObj, k )
{
// consider fanouts of this node
Abc_ObjForEachFanout( pObj, pFanout, f )
{
// stop if there are too many fanouts
if ( f > 20 )
break;
// skip nodes that are already added
if ( pFanout->fMarkA )
continue;
// skip COs
if ( !Abc_ObjIsNode(pFanout) )
if ( Abc_NodeIsTravIdPrevious(pFanout) )
continue;
// skip nodes in the TFO or in the MFFC of node
if ( Abc_NodeIsTravIdCurrent(pFanout) )
continue;
// skip COs
if ( !Abc_ObjIsNode(pFanout) )
continue;
// skip nodes with large level
if ( (int)pFanout->Level > p->nLevDivMax )
if ( (int)pFanout->Level >= p->nLevDivMax )
continue;
// skip nodes whose fanins are not in the cone
// skip nodes whose fanins are not divisors
Abc_ObjForEachFanin( pFanout, pFanin, m )
if ( !pFanin->fMarkA )
if ( !Abc_NodeIsTravIdPrevious(pFanin) )
break;
if ( m < Abc_ObjFaninNum(pFanout) )
continue;
// add the node
Res_WinAddNode( p, pFanout );
// add the node to the divisors
Vec_PtrPush( p->vDivs, pFanout );
Vec_PtrPush( p->vNodes, pFanout );
Abc_NodeSetTravIdPrevious( pFanout );
p->nDivsPlus++;
}
}
}
// unmark the leaves and the internal nodes
Vec_PtrForEachEntry( p->vLeaves, pObj, i )
pObj->fMarkA = 0;
Vec_VecForEachEntry( p->vLevels, pObj, i, k )
pObj->fMarkA = 0;
/**Function*************************************************************
// collect the divisors below the line
Vec_PtrClear( p->vDivs );
// collect the node fanins first and mark the fanins
Abc_ObjForEachFanin( p->pNode, pFanin, m )
{
Vec_PtrPush( p->vDivs, pFanin );
Abc_NodeSetTravIdCurrent( pFanin );
}
// collect the remaining leaves
Synopsis [Marks the TFI cone of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Res_WinMarkTfi_rec( Res_Win_t * p, Abc_Obj_t * pObj )
{
Abc_Obj_t * pFanin;
int i;
if ( Abc_NodeIsTravIdCurrent(pObj) )
return;
Abc_NodeSetTravIdCurrent( pObj );
assert( Abc_ObjIsNode(pObj) );
// visit the fanins of the node
Abc_ObjForEachFanin( pObj, pFanin, i )
Res_WinMarkTfi_rec( p, pFanin );
}
/**Function*************************************************************
Synopsis [Marks the TFI cone of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Res_WinMarkTfi( Res_Win_t * p )
{
Abc_Obj_t * pObj;
int i;
// mark the leaves
Vec_PtrForEachEntry( p->vLeaves, pObj, i )
if ( !Abc_NodeIsTravIdCurrent(pObj) )
Vec_PtrPush( p->vDivs, pObj );
// collect remaining unvisited divisors
Vec_VecForEachEntryStartStop( p->vLevels, pObj, i, k, p->nLevLeaves, p->nLevDivMax )
if ( !Abc_NodeIsTravIdCurrent(pObj) )
Vec_PtrPush( p->vDivs, pObj );
// verify the resulting window
// Res_WinVerify( p );
Abc_NodeSetTravIdCurrent( pObj );
// start from the node
Res_WinMarkTfi_rec( p, p->pNode );
}
/**Function*************************************************************
Synopsis [Marks the TFO of the collected nodes up to the given level.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Res_WinSweepLeafTfo_rec( Abc_Obj_t * pObj, int nLevelLimit )
{
Abc_Obj_t * pFanout;
int i;
if ( Abc_ObjIsCo(pObj) || (int)pObj->Level > nLevelLimit )
return;
if ( Abc_NodeIsTravIdCurrent(pObj) )
return;
Abc_NodeSetTravIdCurrent( pObj );
Abc_ObjForEachFanout( pObj, pFanout, i )
Res_WinSweepLeafTfo_rec( pFanout, nLevelLimit );
}
/**Function*************************************************************
......
......@@ -42,7 +42,7 @@ static unsigned * Res_FilterCollectFaninInfo( Res_Win_t * pWin, Res_Sim_t * pSim
SeeAlso []
***********************************************************************/
int Res_FilterCandidates( Res_Win_t * pWin, Abc_Ntk_t * pAig, Res_Sim_t * pSim, Vec_Vec_t * vResubs )
int Res_FilterCandidates( Res_Win_t * pWin, Abc_Ntk_t * pAig, Res_Sim_t * pSim, Vec_Vec_t * vResubs, Vec_Vec_t * vResubsW )
{
Abc_Obj_t * pFanin, * pFanin2;
unsigned * pInfo;
......@@ -52,18 +52,19 @@ int Res_FilterCandidates( Res_Win_t * pWin, Abc_Ntk_t * pAig, Res_Sim_t * pSim,
pInfo = Vec_PtrEntry( pSim->vOuts, 1 );
RetValue = Abc_InfoIsOne( pInfo, pSim->nWordsOut );
if ( RetValue == 0 )
printf( "Failed 1!" );
printf( "Failed 1!\n" );
// collect the fanin info
pInfo = Res_FilterCollectFaninInfo( pWin, pSim, ~0 );
RetValue = Abc_InfoIsOne( pInfo, pSim->nWordsOut );
if ( RetValue == 0 )
printf( "Failed 2!" );
printf( "Failed 2!\n" );
// try removing fanins
// printf( "Fanins: " );
Counter = 0;
Vec_VecClear( vResubs );
Vec_VecClear( vResubsW );
Abc_ObjForEachFanin( pWin->pNode, pFanin, i )
{
pInfo = Res_FilterCollectFaninInfo( pWin, pSim, ~(1 << i) );
......@@ -78,7 +79,10 @@ int Res_FilterCandidates( Res_Win_t * pWin, Abc_Ntk_t * pAig, Res_Sim_t * pSim,
Abc_ObjForEachFanin( pWin->pNode, pFanin2, k )
{
if ( k != i )
{
Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,2+k) );
Vec_VecPush( vResubsW, Counter, pFanin2 );
}
}
Counter++;
}
......
......@@ -42,49 +42,48 @@ extern "C" {
typedef struct Res_Win_t_ Res_Win_t;
struct Res_Win_t_
{
// the general data
int nWinTfiMax; // the fanin levels
int nWinTfoMax; // the fanout levels
int nLevLeaves; // the level where leaves begin
int nLevDivMax; // the maximum divisor level
int nDivsPlus; // the number of additional divisors
int nLeavesPlus;// the number of additional leaves
Abc_Obj_t * pNode; // the node in the center
// windowing parameters
Abc_Obj_t * pNode; // the node in the center
int nWinTfiMax; // the fanin levels
int nWinTfoMax; // the fanout levels
int nLevDivMax; // the maximum divisor level
// internal windowing parameters
int nFanoutLimit; // the limit on the fanout count of a TFO node (if more, the node is treated as a root)
int nLevTfiMinus; // the number of additional levels to search from TFO below the level of leaves
// derived windowing parameters
int nLevLeafMin; // the minimum level of a leaf
int nLevTravMin; // the minimum level to search from TFO
int nDivsPlus; // the number of additional divisors
// the window data
Vec_Vec_t * vLevels; // nodes by level
Vec_Ptr_t * vLeaves; // leaves of the window
Vec_Ptr_t * vRoots; // roots of the window
Vec_Ptr_t * vDivs; // the candidate divisors of the node
Vec_Ptr_t * vRoots; // outputs of the window
Vec_Ptr_t * vLeaves; // inputs of the window
Vec_Ptr_t * vBranches; // side nodes of the window
Vec_Ptr_t * vNodes; // internal nodes of the window
Vec_Ptr_t * vDivs; // candidate divisors of the node
// temporary data
Vec_Vec_t * vMatrix; // TFI nodes below the given node
};
typedef struct Res_Sim_t_ Res_Sim_t;
struct Res_Sim_t_
{
Abc_Ntk_t * pAig; // AIG for simulation
Abc_Ntk_t * pAig; // AIG for simulation
// simulation parameters
int nWords; // the number of simulation words
int nPats; // the number of patterns
int nWordsOut; // the number of simulation words in the output patterns
int nPatsOut; // the number of patterns in the output patterns
int nWords; // the number of simulation words
int nPats; // the number of patterns
int nWordsOut; // the number of simulation words in the output patterns
int nPatsOut; // the number of patterns in the output patterns
// simulation info
Vec_Ptr_t * vPats; // input simulation patterns
Vec_Ptr_t * vPats0; // input simulation patterns
Vec_Ptr_t * vPats1; // input simulation patterns
Vec_Ptr_t * vOuts; // output simulation info
int nPats0; // the number of 0-patterns accumulated
int nPats1; // the number of 1-patterns accumulated
Vec_Ptr_t * vPats; // input simulation patterns
Vec_Ptr_t * vPats0; // input simulation patterns
Vec_Ptr_t * vPats1; // input simulation patterns
Vec_Ptr_t * vOuts; // output simulation info
int nPats0; // the number of 0-patterns accumulated
int nPats1; // the number of 1-patterns accumulated
// resub candidates
Vec_Vec_t * vCands; // resubstitution candidates
Vec_Vec_t * vCands; // resubstitution candidates
};
// adds one node to the window
static inline void Res_WinAddNode( Res_Win_t * p, Abc_Obj_t * pObj )
{
assert( !pObj->fMarkA );
pObj->fMarkA = 1;
Vec_VecPush( p->vLevels, pObj->Level, pObj );
}
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
......@@ -95,11 +94,12 @@ static inline void Res_WinAddNode( Res_Win_t * p, Abc_Obj_t * pObj )
/*=== resDivs.c ==========================================================*/
extern void Res_WinDivisors( Res_Win_t * p, int nLevDivMax );
extern int Res_WinVisitMffc( Res_Win_t * p );
extern void Res_WinSweepLeafTfo_rec( Abc_Obj_t * pObj, int nLevelLimit );
/*=== resFilter.c ==========================================================*/
extern int Res_FilterCandidates( Res_Win_t * pWin, Abc_Ntk_t * pAig, Res_Sim_t * pSim, Vec_Vec_t * vResubs );
extern int Res_FilterCandidates( Res_Win_t * pWin, Abc_Ntk_t * pAig, Res_Sim_t * pSim, Vec_Vec_t * vResubs, Vec_Vec_t * vResubsW );
/*=== resSat.c ==========================================================*/
extern void * Res_SatProveUnsat( Abc_Ntk_t * pAig, Vec_Ptr_t * vFanins );
extern void * Res_SatSimulateConstr( Abc_Ntk_t * pAig, Vec_Ptr_t * vFanins );
/*=== resSim.c ==========================================================*/
extern Res_Sim_t * Res_SimAlloc( int nWords );
extern void Res_SimFree( Res_Sim_t * p );
......@@ -111,7 +111,7 @@ extern void Res_UpdateNetwork( Abc_Obj_t * pObj, Vec_Ptr_t * vFanins, H
/*=== resWnd.c ==========================================================*/
extern Res_Win_t * Res_WinAlloc();
extern void Res_WinFree( Res_Win_t * p );
extern void Res_WinSweepLeafTfo_rec( Abc_Obj_t * pObj, int nLevelLimit, Abc_Obj_t * pNode );
extern int Res_WinIsTrivial( Res_Win_t * p );
extern int Res_WinCompute( Abc_Obj_t * pNode, int nWinTfiMax, int nWinTfoMax, Res_Win_t * p );
......
......@@ -37,7 +37,7 @@ extern int Res_SatAddAnd( sat_solver * pSat, int iVar, int iVar0, int iVar1, int
/**Function*************************************************************
Synopsis [Loads AIG into the SAT solver.]
Synopsis [Loads AIG into the SAT solver for checking resubstitution.]
Description []
......@@ -126,6 +126,66 @@ void * Res_SatProveUnsat( Abc_Ntk_t * pAig, Vec_Ptr_t * vFanins )
/**Function*************************************************************
Synopsis [Loads AIG into the SAT solver for constrained simulation.]
Description [The array of fanins contains exactly two entries: the
care set and the functions.]
SideEffects []
SeeAlso []
***********************************************************************/
void * Res_SatSimulateConstr( Abc_Ntk_t * pAig, Vec_Ptr_t * vFanins )
{
sat_solver * pSat;
Vec_Ptr_t * vNodes;
Abc_Obj_t * pObj;
int i, nNodes;
// make sure fanins contain POs of the AIG
pObj = Vec_PtrEntry( vFanins, 0 );
assert( pObj->pNtk == pAig && Abc_ObjIsPo(pObj) );
assert( Vec_PtrSize(vFanins) == 2 );
// collect reachable nodes
vNodes = Abc_NtkDfsNodes( pAig, (Abc_Obj_t **)vFanins->pArray, vFanins->nSize );
// assign unique numbers to each node
nNodes = 0;
Abc_AigConst1(pAig)->pCopy = (void *)nNodes++;
Abc_NtkForEachPi( pAig, pObj, i )
pObj->pCopy = (void *)nNodes++;
Vec_PtrForEachEntry( vNodes, pObj, i )
pObj->pCopy = (void *)nNodes++;
Vec_PtrForEachEntry( vFanins, pObj, i ) // useful POs
pObj->pCopy = (void *)nNodes++;
// start the solver
pSat = sat_solver_new();
// add clause for the constant node
Res_SatAddConst1( pSat, (int)Abc_AigConst1(pAig)->pCopy, 0 );
// add clauses for AND gates
Vec_PtrForEachEntry( vNodes, pObj, i )
Res_SatAddAnd( pSat, (int)pObj->pCopy,
(int)Abc_ObjFanin0(pObj)->pCopy, (int)Abc_ObjFanin1(pObj)->pCopy, Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) );
Vec_PtrFree( vNodes );
// add clauses for POs
Vec_PtrForEachEntry( vFanins, pObj, i )
Res_SatAddEqual( pSat, (int)pObj->pCopy,
(int)Abc_ObjFanin0(pObj)->pCopy, Abc_ObjFaninC0(pObj) );
// add trivial clauses
pObj = Vec_PtrEntry(vFanins, 0);
Res_SatAddConst1( pSat, (int)pObj->pCopy, 0 ); // care-set
pObj = Vec_PtrEntry(vFanins, 1);
Res_SatAddConst1( pSat, (int)pObj->pCopy, 0 ); // on-set
return pSat;
}
/**Function*************************************************************
Synopsis [Asserts equality of the variable to a constant.]
Description []
......
......@@ -484,13 +484,13 @@ int Res_SimPrepare( Res_Sim_t * p, Abc_Ntk_t * pAig )
Res_SimProcessPats( p );
if ( !(p->nPats0 < p->nPats || p->nPats1 < p->nPats) )
break;
}
// printf( "%d ", Limit );
// report the last set of patterns
Res_SimReportOne( p );
printf( "\n" );
// Res_SimReportOne( p );
// printf( "\n" );
// quit if there is not enough
// if ( p->nPats0 < 4 || p->nPats1 < 4 )
if ( p->nPats0 < 4 || p->nPats1 < 4 )
{
// Res_SimReportOne( p );
......
......@@ -48,22 +48,25 @@ Abc_Ntk_t * Res_WndStrash( Res_Win_t * p )
Vec_Ptr_t * vPairs;
Abc_Ntk_t * pAig;
Abc_Obj_t * pObj, * pMiter;
int i, k;
int i;
assert( Abc_NtkHasAig(p->pNode->pNtk) );
// Abc_NtkCleanCopy( p->pNode->pNtk );
// create the network
pAig = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG, 1 );
pAig->pName = Extra_UtilStrsav( "window" );
// create the inputs
Vec_PtrForEachEntry( p->vLeaves, pObj, i )
pObj->pCopy = Abc_NtkCreatePi( pAig );
Vec_PtrForEachEntry( p->vBranches, pObj, i )
pObj->pCopy = Abc_NtkCreatePi( pAig );
// go through the nodes in the topological order
Vec_VecForEachEntryStartStop( p->vLevels, pObj, i, k, p->nLevLeaves + 1, (int)p->pNode->Level + p->nWinTfoMax )
Vec_PtrForEachEntry( p->vNodes, pObj, i )
{
pObj->pCopy = Abc_ConvertAigToAig( pAig, pObj );
if ( pObj == p->pNode )
pObj->pCopy = Abc_ObjNot( pObj->pCopy );
}
// collect the PO outputs
// collect the POs
vPairs = Vec_PtrAlloc( 2 * Vec_PtrSize(p->vRoots) );
Vec_PtrForEachEntry( p->vRoots, pObj, i )
{
......@@ -72,15 +75,17 @@ Abc_Ntk_t * Res_WndStrash( Res_Win_t * p )
}
// mark the TFO of the node
Abc_NtkIncrementTravId( p->pNode->pNtk );
Res_WinSweepLeafTfo_rec( p->pNode, (int)p->pNode->Level + p->nWinTfoMax, NULL );
// redo strashing in the TFO
Res_WinSweepLeafTfo_rec( p->pNode, (int)p->pNode->Level + p->nWinTfoMax );
// update strashing of the node
p->pNode->pCopy = Abc_ObjNot( p->pNode->pCopy );
Vec_VecForEachEntryStartStop( p->vLevels, pObj, i, k, p->pNode->Level + 1, (int)p->pNode->Level + p->nWinTfoMax )
Abc_NodeSetTravIdPrevious( p->pNode );
// redo strashing in the TFO
Vec_PtrForEachEntry( p->vNodes, pObj, i )
{
if ( Abc_NodeIsTravIdCurrent(pObj) )
pObj->pCopy = Abc_ConvertAigToAig( pAig, pObj );
}
// collect the PO outputs
// collect the POs
Vec_PtrForEachEntry( p->vRoots, pObj, i )
Vec_PtrWriteEntry( vPairs, 2 * i + 1, pObj->pCopy );
// add the miter
......@@ -89,6 +94,9 @@ Abc_Ntk_t * Res_WndStrash( Res_Win_t * p )
Vec_PtrFree( vPairs );
// add the node
Abc_ObjAddFanin( Abc_NtkCreatePo(pAig), p->pNode->pCopy );
// add the fanins
Abc_ObjForEachFanin( p->pNode, pObj, i )
Abc_ObjAddFanin( Abc_NtkCreatePo(pAig), pObj->pCopy );
// add the divisors
Vec_PtrForEachEntry( p->vDivs, pObj, i )
Abc_ObjAddFanin( Abc_NtkCreatePo(pAig), pObj->pCopy );
......
......@@ -45,11 +45,11 @@ static int Res_UpdateNetworkLevelNew( Abc_Obj_t * pObj );
void Res_UpdateNetwork( Abc_Obj_t * pObj, Vec_Ptr_t * vFanins, Hop_Obj_t * pFunc, Vec_Vec_t * vLevels )
{
Abc_Obj_t * pObjNew, * pFanin, * pFanout, * pTemp;
int i, k, m;
int Lev, k, m;
// create the new node
pObjNew = Abc_NtkCreateNode( pObj->pNtk );
pObjNew->pData = pFunc;
Vec_PtrForEachEntry( vFanins, pFanin, i )
Vec_PtrForEachEntry( vFanins, pFanin, k )
Abc_ObjAddFanin( pObjNew, pFanin );
// replace the old node by the new node
pObjNew->Level = pObj->Level;
......@@ -62,12 +62,12 @@ void Res_UpdateNetwork( Abc_Obj_t * pObj, Vec_Ptr_t * vFanins, Hop_Obj_t * pFunc
Vec_VecPush( vLevels, pObjNew->Level, pObjNew );
pObjNew->fMarkA = 1;
// recursively update level
Vec_VecForEachEntryStart( vLevels, pTemp, i, k, pObjNew->Level )
Vec_VecForEachEntryStart( vLevels, pTemp, Lev, k, pObjNew->Level )
{
pTemp->fMarkA = 0;
pTemp->Level = Res_UpdateNetworkLevelNew( pTemp );
// if the level did not change, to need to check the fanout levels
if ( (int)pTemp->Level == i )
if ( (int)pTemp->Level == Lev )
continue;
// schedule fanout for level update
Abc_ObjForEachFanout( pTemp, pFanout, m )
......
......@@ -771,7 +771,8 @@ int Int_ManProofRecordOne( Int_Man_t * p, Sto_Cls_t * pClause )
{
// construct the proof
Int_ManProofTraceOne( p, pConflict, p->pCnf->pEmpty );
printf( "Found last conflict after adding unit clause number %d!\n", pClause->Id );
if ( p->fVerbose )
printf( "Found last conflict after adding unit clause number %d!\n", pClause->Id );
return 0;
}
......@@ -827,7 +828,7 @@ int Int_ManProcessRoots( Int_Man_t * p )
if ( !Int_ManEnqueue( p, pClause->pLits[0], pClause ) )
{
// detected root level conflict
printf( "Int_ManProcessRoots(): Detected a root-level conflict\n" );
printf( "Error in Int_ManProcessRoots(): Detected a root-level conflict too early!\n" );
assert( 0 );
return 0;
}
......@@ -838,8 +839,9 @@ int Int_ManProcessRoots( Int_Man_t * p )
if ( pClause )
{
// detected root level conflict
printf( "Int_ManProcessRoots(): Detected a root-level conflict\n" );
// assert( 0 );
Int_ManProofTraceOne( p, pClause, p->pCnf->pEmpty );
if ( p->fVerbose )
printf( "Found root level conflict!\n" );
return 0;
}
......@@ -925,17 +927,12 @@ int Int_ManInterpolate( Int_Man_t * p, Sto_Man_t * pCnf, int fVerbose, unsigned
// check that the CNF makes sense
assert( pCnf->nVars > 0 && pCnf->nClauses > 0 );
p->pCnf = pCnf;
p->fVerbose = fVerbose;
*ppResult = NULL;
// adjust the manager
Int_ManResize( p );
// propagate root level assignments
if ( !Int_ManProcessRoots( p ) )
{
*ppResult = NULL;
return p->nVarsAB;
}
// prepare the interpolant computation
Int_ManPrepareInter( p );
......@@ -951,15 +948,19 @@ int Int_ManInterpolate( Int_Man_t * p, Sto_Man_t * pCnf, int fVerbose, unsigned
Sto_ManForEachClauseRoot( p->pCnf, pClause )
Int_ManProofWriteOne( p, pClause );
// consider each learned clause
Sto_ManForEachClause( p->pCnf, pClause )
// propagate root level assignments
if ( Int_ManProcessRoots( p ) )
{
if ( pClause->fRoot )
continue;
if ( !Int_ManProofRecordOne( p, pClause ) )
// if there is no conflict, consider learned clauses
Sto_ManForEachClause( p->pCnf, pClause )
{
RetValue = 0;
break;
if ( pClause->fRoot )
continue;
if ( !Int_ManProofRecordOne( p, pClause ) )
{
RetValue = 0;
break;
}
}
}
......@@ -970,12 +971,15 @@ int Int_ManInterpolate( Int_Man_t * p, Sto_Man_t * pCnf, int fVerbose, unsigned
p->pFile = NULL;
}
if ( fVerbose )
{
printf( "Vars = %d. Roots = %d. Learned = %d. Resol steps = %d. Ave = %.2f. Mem = %.2f Mb\n",
p->pCnf->nVars, p->pCnf->nRoots, p->pCnf->nClauses-p->pCnf->nRoots, p->Counter,
1.0*(p->Counter-p->pCnf->nRoots)/(p->pCnf->nClauses-p->pCnf->nRoots),
1.0*Sto_ManMemoryReport(p->pCnf)/(1<<20) );
p->timeTotal += clock() - clkTotal;
}
*ppResult = Int_ManTruthRead( p, p->pCnf->pTail );
return p->nVarsAB;
}
......
......@@ -1264,7 +1264,7 @@ void sat_solver_store_alloc( sat_solver * s )
void sat_solver_store_write( sat_solver * s, char * pFileName )
{
extern void Sto_ManDumpClauses( void * p, char * pFileName );
Sto_ManDumpClauses( s->pStore, pFileName );
if ( s->pStore ) Sto_ManDumpClauses( s->pStore, pFileName );
}
void sat_solver_store_free( sat_solver * s )
......@@ -1273,7 +1273,7 @@ void sat_solver_store_free( sat_solver * s )
if ( s->pStore ) Sto_ManFree( s->pStore );
s->pStore = NULL;
}
void sat_solver_store_mark_roots( sat_solver * s )
{
extern void Sto_ManMarkRoots( void * p );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment