Version abc70428

This commit is contained in:
Alan Mishchenko 2007-04-28 08:01:00 -07:00
parent c09d4d499c
commit feb8fb692e
41 changed files with 15801 additions and 103 deletions

72
abc.dsp
View File

@ -42,7 +42,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "src\base\abc" /I "src\base\abci" /I "src\base\abcs" /I "src\base\seq" /I "src\base\cmd" /I "src\base\io" /I "src\base\main" /I "src\bdd\cudd" /I "src\bdd\epd" /I "src\bdd\mtr" /I "src\bdd\parse" /I "src\bdd\dsd" /I "src\bdd\reo" /I "src\sop\ft" /I "src\sat\asat" /I "src\sat\bsat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\cut" /I "src\opt\dec" /I "src\opt\fxu" /I "src\opt\sim" /I "src\opt\rwr" /I "src\opt\kit" /I "src\opt\res" /I "src\map\fpga" /I "src\map\if" /I "src\map\mapper" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\mvc" /I "src\misc\util" /I "src\misc\npn" /I "src\misc\vec" /I "src\misc\espresso" /I "src\misc\nm" /I "src\misc\hash" /I "src\aig\ivy" /I "src\aig\hop" /I "src\aig\rwt" /I "src\aig\deco" /I "src\aig\mem" /I "src\temp\esop" /I "src\phys\place" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /FR /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "src\base\abc" /I "src\base\abci" /I "src\base\abcs" /I "src\base\seq" /I "src\base\cmd" /I "src\base\io" /I "src\base\main" /I "src\bdd\cudd" /I "src\bdd\epd" /I "src\bdd\mtr" /I "src\bdd\parse" /I "src\bdd\dsd" /I "src\bdd\reo" /I "src\sop\ft" /I "src\sat\asat" /I "src\sat\bsat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\cut" /I "src\opt\dec" /I "src\opt\fxu" /I "src\opt\sim" /I "src\opt\rwr" /I "src\opt\kit" /I "src\opt\res" /I "src\map\fpga" /I "src\map\if" /I "src\map\mapper" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\mvc" /I "src\misc\util" /I "src\misc\npn" /I "src\misc\vec" /I "src\misc\espresso" /I "src\misc\nm" /I "src\misc\hash" /I "src\aig\ivy" /I "src\aig\hop" /I "src\aig\rwt" /I "src\aig\deco" /I "src\aig\mem" /I "src\aig\dar" /I "src\temp\esop" /I "src\phys\place" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /FR /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
@ -66,7 +66,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "src\base\abc" /I "src\base\abci" /I "src\base\abcs" /I "src\base\seq" /I "src\base\cmd" /I "src\base\io" /I "src\base\main" /I "src\bdd\cudd" /I "src\bdd\epd" /I "src\bdd\mtr" /I "src\bdd\parse" /I "src\bdd\dsd" /I "src\bdd\reo" /I "src\sop\ft" /I "src\sat\asat" /I "src\sat\bsat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\cut" /I "src\opt\dec" /I "src\opt\fxu" /I "src\opt\sim" /I "src\opt\rwr" /I "src\opt\kit" /I "src\opt\res" /I "src\map\fpga" /I "src\map\if" /I "src\map\mapper" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\mvc" /I "src\misc\util" /I "src\misc\npn" /I "src\misc\vec" /I "src\misc\espresso" /I "src\misc\nm" /I "src\misc\hash" /I "src\aig\ivy" /I "src\aig\hop" /I "src\aig\rwt" /I "src\aig\deco" /I "src\aig\mem" /I "src\temp\esop" /I "src\phys\place" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /FR /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "src\base\abc" /I "src\base\abci" /I "src\base\abcs" /I "src\base\seq" /I "src\base\cmd" /I "src\base\io" /I "src\base\main" /I "src\bdd\cudd" /I "src\bdd\epd" /I "src\bdd\mtr" /I "src\bdd\parse" /I "src\bdd\dsd" /I "src\bdd\reo" /I "src\sop\ft" /I "src\sat\asat" /I "src\sat\bsat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\cut" /I "src\opt\dec" /I "src\opt\fxu" /I "src\opt\sim" /I "src\opt\rwr" /I "src\opt\kit" /I "src\opt\res" /I "src\map\fpga" /I "src\map\if" /I "src\map\mapper" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\mvc" /I "src\misc\util" /I "src\misc\npn" /I "src\misc\vec" /I "src\misc\espresso" /I "src\misc\nm" /I "src\misc\hash" /I "src\aig\ivy" /I "src\aig\hop" /I "src\aig\rwt" /I "src\aig\deco" /I "src\aig\mem" /I "src\aig\dar" /I "src\temp\esop" /I "src\phys\place" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /FR /YX /FD /GZ /c
# SUBTRACT CPP /X
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
@ -214,6 +214,10 @@ SOURCE=.\src\base\abci\abcCut.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abci\abcDar.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abci\abcDebug.c
# End Source File
# Begin Source File
@ -278,6 +282,10 @@ SOURCE=.\src\base\abci\abcMap.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abci\abcMeasure.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abci\abcMini.c
# End Source File
# Begin Source File
@ -797,6 +805,66 @@ SOURCE=.\src\aig\mem\mem.h
# PROP Default_Filter ""
# End Group
# Begin Group "dar"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\src\aig\dar\dar.h
# End Source File
# Begin Source File
SOURCE=.\src\aig\dar\darBalance.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\dar\darCheck.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\dar\darCore.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\dar\darCut.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\dar\darData.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\dar\darDfs.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\dar\darLib.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\dar\darMan.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\dar\darMem.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\dar\darObj.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\dar\darOper.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\dar\darTable.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\dar\darUtil.c
# End Source File
# End Group
# End Group
# Begin Group "bdd"

1
abc.rc
View File

@ -166,3 +166,4 @@ alias tst6 "r i10_if6.blif; st; ps; r x/rec6_16_.blif; st; rec_start; r i10_
alias bug "r pj1_if3.blif; lp"
alias table "r lutexp.baf; test"

410
src/aig/dar/dar.h Normal file
View File

@ -0,0 +1,410 @@
/**CFile****************************************************************
FileName [dar.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [DAG-aware AIG rewriting.]
Synopsis [External declarations.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: dar.h,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
#ifndef __DAR_H__
#define __DAR_H__
#ifdef __cplusplus
extern "C" {
#endif
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <time.h>
#include "vec.h"
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
typedef struct Dar_Par_t_ Dar_Par_t;
typedef struct Dar_Man_t_ Dar_Man_t;
typedef struct Dar_Obj_t_ Dar_Obj_t;
typedef struct Dar_Cut_t_ Dar_Cut_t;
typedef struct Dar_MmFixed_t_ Dar_MmFixed_t;
typedef struct Dar_MmFlex_t_ Dar_MmFlex_t;
typedef struct Dar_MmStep_t_ Dar_MmStep_t;
// the maximum number of cuts stored at a node
#define DAR_CUT_BASE 32
// object types
typedef enum {
DAR_AIG_NONE, // 0: non-existent object
DAR_AIG_CONST1, // 1: constant 1
DAR_AIG_PI, // 2: primary input
DAR_AIG_PO, // 3: primary output
DAR_AIG_BUF, // 4: buffer node
DAR_AIG_AND, // 5: AND node
DAR_AIG_EXOR, // 6: EXOR node
DAR_AIG_VOID // 7: unused object
} Dar_Type_t;
// the parameters
struct Dar_Par_t_
{
int fUpdateLevel;
int fUseZeros;
int fVerbose;
int fVeryVerbose;
};
// the AIG 4-cut
struct Dar_Cut_t_ // 8 words
{
unsigned uSign;
unsigned uTruth : 16;
unsigned nLeaves : 3;
int pLeaves[4];
unsigned char pIndices[4];
float aFlow;
};
// the AIG node
struct Dar_Obj_t_ // 8 words
{
void * pData; // misc (cuts, copy, etc)
Dar_Obj_t * pNext; // strashing table
Dar_Obj_t * pFanin0; // fanin
Dar_Obj_t * pFanin1; // fanin
unsigned long Type : 3; // object type
unsigned long fPhase : 1; // value under 000...0 pattern
unsigned long fMarkA : 1; // multipurpose mask
unsigned long fMarkB : 1; // multipurpose mask
unsigned long nRefs : 26; // reference count
unsigned Level : 24; // the level of this node
unsigned nCuts : 8; // the number of cuts
int TravId; // unique ID of last traversal involving the node
int Id; // unique ID of the node
};
// the AIG manager
struct Dar_Man_t_
{
// parameters governing rewriting
Dar_Par_t * pPars;
// AIG nodes
Vec_Ptr_t * vPis; // the array of PIs
Vec_Ptr_t * vPos; // the array of POs
Vec_Ptr_t * vObjs; // the array of all nodes (optional)
Dar_Obj_t * pConst1; // the constant 1 node
Dar_Obj_t Ghost; // the ghost node
// AIG node counters
int nObjs[DAR_AIG_VOID];// the number of objects by type
int nCreated; // the number of created objects
int nDeleted; // the number of deleted objects
// structural hash table
Dar_Obj_t ** pTable; // structural hash table
int nTableSize; // structural hash table size
// 4-input cuts of the nodes
Dar_Cut_t * pBaseCuts[DAR_CUT_BASE];
Dar_Cut_t BaseCuts[DAR_CUT_BASE];
int nBaseCuts;
int nCutsUsed;
// current rewriting step
Vec_Ptr_t * vLeavesBest; // the best set of leaves
int OutBest; // the best output (in the library)
int GainBest; // the best gain
// various data members
Dar_MmFixed_t * pMemObjs; // memory manager for objects
Dar_MmFlex_t * pMemCuts; // memory manager for cuts
Vec_Int_t * vRequired; // the required times
void * pData; // the temporary data
int nTravIds; // the current traversal ID
int fCatchExor; // enables EXOR nodes
// rewriting statistics
int nCutsBad;
int nCutsGood;
// timing statistics
int time1;
int time2;
};
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
#define DAR_MIN(a,b) (((a) < (b))? (a) : (b))
#define DAR_MAX(a,b) (((a) > (b))? (a) : (b))
#ifndef PRT
#define PRT(a,t) printf("%s = ", (a)); printf("%6.2f sec\n", (float)(t)/(float)(CLOCKS_PER_SEC))
#endif
static inline int Dar_BitWordNum( int nBits ) { return (nBits>>5) + ((nBits&31) > 0); }
static inline int Dar_TruthWordNum( int nVars ) { return nVars <= 5 ? 1 : (1 << (nVars - 5)); }
static inline int Dar_InfoHasBit( unsigned * p, int i ) { return (p[(i)>>5] & (1<<((i) & 31))) > 0; }
static inline void Dar_InfoSetBit( unsigned * p, int i ) { p[(i)>>5] |= (1<<((i) & 31)); }
static inline void Dar_InfoXorBit( unsigned * p, int i ) { p[(i)>>5] ^= (1<<((i) & 31)); }
static inline Dar_Obj_t * Dar_Regular( Dar_Obj_t * p ) { return (Dar_Obj_t *)((unsigned long)(p) & ~01); }
static inline Dar_Obj_t * Dar_Not( Dar_Obj_t * p ) { return (Dar_Obj_t *)((unsigned long)(p) ^ 01); }
static inline Dar_Obj_t * Dar_NotCond( Dar_Obj_t * p, int c ) { return (Dar_Obj_t *)((unsigned long)(p) ^ (c)); }
static inline int Dar_IsComplement( Dar_Obj_t * p ) { return (int )(((unsigned long)p) & 01); }
static inline Dar_Obj_t * Dar_ManConst0( Dar_Man_t * p ) { return Dar_Not(p->pConst1); }
static inline Dar_Obj_t * Dar_ManConst1( Dar_Man_t * p ) { return p->pConst1; }
static inline Dar_Obj_t * Dar_ManGhost( Dar_Man_t * p ) { return &p->Ghost; }
static inline Dar_Obj_t * Dar_ManPi( Dar_Man_t * p, int i ) { return (Dar_Obj_t *)Vec_PtrEntry(p->vPis, i); }
static inline Dar_Obj_t * Dar_ManPo( Dar_Man_t * p, int i ) { return (Dar_Obj_t *)Vec_PtrEntry(p->vPos, i); }
static inline Dar_Obj_t * Dar_ManObj( Dar_Man_t * p, int i ) { return p->vObjs ? (Dar_Obj_t *)Vec_PtrEntry(p->vObjs, i) : NULL; }
static inline int Dar_ManPiNum( Dar_Man_t * p ) { return p->nObjs[DAR_AIG_PI]; }
static inline int Dar_ManPoNum( Dar_Man_t * p ) { return p->nObjs[DAR_AIG_PO]; }
static inline int Dar_ManAndNum( Dar_Man_t * p ) { return p->nObjs[DAR_AIG_AND]; }
static inline int Dar_ManExorNum( Dar_Man_t * p ) { return p->nObjs[DAR_AIG_EXOR]; }
static inline int Dar_ManNodeNum( Dar_Man_t * p ) { return p->nObjs[DAR_AIG_AND]+p->nObjs[DAR_AIG_EXOR];}
static inline int Dar_ManGetCost( Dar_Man_t * p ) { return p->nObjs[DAR_AIG_AND]+3*p->nObjs[DAR_AIG_EXOR]; }
static inline int Dar_ManObjNum( Dar_Man_t * p ) { return p->nCreated - p->nDeleted; }
static inline Dar_Type_t Dar_ObjType( Dar_Obj_t * pObj ) { return (Dar_Type_t)pObj->Type; }
static inline int Dar_ObjIsNone( Dar_Obj_t * pObj ) { return pObj->Type == DAR_AIG_NONE; }
static inline int Dar_ObjIsConst1( Dar_Obj_t * pObj ) { assert(!Dar_IsComplement(pObj)); return pObj->Type == DAR_AIG_CONST1; }
static inline int Dar_ObjIsPi( Dar_Obj_t * pObj ) { return pObj->Type == DAR_AIG_PI; }
static inline int Dar_ObjIsPo( Dar_Obj_t * pObj ) { return pObj->Type == DAR_AIG_PO; }
static inline int Dar_ObjIsBuf( Dar_Obj_t * pObj ) { return pObj->Type == DAR_AIG_BUF; }
static inline int Dar_ObjIsAnd( Dar_Obj_t * pObj ) { return pObj->Type == DAR_AIG_AND; }
static inline int Dar_ObjIsExor( Dar_Obj_t * pObj ) { return pObj->Type == DAR_AIG_EXOR; }
static inline int Dar_ObjIsNode( Dar_Obj_t * pObj ) { return pObj->Type == DAR_AIG_AND || pObj->Type == DAR_AIG_EXOR; }
static inline int Dar_ObjIsTerm( Dar_Obj_t * pObj ) { return pObj->Type == DAR_AIG_PI || pObj->Type == DAR_AIG_PO || pObj->Type == DAR_AIG_CONST1; }
static inline int Dar_ObjIsHash( Dar_Obj_t * pObj ) { return pObj->Type == DAR_AIG_AND || pObj->Type == DAR_AIG_EXOR; }
static inline int Dar_ObjIsMarkA( Dar_Obj_t * pObj ) { return pObj->fMarkA; }
static inline void Dar_ObjSetMarkA( Dar_Obj_t * pObj ) { pObj->fMarkA = 1; }
static inline void Dar_ObjClearMarkA( Dar_Obj_t * pObj ) { pObj->fMarkA = 0; }
static inline void Dar_ObjSetTravId( Dar_Obj_t * pObj, int TravId ) { pObj->pData = (void *)TravId; }
static inline void Dar_ObjSetTravIdCurrent( Dar_Man_t * p, Dar_Obj_t * pObj ) { pObj->pData = (void *)p->nTravIds; }
static inline void Dar_ObjSetTravIdPrevious( Dar_Man_t * p, Dar_Obj_t * pObj ) { pObj->pData = (void *)(p->nTravIds - 1); }
static inline int Dar_ObjIsTravIdCurrent( Dar_Man_t * p, Dar_Obj_t * pObj ) { return (int )((int)pObj->pData == p->nTravIds); }
static inline int Dar_ObjIsTravIdPrevious( Dar_Man_t * p, Dar_Obj_t * pObj ) { return (int )((int)pObj->pData == p->nTravIds - 1); }
static inline int Dar_ObjTravId( Dar_Obj_t * pObj ) { return (int)pObj->pData; }
static inline int Dar_ObjPhase( Dar_Obj_t * pObj ) { return pObj->fPhase; }
static inline int Dar_ObjRefs( Dar_Obj_t * pObj ) { return pObj->nRefs; }
static inline void Dar_ObjRef( Dar_Obj_t * pObj ) { pObj->nRefs++; }
static inline void Dar_ObjDeref( Dar_Obj_t * pObj ) { assert( pObj->nRefs > 0 ); pObj->nRefs--; }
static inline void Dar_ObjClearRef( Dar_Obj_t * pObj ) { pObj->nRefs = 0; }
static inline int Dar_ObjFaninC0( Dar_Obj_t * pObj ) { return Dar_IsComplement(pObj->pFanin0); }
static inline int Dar_ObjFaninC1( Dar_Obj_t * pObj ) { return Dar_IsComplement(pObj->pFanin1); }
static inline Dar_Obj_t * Dar_ObjFanin0( Dar_Obj_t * pObj ) { return Dar_Regular(pObj->pFanin0); }
static inline Dar_Obj_t * Dar_ObjFanin1( Dar_Obj_t * pObj ) { return Dar_Regular(pObj->pFanin1); }
static inline Dar_Obj_t * Dar_ObjChild0( Dar_Obj_t * pObj ) { return pObj->pFanin0; }
static inline Dar_Obj_t * Dar_ObjChild1( Dar_Obj_t * pObj ) { return pObj->pFanin1; }
static inline Dar_Obj_t * Dar_ObjChild0Copy( Dar_Obj_t * pObj ) { assert( !Dar_IsComplement(pObj) ); return Dar_ObjFanin0(pObj)? Dar_NotCond((Dar_Obj_t *)Dar_ObjFanin0(pObj)->pData, Dar_ObjFaninC0(pObj)) : NULL; }
static inline Dar_Obj_t * Dar_ObjChild1Copy( Dar_Obj_t * pObj ) { assert( !Dar_IsComplement(pObj) ); return Dar_ObjFanin1(pObj)? Dar_NotCond((Dar_Obj_t *)Dar_ObjFanin1(pObj)->pData, Dar_ObjFaninC1(pObj)) : NULL; }
static inline int Dar_ObjLevel( Dar_Obj_t * pObj ) { return pObj->nRefs; }
static inline int Dar_ObjLevelNew( Dar_Obj_t * pObj ) { return 1 + Dar_ObjIsExor(pObj) + DAR_MAX(Dar_ObjFanin0(pObj)->Level, Dar_ObjFanin1(pObj)->Level); }
static inline int Dar_ObjFaninPhase( Dar_Obj_t * pObj ) { return Dar_Regular(pObj)->fPhase ^ Dar_IsComplement(pObj); }
static inline void Dar_ObjClean( Dar_Obj_t * pObj ) { memset( pObj, 0, sizeof(Dar_Obj_t) ); }
static inline int Dar_ObjWhatFanin( Dar_Obj_t * pObj, Dar_Obj_t * pFanin )
{
if ( Dar_ObjFanin0(pObj) == pFanin ) return 0;
if ( Dar_ObjFanin1(pObj) == pFanin ) return 1;
assert(0); return -1;
}
static inline int Dar_ObjFanoutC( Dar_Obj_t * pObj, Dar_Obj_t * pFanout )
{
if ( Dar_ObjFanin0(pFanout) == pObj ) return Dar_ObjFaninC0(pObj);
if ( Dar_ObjFanin1(pFanout) == pObj ) return Dar_ObjFaninC1(pObj);
assert(0); return -1;
}
// create the ghost of the new node
static inline Dar_Obj_t * Dar_ObjCreateGhost( Dar_Man_t * p, Dar_Obj_t * p0, Dar_Obj_t * p1, Dar_Type_t Type )
{
Dar_Obj_t * pGhost;
assert( Type != DAR_AIG_AND || !Dar_ObjIsConst1(Dar_Regular(p0)) );
assert( p1 == NULL || !Dar_ObjIsConst1(Dar_Regular(p1)) );
assert( Type == DAR_AIG_PI || Dar_Regular(p0) != Dar_Regular(p1) );
pGhost = Dar_ManGhost(p);
pGhost->Type = Type;
if ( Dar_Regular(p0)->Id < Dar_Regular(p1)->Id )
{
pGhost->pFanin0 = p0;
pGhost->pFanin1 = p1;
}
else
{
pGhost->pFanin0 = p1;
pGhost->pFanin1 = p0;
}
return pGhost;
}
// internal memory manager
static inline Dar_Obj_t * Dar_ManFetchMemory( Dar_Man_t * p )
{
extern char * Dar_MmFixedEntryFetch( Dar_MmFixed_t * p );
Dar_Obj_t * pTemp;
pTemp = (Dar_Obj_t *)Dar_MmFixedEntryFetch( p->pMemObjs );
memset( pTemp, 0, sizeof(Dar_Obj_t) );
Vec_PtrPush( p->vObjs, pTemp );
pTemp->Id = p->nCreated++;
return pTemp;
}
static inline void Dar_ManRecycleMemory( Dar_Man_t * p, Dar_Obj_t * pEntry )
{
extern void Dar_MmFixedEntryRecycle( Dar_MmFixed_t * p, char * pEntry );
pEntry->Type = DAR_AIG_NONE; // distinquishes dead node from live node
Dar_MmFixedEntryRecycle( p->pMemObjs, (char *)pEntry );
}
////////////////////////////////////////////////////////////////////////
/// ITERATORS ///
////////////////////////////////////////////////////////////////////////
// iterator over the primary inputs
#define Dar_ManForEachPi( p, pObj, i ) \
Vec_PtrForEachEntry( p->vPis, pObj, i )
// iterator over the primary outputs
#define Dar_ManForEachPo( p, pObj, i ) \
Vec_PtrForEachEntry( p->vPos, pObj, i )
// iterator over all objects, including those currently not used
#define Dar_ManForEachObj( p, pObj, i ) \
Vec_PtrForEachEntry( p->vObjs, pObj, i )
////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*=== darBalance.c ========================================================*/
extern Dar_Man_t * Dar_ManBalance( Dar_Man_t * p, int fUpdateLevel );
extern Dar_Obj_t * Dar_NodeBalanceBuildSuper( Dar_Man_t * p, Vec_Ptr_t * vSuper, Dar_Type_t Type, int fUpdateLevel );
/*=== darCheck.c ========================================================*/
extern int Dar_ManCheck( Dar_Man_t * p );
/*=== darCore.c ========================================================*/
extern int Dar_ManRewrite( Dar_Man_t * p );
/*=== darCut.c ========================================================*/
extern void Dar_ManSetupPis( Dar_Man_t * p );
extern void Dar_ObjComputeCuts_rec( Dar_Man_t * p, Dar_Obj_t * pObj );
extern void Dar_ManCutsFree( Dar_Man_t * p );
/*=== darData.c ========================================================*/
extern Vec_Int_t * Dar_LibReadNodes();
extern Vec_Int_t * Dar_LibReadOuts();
/*=== darDfs.c ==========================================================*/
extern Vec_Ptr_t * Dar_ManDfs( Dar_Man_t * p );
extern Vec_Ptr_t * Dar_ManDfsNode( Dar_Man_t * p, Dar_Obj_t * pNode );
extern int Dar_ManCountLevels( Dar_Man_t * p );
extern void Dar_ManCreateRefs( Dar_Man_t * p );
extern int Dar_DagSize( Dar_Obj_t * pObj );
extern void Dar_ConeUnmark_rec( Dar_Obj_t * pObj );
extern Dar_Obj_t * Dar_Transfer( Dar_Man_t * pSour, Dar_Man_t * pDest, Dar_Obj_t * pObj, int nVars );
extern Dar_Obj_t * Dar_Compose( Dar_Man_t * p, Dar_Obj_t * pRoot, Dar_Obj_t * pFunc, int iVar );
/*=== darLib.c ==========================================================*/
extern void Dar_LibStart();
extern void Dar_LibStop();
extern int Dar_LibEval( Dar_Man_t * p, Dar_Obj_t * pRoot, Dar_Cut_t * pCut, int Required );
extern Dar_Obj_t * Dar_LibBuildBest( Dar_Man_t * p );
/*=== darMan.c ==========================================================*/
extern Dar_Man_t * Dar_ManStart();
extern Dar_Man_t * Dar_ManDup( Dar_Man_t * p );
extern void Dar_ManStop( Dar_Man_t * p );
extern int Dar_ManCleanup( Dar_Man_t * p );
extern void Dar_ManPrintStats( Dar_Man_t * p );
/*=== darMem.c ==========================================================*/
extern void Dar_ManStartMemory( Dar_Man_t * p );
extern void Dar_ManStopMemory( Dar_Man_t * p );
/*=== darObj.c ==========================================================*/
extern Dar_Obj_t * Dar_ObjCreatePi( Dar_Man_t * p );
extern Dar_Obj_t * Dar_ObjCreatePo( Dar_Man_t * p, Dar_Obj_t * pDriver );
extern Dar_Obj_t * Dar_ObjCreate( Dar_Man_t * p, Dar_Obj_t * pGhost );
extern void Dar_ObjConnect( Dar_Man_t * p, Dar_Obj_t * pObj, Dar_Obj_t * pFan0, Dar_Obj_t * pFan1 );
extern void Dar_ObjDisconnect( Dar_Man_t * p, Dar_Obj_t * pObj );
extern void Dar_ObjDelete( Dar_Man_t * p, Dar_Obj_t * pObj );
extern void Dar_ObjDelete_rec( Dar_Man_t * p, Dar_Obj_t * pObj, int fFreeTop );
extern void Dar_ObjReplace( Dar_Man_t * p, Dar_Obj_t * pObjOld, Dar_Obj_t * pObjNew );
/*=== darOper.c =========================================================*/
extern Dar_Obj_t * Dar_IthVar( Dar_Man_t * p, int i );
extern Dar_Obj_t * Dar_Oper( Dar_Man_t * p, Dar_Obj_t * p0, Dar_Obj_t * p1, Dar_Type_t Type );
extern Dar_Obj_t * Dar_And( Dar_Man_t * p, Dar_Obj_t * p0, Dar_Obj_t * p1 );
extern Dar_Obj_t * Dar_Or( Dar_Man_t * p, Dar_Obj_t * p0, Dar_Obj_t * p1 );
extern Dar_Obj_t * Dar_Exor( Dar_Man_t * p, Dar_Obj_t * p0, Dar_Obj_t * p1 );
extern Dar_Obj_t * Dar_Mux( Dar_Man_t * p, Dar_Obj_t * pC, Dar_Obj_t * p1, Dar_Obj_t * p0 );
extern Dar_Obj_t * Dar_Maj( Dar_Man_t * p, Dar_Obj_t * pA, Dar_Obj_t * pB, Dar_Obj_t * pC );
extern Dar_Obj_t * Dar_Miter( Dar_Man_t * p, Vec_Ptr_t * vPairs );
extern Dar_Obj_t * Dar_CreateAnd( Dar_Man_t * p, int nVars );
extern Dar_Obj_t * Dar_CreateOr( Dar_Man_t * p, int nVars );
extern Dar_Obj_t * Dar_CreateExor( Dar_Man_t * p, int nVars );
/*=== darTable.c ========================================================*/
extern Dar_Obj_t * Dar_TableLookup( Dar_Man_t * p, Dar_Obj_t * pGhost );
extern void Dar_TableInsert( Dar_Man_t * p, Dar_Obj_t * pObj );
extern void Dar_TableDelete( Dar_Man_t * p, Dar_Obj_t * pObj );
extern int Dar_TableCountEntries( Dar_Man_t * p );
extern void Dar_TableProfile( Dar_Man_t * p );
/*=== darUtil.c =========================================================*/
extern Dar_Par_t * Dar_ManDefaultParams();
extern void Dar_ManIncrementTravId( Dar_Man_t * p );
extern void Dar_ManCleanData( Dar_Man_t * p );
extern void Dar_ObjCleanData_rec( Dar_Obj_t * pObj );
extern void Dar_ObjCollectMulti( Dar_Obj_t * pFunc, Vec_Ptr_t * vSuper );
extern int Dar_ObjIsMuxType( Dar_Obj_t * pObj );
extern int Dar_ObjRecognizeExor( Dar_Obj_t * pObj, Dar_Obj_t ** ppFan0, Dar_Obj_t ** ppFan1 );
extern Dar_Obj_t * Dar_ObjRecognizeMux( Dar_Obj_t * pObj, Dar_Obj_t ** ppObjT, Dar_Obj_t ** ppObjE );
extern void Dar_ObjPrintEqn( FILE * pFile, Dar_Obj_t * pObj, Vec_Vec_t * vLevels, int Level );
extern void Dar_ObjPrintVerilog( FILE * pFile, Dar_Obj_t * pObj, Vec_Vec_t * vLevels, int Level );
extern void Dar_ObjPrintVerbose( Dar_Obj_t * pObj, int fHaig );
extern void Dar_ManPrintVerbose( Dar_Man_t * p, int fHaig );
extern void Dar_ManDumpBlif( Dar_Man_t * p, char * pFileName );
/*=== darMem.c ===========================================================*/
// fixed-size-block memory manager
extern Dar_MmFixed_t * Dar_MmFixedStart( int nEntrySize, int nEntriesMax );
extern void Dar_MmFixedStop( Dar_MmFixed_t * p, int fVerbose );
extern char * Dar_MmFixedEntryFetch( Dar_MmFixed_t * p );
extern void Dar_MmFixedEntryRecycle( Dar_MmFixed_t * p, char * pEntry );
extern void Dar_MmFixedRestart( Dar_MmFixed_t * p );
extern int Dar_MmFixedReadMemUsage( Dar_MmFixed_t * p );
extern int Dar_MmFixedReadMaxEntriesUsed( Dar_MmFixed_t * p );
// flexible-size-block memory manager
extern Dar_MmFlex_t * Dar_MmFlexStart();
extern void Dar_MmFlexStop( Dar_MmFlex_t * p, int fVerbose );
extern char * Dar_MmFlexEntryFetch( Dar_MmFlex_t * p, int nBytes );
extern void Dar_MmFlexRestart( Dar_MmFlex_t * p );
extern int Dar_MmFlexReadMemUsage( Dar_MmFlex_t * p );
// hierarchical memory manager
extern Dar_MmStep_t * Dar_MmStepStart( int nSteps );
extern void Dar_MmStepStop( Dar_MmStep_t * p, int fVerbose );
extern char * Dar_MmStepEntryFetch( Dar_MmStep_t * p, int nBytes );
extern void Dar_MmStepEntryRecycle( Dar_MmStep_t * p, char * pEntry, int nBytes );
extern int Dar_MmStepReadMemUsage( Dar_MmStep_t * p );
#ifdef __cplusplus
}
#endif
#endif
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

390
src/aig/dar/darBalance.c Normal file
View File

@ -0,0 +1,390 @@
/**CFile****************************************************************
FileName [darBalance.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [DAG-aware AIG rewriting.]
Synopsis [Algebraic AIG balancing.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: darBalance.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
#include "dar.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static Dar_Obj_t * Dar_NodeBalance_rec( Dar_Man_t * pNew, Dar_Obj_t * pObj, Vec_Vec_t * vStore, int Level, int fUpdateLevel );
static Vec_Ptr_t * Dar_NodeBalanceCone( Dar_Obj_t * pObj, Vec_Vec_t * vStore, int Level );
static int Dar_NodeBalanceFindLeft( Vec_Ptr_t * vSuper );
static void Dar_NodeBalancePermute( Dar_Man_t * p, Vec_Ptr_t * vSuper, int LeftBound, int fExor );
static void Dar_NodeBalancePushUniqueOrderByLevel( Vec_Ptr_t * vStore, Dar_Obj_t * pObj );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Performs algebraic balancing of the AIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Dar_Man_t * Dar_ManBalance( Dar_Man_t * p, int fUpdateLevel )
{
Dar_Man_t * pNew;
Dar_Obj_t * pObj, * pObjNew;
Vec_Vec_t * vStore;
int i;
// create the new manager
pNew = Dar_ManStart();
// map the PI nodes
Dar_ManCleanData( p );
Dar_ManConst1(p)->pData = Dar_ManConst1(pNew);
Dar_ManForEachPi( p, pObj, i )
pObj->pData = Dar_ObjCreatePi(pNew);
// balance the AIG
vStore = Vec_VecAlloc( 50 );
Dar_ManForEachPo( p, pObj, i )
{
pObjNew = Dar_NodeBalance_rec( pNew, Dar_ObjFanin0(pObj), vStore, 0, fUpdateLevel );
Dar_ObjCreatePo( pNew, Dar_NotCond( pObjNew, Dar_ObjFaninC0(pObj) ) );
}
Vec_VecFree( vStore );
// remove dangling nodes
// Dar_ManCreateRefs( pNew );
// if ( i = Dar_ManCleanup( pNew ) )
// printf( "Cleanup after balancing removed %d dangling nodes.\n", i );
// check the resulting AIG
if ( !Dar_ManCheck(pNew) )
printf( "Dar_ManBalance(): The check has failed.\n" );
return pNew;
}
/**Function*************************************************************
Synopsis [Returns the new node constructed.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Dar_Obj_t * Dar_NodeBalance_rec( Dar_Man_t * pNew, Dar_Obj_t * pObjOld, Vec_Vec_t * vStore, int Level, int fUpdateLevel )
{
Dar_Obj_t * pObjNew;
Vec_Ptr_t * vSuper;
int i;
assert( !Dar_IsComplement(pObjOld) );
// return if the result is known
if ( pObjOld->pData )
return pObjOld->pData;
assert( Dar_ObjIsNode(pObjOld) );
// get the implication supergate
vSuper = Dar_NodeBalanceCone( pObjOld, vStore, Level );
// check if supergate contains two nodes in the opposite polarity
if ( vSuper->nSize == 0 )
return pObjOld->pData = Dar_ManConst0(pNew);
if ( Vec_PtrSize(vSuper) < 2 )
printf( "BUG!\n" );
// for each old node, derive the new well-balanced node
for ( i = 0; i < Vec_PtrSize(vSuper); i++ )
{
pObjNew = Dar_NodeBalance_rec( pNew, Dar_Regular(vSuper->pArray[i]), vStore, Level + 1, fUpdateLevel );
vSuper->pArray[i] = Dar_NotCond( pObjNew, Dar_IsComplement(vSuper->pArray[i]) );
}
// build the supergate
pObjNew = Dar_NodeBalanceBuildSuper( pNew, vSuper, Dar_ObjType(pObjOld), fUpdateLevel );
// make sure the balanced node is not assigned
// assert( pObjOld->Level >= Dar_Regular(pObjNew)->Level );
assert( pObjOld->pData == NULL );
return pObjOld->pData = pObjNew;
}
/**Function*************************************************************
Synopsis [Collects the nodes of the supergate.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Dar_NodeBalanceCone_rec( Dar_Obj_t * pRoot, Dar_Obj_t * pObj, Vec_Ptr_t * vSuper )
{
int RetValue1, RetValue2, i;
// check if the node is visited
if ( Dar_Regular(pObj)->fMarkB )
{
// check if the node occurs in the same polarity
for ( i = 0; i < vSuper->nSize; i++ )
if ( vSuper->pArray[i] == pObj )
return 1;
// check if the node is present in the opposite polarity
for ( i = 0; i < vSuper->nSize; i++ )
if ( vSuper->pArray[i] == Dar_Not(pObj) )
return -1;
assert( 0 );
return 0;
}
// if the new node is complemented or a PI, another gate begins
if ( pObj != pRoot && (Dar_IsComplement(pObj) || Dar_ObjType(pObj) != Dar_ObjType(pRoot) || Dar_ObjRefs(pObj) > 1) )
{
Vec_PtrPush( vSuper, pObj );
Dar_Regular(pObj)->fMarkB = 1;
return 0;
}
assert( !Dar_IsComplement(pObj) );
assert( Dar_ObjIsNode(pObj) );
// go through the branches
RetValue1 = Dar_NodeBalanceCone_rec( pRoot, Dar_ObjChild0(pObj), vSuper );
RetValue2 = Dar_NodeBalanceCone_rec( pRoot, Dar_ObjChild1(pObj), vSuper );
if ( RetValue1 == -1 || RetValue2 == -1 )
return -1;
// return 1 if at least one branch has a duplicate
return RetValue1 || RetValue2;
}
/**Function*************************************************************
Synopsis [Collects the nodes of the supergate.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Dar_NodeBalanceCone( Dar_Obj_t * pObj, Vec_Vec_t * vStore, int Level )
{
Vec_Ptr_t * vNodes;
int RetValue, i;
assert( !Dar_IsComplement(pObj) );
// extend the storage
if ( Vec_VecSize( vStore ) <= Level )
Vec_VecPush( vStore, Level, 0 );
// get the temporary array of nodes
vNodes = Vec_VecEntry( vStore, Level );
Vec_PtrClear( vNodes );
// collect the nodes in the implication supergate
RetValue = Dar_NodeBalanceCone_rec( pObj, pObj, vNodes );
assert( vNodes->nSize > 1 );
// unmark the visited nodes
Vec_PtrForEachEntry( vNodes, pObj, i )
Dar_Regular(pObj)->fMarkB = 0;
// if we found the node and its complement in the same implication supergate,
// return empty set of nodes (meaning that we should use constant-0 node)
if ( RetValue == -1 )
vNodes->nSize = 0;
return vNodes;
}
/**Function*************************************************************
Synopsis [Procedure used for sorting the nodes in decreasing order of levels.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Dar_NodeCompareLevelsDecrease( Dar_Obj_t ** pp1, Dar_Obj_t ** pp2 )
{
int Diff = Dar_ObjLevel(Dar_Regular(*pp1)) - Dar_ObjLevel(Dar_Regular(*pp2));
if ( Diff > 0 )
return -1;
if ( Diff < 0 )
return 1;
return 0;
}
/**Function*************************************************************
Synopsis [Builds implication supergate.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Dar_Obj_t * Dar_NodeBalanceBuildSuper( Dar_Man_t * p, Vec_Ptr_t * vSuper, Dar_Type_t Type, int fUpdateLevel )
{
Dar_Obj_t * pObj1, * pObj2;
int LeftBound;
assert( vSuper->nSize > 1 );
// sort the new nodes by level in the decreasing order
Vec_PtrSort( vSuper, Dar_NodeCompareLevelsDecrease );
// balance the nodes
while ( vSuper->nSize > 1 )
{
// find the left bound on the node to be paired
LeftBound = (!fUpdateLevel)? 0 : Dar_NodeBalanceFindLeft( vSuper );
// find the node that can be shared (if no such node, randomize choice)
Dar_NodeBalancePermute( p, vSuper, LeftBound, Type == DAR_AIG_EXOR );
// pull out the last two nodes
pObj1 = Vec_PtrPop(vSuper);
pObj2 = Vec_PtrPop(vSuper);
Dar_NodeBalancePushUniqueOrderByLevel( vSuper, Dar_Oper(p, pObj1, pObj2, Type) );
}
return Vec_PtrEntry(vSuper, 0);
}
/**Function*************************************************************
Synopsis [Finds the left bound on the next candidate to be paired.]
Description [The nodes in the array are in the decreasing order of levels.
The last node in the array has the smallest level. By default it would be paired
with the next node on the left. However, it may be possible to pair it with some
other node on the left, in such a way that the new node is shared. This procedure
finds the index of the left-most node, which can be paired with the last node.]
SideEffects []
SeeAlso []
***********************************************************************/
int Dar_NodeBalanceFindLeft( Vec_Ptr_t * vSuper )
{
Dar_Obj_t * pObjRight, * pObjLeft;
int Current;
// if two or less nodes, pair with the first
if ( Vec_PtrSize(vSuper) < 3 )
return 0;
// set the pointer to the one before the last
Current = Vec_PtrSize(vSuper) - 2;
pObjRight = Vec_PtrEntry( vSuper, Current );
// go through the nodes to the left of this one
for ( Current--; Current >= 0; Current-- )
{
// get the next node on the left
pObjLeft = Vec_PtrEntry( vSuper, Current );
// if the level of this node is different, quit the loop
if ( Dar_ObjLevel(Dar_Regular(pObjLeft)) != Dar_ObjLevel(Dar_Regular(pObjRight)) )
break;
}
Current++;
// get the node, for which the equality holds
pObjLeft = Vec_PtrEntry( vSuper, Current );
assert( Dar_ObjLevel(Dar_Regular(pObjLeft)) == Dar_ObjLevel(Dar_Regular(pObjRight)) );
return Current;
}
/**Function*************************************************************
Synopsis [Moves closer to the end the node that is best for sharing.]
Description [If there is no node with sharing, randomly chooses one of
the legal nodes.]
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_NodeBalancePermute( Dar_Man_t * p, Vec_Ptr_t * vSuper, int LeftBound, int fExor )
{
Dar_Obj_t * pObj1, * pObj2, * pObj3, * pGhost;
int RightBound, i;
// get the right bound
RightBound = Vec_PtrSize(vSuper) - 2;
assert( LeftBound <= RightBound );
if ( LeftBound == RightBound )
return;
// get the two last nodes
pObj1 = Vec_PtrEntry( vSuper, RightBound + 1 );
pObj2 = Vec_PtrEntry( vSuper, RightBound );
if ( Dar_Regular(pObj1) == p->pConst1 || Dar_Regular(pObj2) == p->pConst1 )
return;
// find the first node that can be shared
for ( i = RightBound; i >= LeftBound; i-- )
{
pObj3 = Vec_PtrEntry( vSuper, i );
if ( Dar_Regular(pObj3) == p->pConst1 )
{
Vec_PtrWriteEntry( vSuper, i, pObj2 );
Vec_PtrWriteEntry( vSuper, RightBound, pObj3 );
return;
}
pGhost = Dar_ObjCreateGhost( p, pObj1, pObj3, fExor? DAR_AIG_EXOR : DAR_AIG_AND );
if ( Dar_TableLookup( p, pGhost ) )
{
if ( pObj3 == pObj2 )
return;
Vec_PtrWriteEntry( vSuper, i, pObj2 );
Vec_PtrWriteEntry( vSuper, RightBound, pObj3 );
return;
}
}
/*
// we did not find the node to share, randomize choice
{
int Choice = rand() % (RightBound - LeftBound + 1);
pObj3 = Vec_PtrEntry( vSuper, LeftBound + Choice );
if ( pObj3 == pObj2 )
return;
Vec_PtrWriteEntry( vSuper, LeftBound + Choice, pObj2 );
Vec_PtrWriteEntry( vSuper, RightBound, pObj3 );
}
*/
}
/**Function*************************************************************
Synopsis [Inserts a new node in the order by levels.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_NodeBalancePushUniqueOrderByLevel( Vec_Ptr_t * vStore, Dar_Obj_t * pObj )
{
Dar_Obj_t * pObj1, * pObj2;
int i;
if ( Vec_PtrPushUnique(vStore, pObj) )
return;
// find the p of the node
for ( i = vStore->nSize-1; i > 0; i-- )
{
pObj1 = vStore->pArray[i ];
pObj2 = vStore->pArray[i-1];
if ( Dar_ObjLevel(Dar_Regular(pObj1)) <= Dar_ObjLevel(Dar_Regular(pObj2)) )
break;
vStore->pArray[i ] = pObj2;
vStore->pArray[i-1] = pObj1;
}
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

112
src/aig/dar/darCheck.c Normal file
View File

@ -0,0 +1,112 @@
/**CFile****************************************************************
FileName [darCheck.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [DAG-aware AIG rewriting.]
Synopsis [AIG checking procedures.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: darCheck.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
#include "dar.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Checks the consistency of the AIG manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Dar_ManCheck( Dar_Man_t * p )
{
Dar_Obj_t * pObj, * pObj2;
int i;
// check primary inputs
Dar_ManForEachPi( p, pObj, i )
{
if ( Dar_ObjFanin0(pObj) || Dar_ObjFanin1(pObj) )
{
printf( "Dar_ManCheck: The PI node \"%p\" has fanins.\n", pObj );
return 0;
}
}
// check primary outputs
Dar_ManForEachPo( p, pObj, i )
{
if ( !Dar_ObjFanin0(pObj) )
{
printf( "Dar_ManCheck: The PO node \"%p\" has NULL fanin.\n", pObj );
return 0;
}
if ( Dar_ObjFanin1(pObj) )
{
printf( "Dar_ManCheck: The PO node \"%p\" has second fanin.\n", pObj );
return 0;
}
}
// check internal nodes
Dar_ManForEachObj( p, pObj, i )
{
if ( !Dar_ObjIsNode(pObj) )
continue;
if ( !Dar_ObjFanin0(pObj) || !Dar_ObjFanin1(pObj) )
{
printf( "Dar_ManCheck: The AIG has internal node \"%p\" with a NULL fanin.\n", pObj );
return 0;
}
if ( Dar_ObjFanin0(pObj)->Id >= Dar_ObjFanin1(pObj)->Id )
{
printf( "Dar_ManCheck: The AIG has node \"%p\" with a wrong ordering of fanins.\n", pObj );
return 0;
}
pObj2 = Dar_TableLookup( p, pObj );
if ( pObj2 != pObj )
{
printf( "Dar_ManCheck: Node \"%p\" is not in the structural hashing table.\n", pObj );
return 0;
}
}
// count the total number of nodes
if ( Dar_ManObjNum(p) != 1 + Dar_ManPiNum(p) + Dar_ManPoNum(p) + Dar_ManAndNum(p) + Dar_ManExorNum(p) )
{
printf( "Dar_ManCheck: The number of created nodes is wrong.\n" );
return 0;
}
// count the number of nodes in the table
if ( Dar_TableCountEntries(p) != Dar_ManAndNum(p) + Dar_ManExorNum(p) )
{
printf( "Dar_ManCheck: The number of nodes in the structural hashing table is wrong.\n" );
return 0;
}
// if ( !Dar_ManIsAcyclic(p) )
// return 0;
return 1;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

106
src/aig/dar/darCore.c Normal file
View File

@ -0,0 +1,106 @@
/**CFile****************************************************************
FileName [darCore.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [DAG-aware AIG rewriting.]
Synopsis [Core of the rewriting package.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: darCore.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
#include "dar.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Dar_ManRewrite( Dar_Man_t * p )
{
ProgressBar * pProgress;
Dar_Obj_t * pObj, * pObjNew;
int i, k, nNodesOld, nNodeBefore, nNodeAfter, Required;
int clk = 0, clkStart = clock();
// remove dangling nodes
Dar_ManCleanup( p );
// set elementary cuts for the PIs
Dar_ManSetupPis( p );
// if ( p->pPars->fUpdateLevel )
// Dar_NtkStartReverseLevels( p );
// resynthesize each node once
nNodesOld = Vec_PtrSize( p->vObjs );
pProgress = Extra_ProgressBarStart( stdout, nNodesOld );
Dar_ManForEachObj( p, pObj, i )
{
Extra_ProgressBarUpdate( pProgress, i, NULL );
if ( !Dar_ObjIsNode(pObj) )
continue;
if ( i > nNodesOld )
break;
// compute cuts for the node
Dar_ObjComputeCuts_rec( p, pObj );
// go through the cuts of this node
Required = 1000000;
p->GainBest = -1;
for ( k = 1; k < (int)pObj->nCuts; k++ )
Dar_LibEval( p, pObj, (Dar_Cut_t *)pObj->pData + k, Required );
// check the best gain
if ( !(p->GainBest > 0 || p->GainBest == 0 && p->pPars->fUseZeros) )
continue;
// if we end up here, a rewriting step is accepted
nNodeBefore = Dar_ManNodeNum( p );
pObjNew = Dar_LibBuildBest( p );
pObjNew = Dar_NotCond( pObjNew, pObjNew->fPhase ^ pObj->fPhase );
// remove the old nodes
Dar_ObjReplace( p, pObj, pObjNew );
// compare the gains
nNodeAfter = Dar_ManNodeNum( p );
assert( p->GainBest == nNodeBefore - nNodeAfter );
assert( (int)pObjNew->Level <= Required );
}
Extra_ProgressBarStop( pProgress );
Dar_ManCutsFree( p );
// put the nodes into the DFS order and reassign their IDs
// Dar_NtkReassignIds( p );
// fix the levels
// if ( p->pPars->fUpdateLevel )
// Dar_NtkStopReverseLevels( p );
// check
if ( !Dar_ManCheck( p ) )
{
printf( "Dar_ManRewrite: The network check has failed.\n" );
return 0;
}
return 1;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

548
src/aig/dar/darCut.c Normal file
View File

@ -0,0 +1,548 @@
/**CFile****************************************************************
FileName [darCut.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [DAG-aware AIG rewriting.]
Synopsis [Computation of 4-input cuts.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: darCut.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
#include "dar.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Returns 1 if pDom is contained in pCut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Dar_CutCheckDominance( Dar_Cut_t * pDom, Dar_Cut_t * pCut )
{
int i, k;
for ( i = 0; i < (int)pDom->nLeaves; i++ )
{
for ( k = 0; k < (int)pCut->nLeaves; k++ )
if ( pDom->pLeaves[i] == pCut->pLeaves[k] )
break;
if ( k == (int)pCut->nLeaves ) // node i in pDom is not contained in pCut
return 0;
}
// every node in pDom is contained in pCut
return 1;
}
/**Function*************************************************************
Synopsis [Returns 1 if the cut is contained.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Dar_CutFilter( Dar_Man_t * p, Dar_Cut_t * pCut )
{
Dar_Cut_t * pTemp;
int i, k;
assert( p->pBaseCuts[p->nBaseCuts] == pCut );
for ( i = 0; i < p->nBaseCuts; i++ )
{
pTemp = p->pBaseCuts[i];
if ( pTemp->nLeaves > pCut->nLeaves )
{
// do not fiter the first cut
if ( i == 0 )
continue;
// skip the non-contained cuts
if ( (pTemp->uSign & pCut->uSign) != pCut->uSign )
continue;
// check containment seriously
if ( Dar_CutCheckDominance( pCut, pTemp ) )
{
// p->ppCuts[i] = p->ppCuts[p->nCuts-1];
// p->ppCuts[p->nCuts-1] = pTemp;
// p->nCuts--;
// i--;
// remove contained cut
for ( k = i; k < p->nBaseCuts; k++ )
p->pBaseCuts[k] = p->pBaseCuts[k+1];
p->pBaseCuts[p->nBaseCuts] = pTemp;
p->nBaseCuts--;
i--;
}
}
else
{
// skip the non-contained cuts
if ( (pTemp->uSign & pCut->uSign) != pTemp->uSign )
continue;
// check containment seriously
if ( Dar_CutCheckDominance( pTemp, pCut ) )
return 1;
}
}
return 0;
}
/**Function*************************************************************
Synopsis [Merges two cuts.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Dar_CutMergeOrdered( Dar_Cut_t * pC, Dar_Cut_t * pC0, Dar_Cut_t * pC1 )
{
int i, k, c;
assert( pC0->nLeaves >= pC1->nLeaves );
// the case of the largest cut sizes
if ( pC0->nLeaves == 4 && pC1->nLeaves == 4 )
{
if ( pC0->uSign != pC1->uSign )
return 0;
for ( i = 0; i < (int)pC0->nLeaves; i++ )
if ( pC0->pLeaves[i] != pC1->pLeaves[i] )
return 0;
for ( i = 0; i < (int)pC0->nLeaves; i++ )
pC->pLeaves[i] = pC0->pLeaves[i];
pC->nLeaves = pC0->nLeaves;
return 1;
}
// the case when one of the cuts is the largest
if ( pC0->nLeaves == 4 )
{
if ( (pC0->uSign & pC1->uSign) != pC1->uSign )
return 0;
for ( i = 0; i < (int)pC1->nLeaves; i++ )
{
for ( k = (int)pC0->nLeaves - 1; k >= 0; k-- )
if ( pC0->pLeaves[k] == pC1->pLeaves[i] )
break;
if ( k == -1 ) // did not find
return 0;
}
for ( i = 0; i < (int)pC0->nLeaves; i++ )
pC->pLeaves[i] = pC0->pLeaves[i];
pC->nLeaves = pC0->nLeaves;
return 1;
}
// compare two cuts with different numbers
i = k = 0;
for ( c = 0; c < 4; c++ )
{
if ( k == (int)pC1->nLeaves )
{
if ( i == (int)pC0->nLeaves )
{
pC->nLeaves = c;
return 1;
}
pC->pLeaves[c] = pC0->pLeaves[i++];
continue;
}
if ( i == (int)pC0->nLeaves )
{
if ( k == (int)pC1->nLeaves )
{
pC->nLeaves = c;
return 1;
}
pC->pLeaves[c] = pC1->pLeaves[k++];
continue;
}
if ( pC0->pLeaves[i] < pC1->pLeaves[k] )
{
pC->pLeaves[c] = pC0->pLeaves[i++];
continue;
}
if ( pC0->pLeaves[i] > pC1->pLeaves[k] )
{
pC->pLeaves[c] = pC1->pLeaves[k++];
continue;
}
pC->pLeaves[c] = pC0->pLeaves[i++];
k++;
}
if ( i < (int)pC0->nLeaves || k < (int)pC1->nLeaves )
return 0;
pC->nLeaves = c;
return 1;
}
/**Function*************************************************************
Synopsis [Prepares the object for FPGA mapping.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Dar_CutMerge( Dar_Cut_t * pCut, Dar_Cut_t * pCut0, Dar_Cut_t * pCut1 )
{
// merge the nodes
if ( pCut0->nLeaves < pCut1->nLeaves )
{
if ( !Dar_CutMergeOrdered( pCut, pCut1, pCut0 ) )
return 0;
}
else
{
if ( !Dar_CutMergeOrdered( pCut, pCut1, pCut0 ) )
return 0;
}
pCut->uSign = pCut0->uSign | pCut1->uSign;
return 1;
}
/**Function*************************************************************
Synopsis [Computes the stretching phase of the cut w.r.t. the merged cut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline unsigned Dar_CutTruthPhase( Dar_Cut_t * pCut, Dar_Cut_t * pCut1 )
{
unsigned uPhase = 0;
int i, k;
for ( i = k = 0; i < (int)pCut->nLeaves; i++ )
{
if ( k == (int)pCut1->nLeaves )
break;
if ( pCut->pLeaves[i] < pCut1->pLeaves[k] )
continue;
assert( pCut->pLeaves[i] == pCut1->pLeaves[k] );
uPhase |= (1 << i);
k++;
}
return uPhase;
}
/**Function*************************************************************
Synopsis [Swaps two advancent variables of the truth table.]
Description [Swaps variable iVar and iVar+1.]
SideEffects []
SeeAlso []
***********************************************************************/
static inline unsigned Dar_CutTruthSwapAdjacentVars( unsigned uTruth, int iVar )
{
assert( iVar >= 0 && iVar <= 2 );
if ( iVar == 0 )
return (uTruth & 0x99999999) | ((uTruth & 0x22222222) << 1) | ((uTruth & 0x44444444) >> 1);
if ( iVar == 1 )
return (uTruth & 0xC3C3C3C3) | ((uTruth & 0x0C0C0C0C) << 2) | ((uTruth & 0x30303030) >> 2);
if ( iVar == 2 )
return (uTruth & 0xF00FF00F) | ((uTruth & 0x00F000F0) << 4) | ((uTruth & 0x0F000F00) >> 4);
assert( 0 );
return 0;
}
/**Function*************************************************************
Synopsis [Expands the truth table according to the phase.]
Description [The input and output truth tables are in pIn/pOut. The current number
of variables is nVars. The total number of variables in nVarsAll. The last argument
(Phase) contains shows where the variables should go.]
SideEffects []
SeeAlso []
***********************************************************************/
static inline unsigned Dar_CutTruthStretch( unsigned uTruth, int nVars, unsigned Phase )
{
int i, k, Var = nVars - 1;
for ( i = 3; i >= 0; i-- )
if ( Phase & (1 << i) )
{
for ( k = Var; k < i; k++ )
uTruth = Dar_CutTruthSwapAdjacentVars( uTruth, k );
Var--;
}
assert( Var == -1 );
return uTruth;
}
/**Function*************************************************************
Synopsis [Shrinks the truth table according to the phase.]
Description [The input and output truth tables are in pIn/pOut. The current number
of variables is nVars. The total number of variables in nVarsAll. The last argument
(Phase) contains shows what variables should remain.]
SideEffects []
SeeAlso []
***********************************************************************/
static inline unsigned Dar_CutTruthShrink( unsigned uTruth, int nVars, unsigned Phase )
{
int i, k, Var = 0;
for ( i = 0; i < 4; i++ )
if ( Phase & (1 << i) )
{
for ( k = i-1; k >= Var; k-- )
uTruth = Dar_CutTruthSwapAdjacentVars( uTruth, k );
Var++;
}
assert( Var == nVars );
return uTruth;
}
/**Function*************************************************************
Synopsis [Performs truth table computation.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
unsigned Dar_CutTruth( Dar_Cut_t * pCut, Dar_Cut_t * pCut0, Dar_Cut_t * pCut1, int fCompl0, int fCompl1 )
{
unsigned uTruth0 = fCompl0 ? ~pCut0->uTruth : pCut0->uTruth;
unsigned uTruth1 = fCompl1 ? ~pCut1->uTruth : pCut1->uTruth;
uTruth0 = Dar_CutTruthStretch( uTruth0, pCut0->nLeaves, Dar_CutTruthPhase(pCut, pCut0) );
uTruth1 = Dar_CutTruthStretch( uTruth1, pCut1->nLeaves, Dar_CutTruthPhase(pCut, pCut1) );
return uTruth0 & uTruth1;
}
/**Function*************************************************************
Synopsis [Minimize support of the cut.]
Description [Returns 1 if the node's support has changed]
SideEffects []
SeeAlso []
***********************************************************************/
int Dar_CutSuppMinimize( Dar_Cut_t * pCut )
{
unsigned uMasks[4][2] = {
{ 0x5555, 0xAAAA },
{ 0x3333, 0xCCCC },
{ 0x0F0F, 0xF0F0 },
{ 0x00FF, 0xFF00 }
};
unsigned uPhase = 0, uTruth = 0xFFFF & pCut->uTruth;
int i, k, nLeaves;
// compute the truth support of the cut's function
nLeaves = pCut->nLeaves;
for ( i = 0; i < (int)pCut->nLeaves; i++ )
if ( (uTruth & uMasks[i][0]) == ((uTruth & uMasks[i][1]) >> (1 << i)) )
nLeaves--;
else
uPhase |= (1 << i);
if ( nLeaves == (int)pCut->nLeaves )
return 0;
// shrink the truth table
uTruth = Dar_CutTruthShrink( uTruth, pCut->nLeaves, uPhase );
pCut->uTruth = 0xFFFF & uTruth;
// update leaves and signature
pCut->uSign = 0;
for ( i = k = 0; i < (int)pCut->nLeaves; i++ )
{
if ( !(uPhase & (1 << i)) )
continue;
pCut->pLeaves[k] = pCut->pLeaves[i];
pCut->pIndices[k] = pCut->pIndices[i];
pCut->uSign |= (1 << (pCut->pLeaves[i] & 31));
k++;
}
assert( k == nLeaves );
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_ObjSetupTrivial( Dar_Obj_t * pObj )
{
Dar_Cut_t * pCut;
pCut = pObj->pData;
pCut->nLeaves = 1;
pCut->pLeaves[0] = pObj->Id;
pCut->pIndices[0] = 0;
pCut->uSign = (1 << (pObj->Id & 31));
pCut->uTruth = 0xAAAA;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_ManSetupPis( Dar_Man_t * p )
{
Dar_Obj_t * pObj;
int i;
Dar_ManForEachPi( p, pObj, i )
{
pObj->nCuts = 1;
pObj->pData = (Dar_Cut_t *)Dar_MmFlexEntryFetch( p->pMemCuts, pObj->nCuts * sizeof(Dar_Cut_t) );
Dar_ObjSetupTrivial( pObj );
}
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_ManCutsFree( Dar_Man_t * p )
{
Dar_Obj_t * pObj;
int i;
Dar_ManForEachObj( p, pObj, i )
pObj->pData = NULL;
Dar_MmFlexStop( p->pMemCuts, 0 );
p->pMemCuts = NULL;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_ObjComputeCuts( Dar_Man_t * p, Dar_Obj_t * pObj )
{
Dar_Cut_t * pCut0 = Dar_ObjFanin0(pObj)->pData;
Dar_Cut_t * pCut1 = Dar_ObjFanin1(pObj)->pData;
Dar_Cut_t * pStop0 = pCut0 + Dar_ObjFanin0(pObj)->nCuts;
Dar_Cut_t * pStop1 = pCut1 + Dar_ObjFanin1(pObj)->nCuts;
Dar_Cut_t * pCut;
int i;
assert( pObj->pData == NULL );
// make sure fanins cuts are computed
p->nCutsUsed = 0;
for ( ; pCut0 < pStop0; pCut0++ )
for ( ; pCut1 < pStop1; pCut1++ )
{
// get storage for the next cut
if ( p->nCutsUsed == p->nBaseCuts )
break;
pCut = p->pBaseCuts[p->nCutsUsed];
// create the new cut
if ( !Dar_CutMerge( pCut, pCut0, pCut1 ) )
continue;
// check dominance
if ( Dar_CutFilter( p, pCut ) )
continue;
// compute truth table
pCut->uTruth = 0xFFFF & Dar_CutTruth( pCut, pCut0, pCut1, Dar_ObjFaninC0(pObj), Dar_ObjFaninC1(pObj) );
// minimize support of the cut
if ( Dar_CutSuppMinimize( pCut ) )
Dar_CutFilter( p, pCut );
}
// get memory for the cuts of this node
pObj->nCuts = p->nCutsUsed + 1;
pObj->pData = pCut = (Dar_Cut_t *)Dar_MmFlexEntryFetch( p->pMemCuts, pObj->nCuts * sizeof(Dar_Cut_t) );
// create elementary cut
Dar_ObjSetupTrivial( pObj );
// copy non-elementary cuts
for ( i = 0; i < p->nCutsUsed; i++ )
*++pCut = *(p->pBaseCuts[i]);
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_ObjComputeCuts_rec( Dar_Man_t * p, Dar_Obj_t * pObj )
{
if ( pObj->pData )
return;
Dar_ObjComputeCuts_rec( p, Dar_ObjFanin0(pObj) );
Dar_ObjComputeCuts_rec( p, Dar_ObjFanin1(pObj) );
Dar_ObjComputeCuts( p, pObj );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

9603
src/aig/dar/darData.c Normal file

File diff suppressed because it is too large Load Diff

363
src/aig/dar/darDfs.c Normal file
View File

@ -0,0 +1,363 @@
/**CFile****************************************************************
FileName [darDfs.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [DAG-aware AIG rewriting.]
Synopsis [DFS traversal procedures.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: darDfs.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
#include "dar.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Collects internal nodes in the DFS order.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_ManDfs_rec( Dar_Obj_t * pObj, Vec_Ptr_t * vNodes )
{
assert( !Dar_IsComplement(pObj) );
if ( !Dar_ObjIsNode(pObj) || Dar_ObjIsMarkA(pObj) )
return;
Dar_ManDfs_rec( Dar_ObjFanin0(pObj), vNodes );
Dar_ManDfs_rec( Dar_ObjFanin1(pObj), vNodes );
assert( !Dar_ObjIsMarkA(pObj) ); // loop detection
Dar_ObjSetMarkA(pObj);
Vec_PtrPush( vNodes, pObj );
}
/**Function*************************************************************
Synopsis [Collects internal nodes in the DFS order.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Dar_ManDfs( Dar_Man_t * p )
{
Vec_Ptr_t * vNodes;
Dar_Obj_t * pObj;
int i;
vNodes = Vec_PtrAlloc( Dar_ManNodeNum(p) );
Dar_ManForEachObj( p, pObj, i )
Dar_ManDfs_rec( pObj, vNodes );
Dar_ManForEachObj( p, pObj, i )
Dar_ObjClearMarkA(pObj);
return vNodes;
}
/**Function*************************************************************
Synopsis [Collects internal nodes in the DFS order.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Dar_ManDfsNode( Dar_Man_t * p, Dar_Obj_t * pNode )
{
Vec_Ptr_t * vNodes;
Dar_Obj_t * pObj;
int i;
assert( !Dar_IsComplement(pNode) );
vNodes = Vec_PtrAlloc( 16 );
Dar_ManDfs_rec( pNode, vNodes );
Vec_PtrForEachEntry( vNodes, pObj, i )
Dar_ObjClearMarkA(pObj);
return vNodes;
}
/**Function*************************************************************
Synopsis [Computes the max number of levels in the manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Dar_ManCountLevels( Dar_Man_t * p )
{
Vec_Ptr_t * vNodes;
Dar_Obj_t * pObj;
int i, LevelsMax, Level0, Level1;
// initialize the levels
Dar_ManConst1(p)->pData = NULL;
Dar_ManForEachPi( p, pObj, i )
pObj->pData = NULL;
// compute levels in a DFS order
vNodes = Dar_ManDfs( p );
Vec_PtrForEachEntry( vNodes, pObj, i )
{
Level0 = (int)Dar_ObjFanin0(pObj)->pData;
Level1 = (int)Dar_ObjFanin1(pObj)->pData;
pObj->pData = (void *)(1 + Dar_ObjIsExor(pObj) + DAR_MAX(Level0, Level1));
}
Vec_PtrFree( vNodes );
// get levels of the POs
LevelsMax = 0;
Dar_ManForEachPo( p, pObj, i )
LevelsMax = DAR_MAX( LevelsMax, (int)Dar_ObjFanin0(pObj)->pData );
return LevelsMax;
}
/**Function*************************************************************
Synopsis [Counts the number of AIG nodes rooted at this cone.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_ConeMark_rec( Dar_Obj_t * pObj )
{
assert( !Dar_IsComplement(pObj) );
if ( !Dar_ObjIsNode(pObj) || Dar_ObjIsMarkA(pObj) )
return;
Dar_ConeMark_rec( Dar_ObjFanin0(pObj) );
Dar_ConeMark_rec( Dar_ObjFanin1(pObj) );
assert( !Dar_ObjIsMarkA(pObj) ); // loop detection
Dar_ObjSetMarkA( pObj );
}
/**Function*************************************************************
Synopsis [Counts the number of AIG nodes rooted at this cone.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_ConeCleanAndMark_rec( Dar_Obj_t * pObj )
{
assert( !Dar_IsComplement(pObj) );
if ( !Dar_ObjIsNode(pObj) || Dar_ObjIsMarkA(pObj) )
return;
Dar_ConeCleanAndMark_rec( Dar_ObjFanin0(pObj) );
Dar_ConeCleanAndMark_rec( Dar_ObjFanin1(pObj) );
assert( !Dar_ObjIsMarkA(pObj) ); // loop detection
Dar_ObjSetMarkA( pObj );
pObj->pData = NULL;
}
/**Function*************************************************************
Synopsis [Counts the number of AIG nodes rooted at this cone.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Dar_ConeCountAndMark_rec( Dar_Obj_t * pObj )
{
int Counter;
assert( !Dar_IsComplement(pObj) );
if ( !Dar_ObjIsNode(pObj) || Dar_ObjIsMarkA(pObj) )
return 0;
Counter = 1 + Dar_ConeCountAndMark_rec( Dar_ObjFanin0(pObj) ) +
Dar_ConeCountAndMark_rec( Dar_ObjFanin1(pObj) );
assert( !Dar_ObjIsMarkA(pObj) ); // loop detection
Dar_ObjSetMarkA( pObj );
return Counter;
}
/**Function*************************************************************
Synopsis [Counts the number of AIG nodes rooted at this cone.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_ConeUnmark_rec( Dar_Obj_t * pObj )
{
assert( !Dar_IsComplement(pObj) );
if ( !Dar_ObjIsNode(pObj) || !Dar_ObjIsMarkA(pObj) )
return;
Dar_ConeUnmark_rec( Dar_ObjFanin0(pObj) );
Dar_ConeUnmark_rec( Dar_ObjFanin1(pObj) );
assert( Dar_ObjIsMarkA(pObj) ); // loop detection
Dar_ObjClearMarkA( pObj );
}
/**Function*************************************************************
Synopsis [Counts the number of AIG nodes rooted at this cone.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Dar_DagSize( Dar_Obj_t * pObj )
{
int Counter;
Counter = Dar_ConeCountAndMark_rec( Dar_Regular(pObj) );
Dar_ConeUnmark_rec( Dar_Regular(pObj) );
return Counter;
}
/**Function*************************************************************
Synopsis [Transfers the AIG from one manager into another.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_Transfer_rec( Dar_Man_t * pDest, Dar_Obj_t * pObj )
{
assert( !Dar_IsComplement(pObj) );
if ( !Dar_ObjIsNode(pObj) || Dar_ObjIsMarkA(pObj) )
return;
Dar_Transfer_rec( pDest, Dar_ObjFanin0(pObj) );
Dar_Transfer_rec( pDest, Dar_ObjFanin1(pObj) );
pObj->pData = Dar_And( pDest, Dar_ObjChild0Copy(pObj), Dar_ObjChild1Copy(pObj) );
assert( !Dar_ObjIsMarkA(pObj) ); // loop detection
Dar_ObjSetMarkA( pObj );
}
/**Function*************************************************************
Synopsis [Transfers the AIG from one manager into another.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Dar_Obj_t * Dar_Transfer( Dar_Man_t * pSour, Dar_Man_t * pDest, Dar_Obj_t * pRoot, int nVars )
{
Dar_Obj_t * pObj;
int i;
// solve simple cases
if ( pSour == pDest )
return pRoot;
if ( Dar_ObjIsConst1( Dar_Regular(pRoot) ) )
return Dar_NotCond( Dar_ManConst1(pDest), Dar_IsComplement(pRoot) );
// set the PI mapping
Dar_ManForEachPi( pSour, pObj, i )
{
if ( i == nVars )
break;
pObj->pData = Dar_IthVar(pDest, i);
}
// transfer and set markings
Dar_Transfer_rec( pDest, Dar_Regular(pRoot) );
// clear the markings
Dar_ConeUnmark_rec( Dar_Regular(pRoot) );
return Dar_NotCond( Dar_Regular(pRoot)->pData, Dar_IsComplement(pRoot) );
}
/**Function*************************************************************
Synopsis [Composes the AIG (pRoot) with the function (pFunc) using PI var (iVar).]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_Compose_rec( Dar_Man_t * p, Dar_Obj_t * pObj, Dar_Obj_t * pFunc, Dar_Obj_t * pVar )
{
assert( !Dar_IsComplement(pObj) );
if ( Dar_ObjIsMarkA(pObj) )
return;
if ( Dar_ObjIsConst1(pObj) || Dar_ObjIsPi(pObj) )
{
pObj->pData = pObj == pVar ? pFunc : pObj;
return;
}
Dar_Compose_rec( p, Dar_ObjFanin0(pObj), pFunc, pVar );
Dar_Compose_rec( p, Dar_ObjFanin1(pObj), pFunc, pVar );
pObj->pData = Dar_And( p, Dar_ObjChild0Copy(pObj), Dar_ObjChild1Copy(pObj) );
assert( !Dar_ObjIsMarkA(pObj) ); // loop detection
Dar_ObjSetMarkA( pObj );
}
/**Function*************************************************************
Synopsis [Composes the AIG (pRoot) with the function (pFunc) using PI var (iVar).]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Dar_Obj_t * Dar_Compose( Dar_Man_t * p, Dar_Obj_t * pRoot, Dar_Obj_t * pFunc, int iVar )
{
// quit if the PI variable is not defined
if ( iVar >= Dar_ManPiNum(p) )
{
printf( "Dar_Compose(): The PI variable %d is not defined.\n", iVar );
return NULL;
}
// recursively perform composition
Dar_Compose_rec( p, Dar_Regular(pRoot), pFunc, Dar_ManPi(p, iVar) );
// clear the markings
Dar_ConeUnmark_rec( Dar_Regular(pRoot) );
return Dar_NotCond( Dar_Regular(pRoot)->pData, Dar_IsComplement(pRoot) );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

668
src/aig/dar/darLib.c Normal file
View File

@ -0,0 +1,668 @@
/**CFile****************************************************************
FileName [darLib.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [DAG-aware AIG rewriting.]
Synopsis [Library of AIG subgraphs used for rewriting.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: darLib.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
#include "dar.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
typedef struct Dar_Lib_t_ Dar_Lib_t;
typedef struct Dar_LibObj_t_ Dar_LibObj_t;
typedef struct Dar_LibDat_t_ Dar_LibDat_t;
struct Dar_LibObj_t_ // library object (2 words)
{
unsigned Fan0 : 16; // the first fanin
unsigned Fan1 : 16; // the second fanin
unsigned fCompl0 : 1; // the first compl attribute
unsigned fCompl1 : 1; // the second compl attribute
unsigned fPhase : 1; // the phase of the node
unsigned fTerm : 1; // indicates a PI
unsigned Num : 28; // internal use
};
struct Dar_LibDat_t_ // library object data
{
Dar_Obj_t * pFunc; // the corresponding AIG node
int Level;
int TravId;
float aFlow;
unsigned char Area;
unsigned char nLats[3];
};
struct Dar_Lib_t_ // library
{
// objects
Dar_LibObj_t * pObjs; // the set of library objects
int nObjs; // the number of objects used
int iObj; // the current object
// object data
Dar_LibDat_t * pDatas;
int nDatas;
// structures by class
int nSubgr[222]; // the number of subgraphs by class
int * pSubgr[222]; // the subgraphs for each class
int * pSubgrMem; // memory for subgraph pointers
int pSubgrTotal; // the total number of subgraph
// nodes by class
int nNodes[222]; // the number of nodes by class
int * pNodes[222]; // the nodes for each class
int * pNodesMem; // memory for nodes pointers
int pNodesTotal; // the total number of nodes
// information by NPN classes
char ** pPerms4;
unsigned short * puCanons;
char * pPhases;
char * pPerms;
unsigned char * pMap;
};
static Dar_Lib_t * s_DarLib = NULL;
static inline Dar_LibObj_t * Dar_LibObj( Dar_Lib_t * p, int Id ) { return p->pObjs + Id; }
static inline int Dar_LibObjTruth( Dar_LibObj_t * pObj ) { return pObj->Num < (0xFFFF & ~pObj->Num) ? pObj->Num : (0xFFFF & ~pObj->Num); }
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Starts the library.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Dar_Lib_t * Dar_LibAlloc( int nObjs, int nDatas )
{
unsigned uTruths[4] = { 0xAAAA, 0xCCCC, 0xF0F0, 0xFF00 };
Dar_Lib_t * p;
int i, clk = clock();
p = ALLOC( Dar_Lib_t, 1 );
memset( p, 0, sizeof(Dar_Lib_t) );
// allocate objects
p->nObjs = nObjs;
p->pObjs = ALLOC( Dar_LibObj_t, nObjs );
memset( p->pObjs, 0, sizeof(Dar_LibObj_t) * nObjs );
// allocate datas
p->nDatas = nDatas;
p->pDatas = ALLOC( Dar_LibDat_t, nDatas );
memset( p->pObjs, 0, sizeof(Dar_LibDat_t) * nDatas );
// allocate canonical data
p->pPerms4 = Extra_Permutations( 4 );
Extra_Truth4VarNPN( &p->puCanons, &p->pPhases, &p->pPerms, &p->pMap );
// start the elementary objects
p->iObj = 4;
for ( i = 0; i < 4; i++ )
{
p->pObjs[i].fTerm = 1;
p->pObjs[i].Num = uTruths[i];
}
// PRT( "Library start", clock() - clk );
return p;
}
/**Function*************************************************************
Synopsis [Frees the library.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_LibFree( Dar_Lib_t * p )
{
free( p->pObjs );
free( p->pDatas );
free( p->pSubgrMem );
free( p->pPerms4 );
free( p->puCanons );
free( p->pPhases );
free( p->pPerms );
free( p->pMap );
free( p );
}
/**Function*************************************************************
Synopsis [Adds one AND to the library.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_LibAddNode( Dar_Lib_t * p, int Id0, int Id1, int fCompl0, int fCompl1 )
{
Dar_LibObj_t * pFan0 = Dar_LibObj( p, Id0 );
Dar_LibObj_t * pFan1 = Dar_LibObj( p, Id1 );
Dar_LibObj_t * pObj = p->pObjs + p->iObj++;
pObj->Fan0 = Id0;
pObj->Fan1 = Id1;
pObj->fCompl0 = fCompl0;
pObj->fCompl1 = fCompl1;
pObj->fPhase = (fCompl0 ^ pFan0->fPhase) & (fCompl1 ^ pFan1->fPhase);
pObj->Num = 0xFFFF & (fCompl0? ~pFan0->Num : pFan0->Num) & (fCompl1? ~pFan1->Num : pFan1->Num);
}
/**Function*************************************************************
Synopsis [Adds one AND to the library.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_LibSetup_rec( Dar_Lib_t * p, Dar_LibObj_t * pObj, int Class )
{
if ( pObj->fTerm || (int)pObj->Num == Class )
return;
pObj->Num = Class;
Dar_LibSetup_rec( p, Dar_LibObj(p, pObj->Fan0), Class );
Dar_LibSetup_rec( p, Dar_LibObj(p, pObj->Fan1), Class );
if ( p->pNodesMem )
p->pNodes[Class][ p->nNodes[Class]++ ] = pObj-p->pObjs;
else
p->nNodes[Class]++;
}
/**Function*************************************************************
Synopsis [Adds one AND to the library.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_LibSetup( Dar_Lib_t * p, Vec_Int_t * vOuts )
{
Dar_LibObj_t * pObj;
int uTruth, Class, Out, i, k;
assert( p->iObj == p->nObjs );
// count the number of representatives of each class
for ( i = 0; i < 222; i++ )
p->nSubgr[i] = p->nNodes[i] = 0;
Vec_IntForEachEntry( vOuts, Out, i )
{
pObj = Dar_LibObj( p, Out );
uTruth = Dar_LibObjTruth( pObj );
Class = p->pMap[uTruth];
p->nSubgr[Class]++;
}
// allocate memory for the roots of each class
p->pSubgrMem = ALLOC( int, Vec_IntSize(vOuts) );
p->pSubgrTotal = 0;
for ( i = 0; i < 222; i++ )
{
p->pSubgr[i] = p->pSubgrMem + p->pSubgrTotal;
p->pSubgrTotal += p->nSubgr[i];
p->nSubgr[i] = 0;
}
assert( p->pSubgrTotal == Vec_IntSize(vOuts) );
// add the outputs to storage
Vec_IntForEachEntry( vOuts, Out, i )
{
pObj = Dar_LibObj( p, Out );
uTruth = Dar_LibObjTruth( pObj );
Class = p->pMap[uTruth];
p->pSubgr[Class][ p->nSubgr[Class]++ ] = Out;
}
// clear truth tables
for ( i = 0; i < p->iObj; i++ )
Dar_LibObj( p, Out )->Num = 0xff;
// count nodes in each class
for ( i = 0; i < 222; i++ )
for ( k = 0; k < p->nSubgr[i]; k++ )
Dar_LibSetup_rec( p, Dar_LibObj(p, p->pSubgr[i][k]), i );
// count the total number of nodes
p->pNodesTotal = 0;
for ( i = 0; i < 222; i++ )
p->pNodesTotal += p->nNodes[i];
// allocate memory for the nodes of each class
p->pNodesMem = ALLOC( int, p->pNodesTotal );
p->pNodesTotal = 0;
for ( i = 0; i < 222; i++ )
{
p->pNodes[i] = p->pNodesMem + p->pNodesTotal;
p->pNodesTotal += p->nNodes[i];
p->nNodes[i] = 0;
}
// add the nodes to storage
for ( i = 0; i < 222; i++ )
for ( k = 0; k < p->nSubgr[i]; k++ )
Dar_LibSetup_rec( p, Dar_LibObj(p, p->pSubgr[i][k]), i );
}
/**Function*************************************************************
Synopsis [Reads library from array.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Dar_Lib_t * Dar_LibRead()
{
Vec_Int_t * vObjs, * vOuts;
Dar_Lib_t * p;
int i;
// read nodes and outputs
vObjs = Dar_LibReadNodes();
vOuts = Dar_LibReadOuts();
// create library
p = Dar_LibAlloc( Vec_IntSize(vObjs)/2 + 4, 5000 );
// create nodes
for ( i = 0; i < vObjs->nSize; i += 2 )
Dar_LibAddNode( p, vObjs->pArray[i] >> 1, vObjs->pArray[i+1] >> 1,
vObjs->pArray[i] & 1, vObjs->pArray[i+1] & 1 );
// create outputs
Dar_LibSetup( p, vOuts );
Vec_IntFree( vObjs );
Vec_IntFree( vOuts );
return p;
}
/**Function*************************************************************
Synopsis [Starts the library.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_LibStart()
{
int clk = clock();
assert( s_DarLib == NULL );
s_DarLib = Dar_LibRead();
printf( "The 4-input library started with %d nodes and %d subgraphs. ", s_DarLib->nObjs - 4, s_DarLib->pSubgrTotal );
PRT( "Time", clock() - clk );
}
/**Function*************************************************************
Synopsis [Stops the library.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_LibStop()
{
assert( s_DarLib != NULL );
Dar_LibFree( s_DarLib );
s_DarLib = NULL;
}
/**Function*************************************************************
Synopsis [Matches the cut with its canonical form.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Dar_LibCutMatch( Dar_Man_t * p, Dar_Cut_t * pCut )
{
Dar_Obj_t * pFanin;
unsigned uPhase;
char * pPerm;
int i;
assert( pCut->nLeaves == 4 );
// get the fanin permutation
uPhase = s_DarLib->pPhases[pCut->uTruth];
pPerm = s_DarLib->pPerms4[ s_DarLib->pPerms[pCut->uTruth] ];
// collect fanins with the corresponding permutation/phase
for ( i = 0; i < (int)pCut->nLeaves; i++ )
{
pFanin = Dar_ManObj( p, pCut->pLeaves[pPerm[i]] );
if ( pFanin == NULL )
{
p->nCutsBad++;
return 0;
}
pFanin = Dar_NotCond(pFanin, ((uPhase & (1<<i)) > 0) );
// Vec_PtrWriteEntry( p->vFaninsCur, i, pFanin );
s_DarLib->pDatas[i].pFunc = pFanin;
s_DarLib->pDatas[i].Level = Dar_Regular(pFanin)->Level;
}
p->nCutsGood++;
return 1;
}
/**Function*************************************************************
Synopsis [Dereferences the node's MFFC.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Dar_NodeDeref_rec( Dar_Man_t * p, Dar_Obj_t * pNode )
{
Dar_Obj_t * pFanin;
int Counter = 1;
if ( Dar_ObjIsPi(pNode) )
return 0;
pFanin = Dar_ObjFanin0( pNode );
assert( pFanin->nRefs > 0 );
if ( --pFanin->nRefs == 0 )
Counter += Dar_NodeDeref_rec( p, pFanin );
pFanin = Dar_ObjFanin0( pNode );
assert( pFanin->nRefs > 0 );
if ( --pFanin->nRefs == 0 )
Counter += Dar_NodeDeref_rec( p, pFanin );
return Counter;
}
/**Function*************************************************************
Synopsis [References the node's MFFC.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Dar_NodeRef_rec( Dar_Man_t * p, Dar_Obj_t * pNode )
{
Dar_Obj_t * pFanin;
int Counter = 1;
if ( Dar_ObjIsPi(pNode) )
return 0;
Dar_ObjSetTravIdCurrent( p, pNode );
pFanin = Dar_ObjFanin0( pNode );
if ( pFanin->nRefs++ == 0 )
Counter += Dar_NodeRef_rec( p, pFanin );
pFanin = Dar_ObjFanin1( pNode );
if ( pFanin->nRefs++ == 0 )
Counter += Dar_NodeRef_rec( p, pFanin );
return Counter;
}
/**Function*************************************************************
Synopsis [Marks the MFFC of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Dar_LibCutMarkMffc( Dar_Man_t * p, Dar_Obj_t * pRoot )
{
int i, nNodes1, nNodes2;
// mark the cut leaves
for ( i = 0; i < 4; i++ )
Dar_Regular(s_DarLib->pDatas[i].pFunc)->nRefs++;
// label MFFC with current ID
Dar_ManIncrementTravId( p );
nNodes1 = Dar_NodeDeref_rec( p, pRoot );
nNodes2 = Dar_NodeRef_rec( p, pRoot );
assert( nNodes1 == nNodes2 );
// unmark the cut leaves
for ( i = 0; i < 4; i++ )
Dar_Regular(s_DarLib->pDatas[i].pFunc)->nRefs--;
return nNodes1;
}
/**Function*************************************************************
Synopsis [Assigns numbers to the nodes of one class.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_LibEvalAssignNums( Dar_Man_t * p, int Class )
{
Dar_LibObj_t * pObj;
Dar_LibDat_t * pData;
Dar_Obj_t * pFanin0, * pFanin1, * pGhost;
int i;
for ( i = 0; i < 4; i++ )
{
pObj = Dar_LibObj(s_DarLib, i);
pObj->Num = i;
}
for ( i = 0; i < s_DarLib->nNodes[Class]; i++ )
{
pObj = Dar_LibObj(s_DarLib, s_DarLib->pNodes[Class][i]);
pObj->Num = 4 + i;
pData = s_DarLib->pDatas + pObj->Num;
pData->pFunc = NULL;
pData->TravId = 0xFFFF;
/*
// get the first fanin
pFan = Dar_LibObj(p, pObj->Fan0);
s_DarLib->pDatas[i].Level = s_DarLib->pDatas[pFan->Num].Level;
pFan = Dar_LibObj(p, pObj->Fan1);
if ( s_DarLib->pDatas[i].Level < s_DarLib->pDatas[pFan->Num].Level )
s_DarLib->pDatas[i].Level = s_DarLib->pDatas[pFan->Num].Level;
s_DarLib->pDatas[i].Level++;
*/
pFanin0 = s_DarLib->pDatas[ Dar_LibObj(s_DarLib, pObj->Fan0)->Num ].pFunc;
if ( pFanin0 == NULL )
continue;
pFanin1 = s_DarLib->pDatas[ Dar_LibObj(s_DarLib, pObj->Fan1)->Num ].pFunc;
if ( pFanin1 == NULL )
continue;
pFanin0 = Dar_NotCond( pFanin0, pObj->fCompl0 );
pFanin1 = Dar_NotCond( pFanin1, pObj->fCompl1 );
pGhost = Dar_ObjCreateGhost( p, pFanin0, pFanin1, DAR_AIG_AND );
pData->pFunc = Dar_TableLookup( p, pGhost );
// clear the node if it is part of MFFC
if ( pData->pFunc != NULL && Dar_ObjIsTravIdCurrent(p, pData->pFunc) )
pData->pFunc = NULL;
}
}
/**Function*************************************************************
Synopsis [Evaluates one cut.]
Description [Returns the best gain.]
SideEffects []
SeeAlso []
***********************************************************************/
int Dar_LibEval_rec( Dar_LibObj_t * pObj, int Out, int nNodesSaved, int Required )
{
Dar_LibDat_t * pData;
int Area;
if ( pObj->fTerm )
return 0;
pData = s_DarLib->pDatas + pObj->Num;
if ( pData->pFunc )
return 0;
if ( pData->Level > Required )
return 0xff;
if ( pData->TravId == Out )
return pData->Area;
pData->TravId = Out;
Area = 1 + Dar_LibEval_rec( Dar_LibObj(s_DarLib, pObj->Fan0), Out, nNodesSaved, Required );
if ( Area > nNodesSaved )
return pData->Area = 0xff;
Area += Dar_LibEval_rec( Dar_LibObj(s_DarLib, pObj->Fan1), Out, nNodesSaved, Required );
if ( Area > nNodesSaved )
return pData->Area = 0xff;
return pData->Area = Area;
}
/**Function*************************************************************
Synopsis [Evaluates one cut.]
Description [Returns the best gain.]
SideEffects []
SeeAlso []
***********************************************************************/
int Dar_LibEval( Dar_Man_t * p, Dar_Obj_t * pRoot, Dar_Cut_t * pCut, int Required )
{
Dar_LibObj_t * pObj;
int i, k, Class, nNodesSaved, nNodesAdded, nNodesGained;
// check if the cut exits
if ( !Dar_LibCutMatch(p, pCut) )
return p->GainBest;
// mark MFFC of the node
nNodesSaved = Dar_LibCutMarkMffc( p, pRoot );
// evaluate the cut
Class = s_DarLib->pMap[pCut->uTruth];
Dar_LibEvalAssignNums( p, Class );
// profile outputs by their savings
for ( i = 0; i < s_DarLib->nSubgr[Class]; i++ )
{
pObj = Dar_LibObj(s_DarLib, s_DarLib->pSubgr[Class][i]);
nNodesAdded = Dar_LibEval_rec( pObj, i, nNodesSaved, Required );
nNodesGained = nNodesSaved - nNodesAdded;
if ( nNodesGained <= 0 )
continue;
if ( nNodesGained <= p->GainBest )
continue;
// remember this possibility
Vec_PtrClear( p->vLeavesBest );
for ( k = 0; k < 4; k++ )
Vec_PtrPush( p->vLeavesBest, s_DarLib->pDatas[k].pFunc );
p->OutBest = s_DarLib->pSubgr[Class][i];
p->GainBest = nNodesGained;
}
return p->GainBest;
}
/**Function*************************************************************
Synopsis [Reconstructs the best cut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_LibBuildClear_rec( Dar_LibObj_t * pObj )
{
if ( pObj->fTerm )
return;
s_DarLib->pDatas[ pObj->Num ].pFunc = NULL;
Dar_LibBuildClear_rec( Dar_LibObj(s_DarLib, pObj->Fan0) );
Dar_LibBuildClear_rec( Dar_LibObj(s_DarLib, pObj->Fan1) );
}
/**Function*************************************************************
Synopsis [Reconstructs the best cut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Dar_Obj_t * Dar_LibBuildBest_rec( Dar_Man_t * p, Dar_LibObj_t * pObj )
{
Dar_Obj_t * pFanin0, * pFanin1;
Dar_LibDat_t * pData = s_DarLib->pDatas + pObj->Num;
if ( pData->pFunc )
return pData->pFunc;
pFanin0 = Dar_LibBuildBest_rec( p, Dar_LibObj(s_DarLib, pObj->Fan0) );
pFanin1 = Dar_LibBuildBest_rec( p, Dar_LibObj(s_DarLib, pObj->Fan1) );
pFanin0 = Dar_NotCond( pFanin0, pObj->fCompl0 );
pFanin1 = Dar_NotCond( pFanin1, pObj->fCompl1 );
return pData->pFunc = Dar_And( p, pFanin0, pFanin1 );
}
/**Function*************************************************************
Synopsis [Reconstructs the best cut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Dar_Obj_t * Dar_LibBuildBest( Dar_Man_t * p )
{
int i;
for ( i = 0; i < 4; i++ )
s_DarLib->pDatas[i].pFunc = Vec_PtrEntry( p->vLeavesBest, i );
Dar_LibBuildClear_rec( Dar_LibObj(s_DarLib, p->OutBest) );
return Dar_LibBuildBest_rec( p, Dar_LibObj(s_DarLib, p->OutBest) );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

169
src/aig/dar/darMan.c Normal file
View File

@ -0,0 +1,169 @@
/**CFile****************************************************************
FileName [darMan.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [DAG-aware AIG rewriting.]
Synopsis [AIG manager.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: darMan.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
#include "dar.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Starts the AIG manager.]
Description [The argument of this procedure is a soft limit on the
the number of nodes, or 0 if the limit is unknown.]
SideEffects []
SeeAlso []
***********************************************************************/
Dar_Man_t * Dar_ManStart( int nNodesMax )
{
Dar_Man_t * p;
int i;
if ( nNodesMax <= 0 )
nNodesMax = 10007;
// start the manager
p = ALLOC( Dar_Man_t, 1 );
memset( p, 0, sizeof(Dar_Man_t) );
// perform initializations
p->nTravIds = 1;
p->fCatchExor = 0;
// allocate arrays for nodes
p->vPis = Vec_PtrAlloc( 100 );
p->vPos = Vec_PtrAlloc( 100 );
// prepare the internal memory manager
p->pMemObjs = Dar_MmFixedStart( sizeof(Dar_Obj_t), nNodesMax );
p->pMemCuts = Dar_MmFlexStart();
// prepare storage for cuts
p->nBaseCuts = DAR_CUT_BASE;
for ( i = 0; i < p->nBaseCuts; i++ )
p->pBaseCuts[i] = p->BaseCuts + i;
// create the constant node
p->pConst1 = Dar_ManFetchMemory( p );
p->pConst1->Type = DAR_AIG_CONST1;
p->pConst1->fPhase = 1;
p->nCreated = 1;
// start the table
p->nTableSize = nNodesMax;
p->pTable = ALLOC( Dar_Obj_t *, p->nTableSize );
memset( p->pTable, 0, sizeof(Dar_Obj_t *) * p->nTableSize );
// other data
p->vLeavesBest = Vec_PtrAlloc( 4 );
return p;
}
/**Function*************************************************************
Synopsis [Stops the AIG manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_ManStop( Dar_Man_t * p )
{
Dar_Obj_t * pObj;
int i;
// make sure the nodes have clean marks
Dar_ManForEachObj( p, pObj, i )
assert( !pObj->fMarkA && !pObj->fMarkB );
// print time
if ( p->time1 ) { PRT( "time1", p->time1 ); }
if ( p->time2 ) { PRT( "time2", p->time2 ); }
// Dar_TableProfile( p );
Dar_MmFixedStop( p->pMemObjs, 0 );
Dar_MmFlexStop( p->pMemCuts, 0 );
if ( p->vPis ) Vec_PtrFree( p->vPis );
if ( p->vPos ) Vec_PtrFree( p->vPos );
if ( p->vObjs ) Vec_PtrFree( p->vObjs );
if ( p->vRequired ) Vec_IntFree( p->vRequired );
if ( p->vLeavesBest ) Vec_PtrFree( p->vLeavesBest );
free( p->pTable );
free( p );
}
/**Function*************************************************************
Synopsis [Returns the number of dangling nodes removed.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Dar_ManCleanup( Dar_Man_t * p )
{
Vec_Ptr_t * vObjs;
Dar_Obj_t * pNode;
int i, nNodesOld;
nNodesOld = Dar_ManNodeNum(p);
// collect roots of dangling nodes
vObjs = Vec_PtrAlloc( 100 );
Dar_ManForEachObj( p, pNode, i )
if ( Dar_ObjIsNode(pNode) && Dar_ObjRefs(pNode) == 0 )
Vec_PtrPush( vObjs, pNode );
// recursively remove dangling nodes
Vec_PtrForEachEntry( vObjs, pNode, i )
Dar_ObjDelete_rec( p, pNode, 1 );
Vec_PtrFree( vObjs );
return nNodesOld - Dar_ManNodeNum(p);
}
/**Function*************************************************************
Synopsis [Stops the AIG manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_ManPrintStats( Dar_Man_t * p )
{
printf( "PI/PO = %d/%d. ", Dar_ManPiNum(p), Dar_ManPoNum(p) );
printf( "A = %7d. ", Dar_ManAndNum(p) );
printf( "X = %5d. ", Dar_ManExorNum(p) );
printf( "Cre = %7d. ", p->nCreated );
printf( "Del = %7d. ", p->nDeleted );
printf( "Lev = %3d. ", Dar_ManCountLevels(p) );
printf( "\n" );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

601
src/aig/dar/darMem.c Normal file
View File

@ -0,0 +1,601 @@
/**CFile****************************************************************
FileName [darMem.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [DAG-aware AIG rewriting.]
Synopsis [Memory managers.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: darMem.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "dar.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
struct Dar_MmFixed_t_
{
// information about individual entries
int nEntrySize; // the size of one entry
int nEntriesAlloc; // the total number of entries allocated
int nEntriesUsed; // the number of entries in use
int nEntriesMax; // the max number of entries in use
char * pEntriesFree; // the linked list of free entries
// this is where the memory is stored
int nChunkSize; // the size of one chunk
int nChunksAlloc; // the maximum number of memory chunks
int nChunks; // the current number of memory chunks
char ** pChunks; // the allocated memory
// statistics
int nMemoryUsed; // memory used in the allocated entries
int nMemoryAlloc; // memory allocated
};
struct Dar_MmFlex_t_
{
// information about individual entries
int nEntriesUsed; // the number of entries allocated
char * pCurrent; // the current pointer to free memory
char * pEnd; // the first entry outside the free memory
// this is where the memory is stored
int nChunkSize; // the size of one chunk
int nChunksAlloc; // the maximum number of memory chunks
int nChunks; // the current number of memory chunks
char ** pChunks; // the allocated memory
// statistics
int nMemoryUsed; // memory used in the allocated entries
int nMemoryAlloc; // memory allocated
};
struct Dar_MmStep_t_
{
int nMems; // the number of fixed memory managers employed
Dar_MmFixed_t ** pMems; // memory managers: 2^1 words, 2^2 words, etc
int nMapSize; // the size of the memory array
Dar_MmFixed_t ** pMap; // maps the number of bytes into its memory manager
};
#define ALLOC(type, num) ((type *) malloc(sizeof(type) * (num)))
#define FREE(obj) ((obj) ? (free((char *) (obj)), (obj) = 0) : 0)
#define REALLOC(type, obj, num) \
((obj) ? ((type *) realloc((char *)(obj), sizeof(type) * (num))) : \
((type *) malloc(sizeof(type) * (num))))
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Allocates memory pieces of fixed size.]
Description [The size of the chunk is computed as the minimum of
1024 entries and 64K. Can only work with entry size at least 4 byte long.]
SideEffects []
SeeAlso []
***********************************************************************/
Dar_MmFixed_t * Dar_MmFixedStart( int nEntrySize, int nEntriesMax )
{
Dar_MmFixed_t * p;
p = ALLOC( Dar_MmFixed_t, 1 );
memset( p, 0, sizeof(Dar_MmFixed_t) );
p->nEntrySize = nEntrySize;
p->nEntriesAlloc = 0;
p->nEntriesUsed = 0;
p->pEntriesFree = NULL;
p->nChunkSize = nEntriesMax / 8;
if ( p->nChunkSize < 8 )
p->nChunkSize = 8;
p->nChunksAlloc = 64;
p->nChunks = 0;
p->pChunks = ALLOC( char *, p->nChunksAlloc );
p->nMemoryUsed = 0;
p->nMemoryAlloc = 0;
return p;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_MmFixedStop( Dar_MmFixed_t * p, int fVerbose )
{
int i;
if ( p == NULL )
return;
if ( fVerbose )
{
printf( "Fixed memory manager: Entry = %5d. Chunk = %5d. Chunks used = %5d.\n",
p->nEntrySize, p->nChunkSize, p->nChunks );
printf( " Entries used = %8d. Entries peak = %8d. Memory used = %8d. Memory alloc = %8d.\n",
p->nEntriesUsed, p->nEntriesMax, p->nEntrySize * p->nEntriesUsed, p->nMemoryAlloc );
}
for ( i = 0; i < p->nChunks; i++ )
free( p->pChunks[i] );
free( p->pChunks );
free( p );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
char * Dar_MmFixedEntryFetch( Dar_MmFixed_t * p )
{
char * pTemp;
int i;
// check if there are still free entries
if ( p->nEntriesUsed == p->nEntriesAlloc )
{ // need to allocate more entries
assert( p->pEntriesFree == NULL );
if ( p->nChunks == p->nChunksAlloc )
{
p->nChunksAlloc *= 2;
p->pChunks = REALLOC( char *, p->pChunks, p->nChunksAlloc );
}
p->pEntriesFree = ALLOC( char, p->nEntrySize * p->nChunkSize );
p->nMemoryAlloc += p->nEntrySize * p->nChunkSize;
// transform these entries into a linked list
pTemp = p->pEntriesFree;
for ( i = 1; i < p->nChunkSize; i++ )
{
*((char **)pTemp) = pTemp + p->nEntrySize;
pTemp += p->nEntrySize;
}
// set the last link
*((char **)pTemp) = NULL;
// add the chunk to the chunk storage
p->pChunks[ p->nChunks++ ] = p->pEntriesFree;
// add to the number of entries allocated
p->nEntriesAlloc += p->nChunkSize;
}
// incrememt the counter of used entries
p->nEntriesUsed++;
if ( p->nEntriesMax < p->nEntriesUsed )
p->nEntriesMax = p->nEntriesUsed;
// return the first entry in the free entry list
pTemp = p->pEntriesFree;
p->pEntriesFree = *((char **)pTemp);
return pTemp;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_MmFixedEntryRecycle( Dar_MmFixed_t * p, char * pEntry )
{
// decrement the counter of used entries
p->nEntriesUsed--;
// add the entry to the linked list of free entries
*((char **)pEntry) = p->pEntriesFree;
p->pEntriesFree = pEntry;
}
/**Function*************************************************************
Synopsis []
Description [Relocates all the memory except the first chunk.]
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_MmFixedRestart( Dar_MmFixed_t * p )
{
int i;
char * pTemp;
// deallocate all chunks except the first one
for ( i = 1; i < p->nChunks; i++ )
free( p->pChunks[i] );
p->nChunks = 1;
// transform these entries into a linked list
pTemp = p->pChunks[0];
for ( i = 1; i < p->nChunkSize; i++ )
{
*((char **)pTemp) = pTemp + p->nEntrySize;
pTemp += p->nEntrySize;
}
// set the last link
*((char **)pTemp) = NULL;
// set the free entry list
p->pEntriesFree = p->pChunks[0];
// set the correct statistics
p->nMemoryAlloc = p->nEntrySize * p->nChunkSize;
p->nMemoryUsed = 0;
p->nEntriesAlloc = p->nChunkSize;
p->nEntriesUsed = 0;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Dar_MmFixedReadMemUsage( Dar_MmFixed_t * p )
{
return p->nMemoryAlloc;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Dar_MmFixedReadMaxEntriesUsed( Dar_MmFixed_t * p )
{
return p->nEntriesMax;
}
/**Function*************************************************************
Synopsis [Allocates entries of flexible size.]
Description [Can only work with entry size at least 4 byte long.]
SideEffects []
SeeAlso []
***********************************************************************/
Dar_MmFlex_t * Dar_MmFlexStart()
{
Dar_MmFlex_t * p;
p = ALLOC( Dar_MmFlex_t, 1 );
memset( p, 0, sizeof(Dar_MmFlex_t) );
p->nEntriesUsed = 0;
p->pCurrent = NULL;
p->pEnd = NULL;
p->nChunkSize = (1 << 18);
p->nChunksAlloc = 64;
p->nChunks = 0;
p->pChunks = ALLOC( char *, p->nChunksAlloc );
p->nMemoryUsed = 0;
p->nMemoryAlloc = 0;
return p;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_MmFlexStop( Dar_MmFlex_t * p, int fVerbose )
{
int i;
if ( p == NULL )
return;
if ( fVerbose )
{
printf( "Flexible memory manager: Chunk size = %d. Chunks used = %d.\n",
p->nChunkSize, p->nChunks );
printf( " Entries used = %d. Memory used = %d. Memory alloc = %d.\n",
p->nEntriesUsed, p->nMemoryUsed, p->nMemoryAlloc );
}
for ( i = 0; i < p->nChunks; i++ )
free( p->pChunks[i] );
free( p->pChunks );
free( p );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
char * Dar_MmFlexEntryFetch( Dar_MmFlex_t * p, int nBytes )
{
char * pTemp;
// check if there are still free entries
if ( p->pCurrent == NULL || p->pCurrent + nBytes > p->pEnd )
{ // need to allocate more entries
if ( p->nChunks == p->nChunksAlloc )
{
p->nChunksAlloc *= 2;
p->pChunks = REALLOC( char *, p->pChunks, p->nChunksAlloc );
}
if ( nBytes > p->nChunkSize )
{
// resize the chunk size if more memory is requested than it can give
// (ideally, this should never happen)
p->nChunkSize = 2 * nBytes;
}
p->pCurrent = ALLOC( char, p->nChunkSize );
p->pEnd = p->pCurrent + p->nChunkSize;
p->nMemoryAlloc += p->nChunkSize;
// add the chunk to the chunk storage
p->pChunks[ p->nChunks++ ] = p->pCurrent;
}
assert( p->pCurrent + nBytes <= p->pEnd );
// increment the counter of used entries
p->nEntriesUsed++;
// keep track of the memory used
p->nMemoryUsed += nBytes;
// return the next entry
pTemp = p->pCurrent;
p->pCurrent += nBytes;
return pTemp;
}
/**Function*************************************************************
Synopsis []
Description [Relocates all the memory except the first chunk.]
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_MmFlexRestart( Dar_MmFlex_t * p )
{
int i;
if ( p->nChunks == 0 )
return;
// deallocate all chunks except the first one
for ( i = 1; i < p->nChunks; i++ )
free( p->pChunks[i] );
p->nChunks = 1;
p->nMemoryAlloc = p->nChunkSize;
// transform these entries into a linked list
p->pCurrent = p->pChunks[0];
p->pEnd = p->pCurrent + p->nChunkSize;
p->nEntriesUsed = 0;
p->nMemoryUsed = 0;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Dar_MmFlexReadMemUsage( Dar_MmFlex_t * p )
{
return p->nMemoryUsed;
}
/**Function*************************************************************
Synopsis [Starts the hierarchical memory manager.]
Description [This manager can allocate entries of any size.
Iternally they are mapped into the entries with the number of bytes
equal to the power of 2. The smallest entry size is 8 bytes. The
next one is 16 bytes etc. So, if the user requests 6 bytes, he gets
8 byte entry. If we asks for 25 bytes, he gets 32 byte entry etc.
The input parameters "nSteps" says how many fixed memory managers
are employed internally. Calling this procedure with nSteps equal
to 10 results in 10 hierarchically arranged internal memory managers,
which can allocate up to 4096 (1Kb) entries. Requests for larger
entries are handed over to malloc() and then free()ed.]
SideEffects []
SeeAlso []
***********************************************************************/
Dar_MmStep_t * Dar_MmStepStart( int nSteps )
{
Dar_MmStep_t * p;
int i, k;
p = ALLOC( Dar_MmStep_t, 1 );
memset( p, 0, sizeof(Dar_MmStep_t) );
p->nMems = nSteps;
// start the fixed memory managers
p->pMems = ALLOC( Dar_MmFixed_t *, p->nMems );
for ( i = 0; i < p->nMems; i++ )
p->pMems[i] = Dar_MmFixedStart( (8<<i), (1<<13) );
// set up the mapping of the required memory size into the corresponding manager
p->nMapSize = (4<<p->nMems);
p->pMap = ALLOC( Dar_MmFixed_t *, p->nMapSize+1 );
p->pMap[0] = NULL;
for ( k = 1; k <= 4; k++ )
p->pMap[k] = p->pMems[0];
for ( i = 0; i < p->nMems; i++ )
for ( k = (4<<i)+1; k <= (8<<i); k++ )
p->pMap[k] = p->pMems[i];
//for ( i = 1; i < 100; i ++ )
//printf( "%10d: size = %10d\n", i, p->pMap[i]->nEntrySize );
return p;
}
/**Function*************************************************************
Synopsis [Stops the memory manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_MmStepStop( Dar_MmStep_t * p, int fVerbose )
{
int i;
for ( i = 0; i < p->nMems; i++ )
Dar_MmFixedStop( p->pMems[i], fVerbose );
// if ( p->pLargeChunks )
// {
// for ( i = 0; i < p->nLargeChunks; i++ )
// free( p->pLargeChunks[i] );
// free( p->pLargeChunks );
// }
free( p->pMems );
free( p->pMap );
free( p );
}
/**Function*************************************************************
Synopsis [Creates the entry.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
char * Dar_MmStepEntryFetch( Dar_MmStep_t * p, int nBytes )
{
if ( nBytes == 0 )
return NULL;
if ( nBytes > p->nMapSize )
{
// printf( "Allocating %d bytes.\n", nBytes );
/*
if ( p->nLargeChunks == p->nLargeChunksAlloc )
{
if ( p->nLargeChunksAlloc == 0 )
p->nLargeChunksAlloc = 5;
p->nLargeChunksAlloc *= 2;
p->pLargeChunks = REALLOC( char *, p->pLargeChunks, p->nLargeChunksAlloc );
}
p->pLargeChunks[ p->nLargeChunks++ ] = ALLOC( char, nBytes );
return p->pLargeChunks[ p->nLargeChunks - 1 ];
*/
return ALLOC( char, nBytes );
}
return Dar_MmFixedEntryFetch( p->pMap[nBytes] );
}
/**Function*************************************************************
Synopsis [Recycles the entry.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_MmStepEntryRecycle( Dar_MmStep_t * p, char * pEntry, int nBytes )
{
if ( nBytes == 0 )
return;
if ( nBytes > p->nMapSize )
{
free( pEntry );
return;
}
Dar_MmFixedEntryRecycle( p->pMap[nBytes], pEntry );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Dar_MmStepReadMemUsage( Dar_MmStep_t * p )
{
int i, nMemTotal = 0;
for ( i = 0; i < p->nMems; i++ )
nMemTotal += p->pMems[i]->nMemoryAlloc;
return nMemTotal;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

273
src/aig/dar/darObj.c Normal file
View File

@ -0,0 +1,273 @@
/**CFile****************************************************************
FileName [darObj.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [DAG-aware AIG rewriting.]
Synopsis [Adding/removing objects.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: darObj.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
#include "dar.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Creates primary input.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Dar_Obj_t * Dar_ObjCreatePi( Dar_Man_t * p )
{
Dar_Obj_t * pObj;
pObj = Dar_ManFetchMemory( p );
pObj->Type = DAR_AIG_PI;
Vec_PtrPush( p->vPis, pObj );
p->nObjs[DAR_AIG_PI]++;
return pObj;
}
/**Function*************************************************************
Synopsis [Creates primary output with the given driver.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Dar_Obj_t * Dar_ObjCreatePo( Dar_Man_t * p, Dar_Obj_t * pDriver )
{
Dar_Obj_t * pObj;
pObj = Dar_ManFetchMemory( p );
pObj->Type = DAR_AIG_PO;
Vec_PtrPush( p->vPos, pObj );
// add connections
Dar_ObjConnect( p, pObj, pDriver, NULL );
// update node counters of the manager
p->nObjs[DAR_AIG_PO]++;
return pObj;
}
/**Function*************************************************************
Synopsis [Create the new node assuming it does not exist.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Dar_Obj_t * Dar_ObjCreate( Dar_Man_t * p, Dar_Obj_t * pGhost )
{
Dar_Obj_t * pObj;
assert( !Dar_IsComplement(pGhost) );
assert( Dar_ObjIsNode(pGhost) );
assert( pGhost == &p->Ghost );
// get memory for the new object
pObj = Dar_ManFetchMemory( p );
pObj->Type = pGhost->Type;
// add connections
Dar_ObjConnect( p, pObj, pGhost->pFanin0, pGhost->pFanin1 );
// update node counters of the manager
p->nObjs[Dar_ObjType(pObj)]++;
assert( pObj->pData == NULL );
return pObj;
}
/**Function*************************************************************
Synopsis [Connect the object to the fanin.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_ObjConnect( Dar_Man_t * p, Dar_Obj_t * pObj, Dar_Obj_t * pFan0, Dar_Obj_t * pFan1 )
{
assert( !Dar_IsComplement(pObj) );
assert( Dar_ObjIsNode(pObj) );
// add the first fanin
pObj->pFanin0 = pFan0;
pObj->pFanin1 = pFan1;
// increment references of the fanins and add their fanouts
if ( pFan0 != NULL )
Dar_ObjRef( Dar_ObjFanin0(pObj) );
if ( pFan1 != NULL )
Dar_ObjRef( Dar_ObjFanin1(pObj) );
// set level and phase
if ( pFan1 != NULL )
{
pObj->Level = Dar_ObjLevelNew( pObj );
pObj->fPhase = Dar_ObjFaninPhase(pFan0) & Dar_ObjFaninPhase(pFan1);
}
else
{
pObj->Level = pFan0->Level;
pObj->fPhase = Dar_ObjFaninPhase(pFan0);
}
// add the node to the structural hash table
if ( Dar_ObjIsNode(pObj) )
Dar_TableInsert( p, pObj );
}
/**Function*************************************************************
Synopsis [Disconnects the object from the fanins.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_ObjDisconnect( Dar_Man_t * p, Dar_Obj_t * pObj )
{
assert( !Dar_IsComplement(pObj) );
// remove connections
if ( pObj->pFanin0 != NULL )
Dar_ObjDeref(Dar_ObjFanin0(pObj));
if ( pObj->pFanin1 != NULL )
Dar_ObjDeref(Dar_ObjFanin1(pObj));
// remove the node from the structural hash table
if ( Dar_ObjIsNode(pObj) )
Dar_TableDelete( p, pObj );
// add the first fanin
pObj->pFanin0 = NULL;
pObj->pFanin1 = NULL;
}
/**Function*************************************************************
Synopsis [Deletes the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_ObjDelete( Dar_Man_t * p, Dar_Obj_t * pObj )
{
assert( !Dar_IsComplement(pObj) );
assert( !Dar_ObjIsTerm(pObj) );
assert( Dar_ObjRefs(pObj) == 0 );
p->nDeleted++;
Vec_PtrWriteEntry( p->vObjs, pObj->Id, NULL );
Dar_ManRecycleMemory( p, pObj );
}
/**Function*************************************************************
Synopsis [Deletes the MFFC of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_ObjDelete_rec( Dar_Man_t * p, Dar_Obj_t * pObj, int fFreeTop )
{
Dar_Obj_t * pFanin0, * pFanin1;
assert( !Dar_IsComplement(pObj) );
if ( Dar_ObjIsConst1(pObj) || Dar_ObjIsPi(pObj) )
return;
assert( Dar_ObjIsNode(pObj) );
pFanin0 = Dar_ObjFanin0(pObj);
pFanin1 = Dar_ObjFanin1(pObj);
Dar_ObjDisconnect( p, pObj );
p->nObjs[pObj->Type]--;
if ( fFreeTop )
Dar_ObjDelete( p, pObj );
if ( pFanin0 && !Dar_ObjIsNone(pFanin0) && Dar_ObjRefs(pFanin0) == 0 )
Dar_ObjDelete_rec( p, pFanin0, 1 );
if ( pFanin1 && !Dar_ObjIsNone(pFanin1) && Dar_ObjRefs(pFanin1) == 0 )
Dar_ObjDelete_rec( p, pFanin1, 1 );
}
/**Function*************************************************************
Synopsis [Replaces one object by another.]
Description [Both objects are currently in the manager. The new object
(pObjNew) should be used instead of the old object (pObjOld). If the
new object is complemented or used, the buffer is added.]
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_ObjReplace( Dar_Man_t * p, Dar_Obj_t * pObjOld, Dar_Obj_t * pObjNew )
{
Dar_Obj_t * pObjNewR = Dar_Regular(pObjNew);
// the object to be replaced cannot be complemented
assert( !Dar_IsComplement(pObjOld) );
// the object to be replaced cannot be a terminal
assert( !Dar_ObjIsPi(pObjOld) && !Dar_ObjIsPo(pObjOld) );
// the object to be used cannot be a buffer
assert( !Dar_ObjIsBuf(pObjNewR) && !Dar_ObjIsPo(pObjNewR) );
// the object cannot be the same
assert( pObjOld != pObjNewR );
// make sure object is not pointing to itself
assert( pObjOld != Dar_ObjFanin0(pObjNewR) );
assert( pObjOld != Dar_ObjFanin1(pObjNewR) );
// delete the old node
Dar_ObjDelete_rec( p, pObjOld, 0 );
// if the new object is complemented or already used, create a buffer
if ( Dar_IsComplement(pObjNew) || Dar_ObjRefs(pObjNew) > 0 || !Dar_ObjIsNode(pObjNew) )
{
pObjOld->Type = DAR_AIG_BUF;
p->nObjs[pObjOld->Type]++;
Dar_ObjConnect( p, pObjOld, pObjNew, NULL );
}
else
{
Dar_Obj_t * pFanin0 = pObjNew->pFanin0;
Dar_Obj_t * pFanin1 = pObjNew->pFanin1;
pObjOld->Type = pObjNew->Type;
Dar_ObjDisconnect( p, pObjNew );
Dar_ObjDelete( p, pObjNew );
Dar_ObjConnect( p, pObjOld, pFanin0, pFanin1 );
}
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

373
src/aig/dar/darOper.c Normal file
View File

@ -0,0 +1,373 @@
/**CFile****************************************************************
FileName [darOper.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [DAG-aware AIG rewriting.]
Synopsis [AIG operations.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: darOper.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
#include "dar.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
// procedure to detect an EXOR gate
static inline int Dar_ObjIsExorType( Dar_Obj_t * p0, Dar_Obj_t * p1, Dar_Obj_t ** ppFan0, Dar_Obj_t ** ppFan1 )
{
if ( !Dar_IsComplement(p0) || !Dar_IsComplement(p1) )
return 0;
p0 = Dar_Regular(p0);
p1 = Dar_Regular(p1);
if ( !Dar_ObjIsAnd(p0) || !Dar_ObjIsAnd(p1) )
return 0;
if ( Dar_ObjFanin0(p0) != Dar_ObjFanin0(p1) || Dar_ObjFanin1(p0) != Dar_ObjFanin1(p1) )
return 0;
if ( Dar_ObjFaninC0(p0) == Dar_ObjFaninC0(p1) || Dar_ObjFaninC1(p0) == Dar_ObjFaninC1(p1) )
return 0;
*ppFan0 = Dar_ObjChild0(p0);
*ppFan1 = Dar_ObjChild1(p0);
return 1;
}
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Returns i-th elementary variable.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Dar_Obj_t * Dar_IthVar( Dar_Man_t * p, int i )
{
int v;
for ( v = Dar_ManPiNum(p); v <= i; v++ )
Dar_ObjCreatePi( p );
assert( i < Vec_PtrSize(p->vPis) );
return Dar_ManPi( p, i );
}
/**Function*************************************************************
Synopsis [Perform one operation.]
Description [The argument nodes can be complemented.]
SideEffects []
SeeAlso []
***********************************************************************/
Dar_Obj_t * Dar_Oper( Dar_Man_t * p, Dar_Obj_t * p0, Dar_Obj_t * p1, Dar_Type_t Type )
{
if ( Type == DAR_AIG_AND )
return Dar_And( p, p0, p1 );
if ( Type == DAR_AIG_EXOR )
return Dar_Exor( p, p0, p1 );
assert( 0 );
return NULL;
}
/**Function*************************************************************
Synopsis [Performs canonicization step.]
Description [The argument nodes can be complemented.]
SideEffects []
SeeAlso []
***********************************************************************/
Dar_Obj_t * Dar_And( Dar_Man_t * p, Dar_Obj_t * p0, Dar_Obj_t * p1 )
{
Dar_Obj_t * pGhost, * pResult;
// Dar_Obj_t * pFan0, * pFan1;
// check trivial cases
if ( p0 == p1 )
return p0;
if ( p0 == Dar_Not(p1) )
return Dar_Not(p->pConst1);
if ( Dar_Regular(p0) == p->pConst1 )
return p0 == p->pConst1 ? p1 : Dar_Not(p->pConst1);
if ( Dar_Regular(p1) == p->pConst1 )
return p1 == p->pConst1 ? p0 : Dar_Not(p->pConst1);
// check if it can be an EXOR gate
// if ( Dar_ObjIsExorType( p0, p1, &pFan0, &pFan1 ) )
// return Dar_Exor( p, pFan0, pFan1 );
// check the table
pGhost = Dar_ObjCreateGhost( p, p0, p1, DAR_AIG_AND );
if ( pResult = Dar_TableLookup( p, pGhost ) )
return pResult;
return Dar_ObjCreate( p, pGhost );
}
/**Function*************************************************************
Synopsis [Performs canonicization step.]
Description [The argument nodes can be complemented.]
SideEffects []
SeeAlso []
***********************************************************************/
Dar_Obj_t * Dar_Exor( Dar_Man_t * p, Dar_Obj_t * p0, Dar_Obj_t * p1 )
{
/*
Dar_Obj_t * pGhost, * pResult;
// check trivial cases
if ( p0 == p1 )
return Dar_Not(p->pConst1);
if ( p0 == Dar_Not(p1) )
return p->pConst1;
if ( Dar_Regular(p0) == p->pConst1 )
return Dar_NotCond( p1, p0 == p->pConst1 );
if ( Dar_Regular(p1) == p->pConst1 )
return Dar_NotCond( p0, p1 == p->pConst1 );
// check the table
pGhost = Dar_ObjCreateGhost( p, p0, p1, DAR_AIG_EXOR );
if ( pResult = Dar_TableLookup( p, pGhost ) )
return pResult;
return Dar_ObjCreate( p, pGhost );
*/
return Dar_Or( p, Dar_And(p, p0, Dar_Not(p1)), Dar_And(p, Dar_Not(p0), p1) );
}
/**Function*************************************************************
Synopsis [Implements Boolean OR.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Dar_Obj_t * Dar_Or( Dar_Man_t * p, Dar_Obj_t * p0, Dar_Obj_t * p1 )
{
return Dar_Not( Dar_And( p, Dar_Not(p0), Dar_Not(p1) ) );
}
/**Function*************************************************************
Synopsis [Implements ITE operation.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Dar_Obj_t * Dar_Mux( Dar_Man_t * p, Dar_Obj_t * pC, Dar_Obj_t * p1, Dar_Obj_t * p0 )
{
/*
Dar_Obj_t * pTempA1, * pTempA2, * pTempB1, * pTempB2, * pTemp;
int Count0, Count1;
// consider trivial cases
if ( p0 == Dar_Not(p1) )
return Dar_Exor( p, pC, p0 );
// other cases can be added
// implement the first MUX (F = C * x1 + C' * x0)
// check for constants here!!!
pTempA1 = Dar_TableLookup( p, Dar_ObjCreateGhost(p, pC, p1, DAR_AIG_AND) );
pTempA2 = Dar_TableLookup( p, Dar_ObjCreateGhost(p, Dar_Not(pC), p0, DAR_AIG_AND) );
if ( pTempA1 && pTempA2 )
{
pTemp = Dar_TableLookup( p, Dar_ObjCreateGhost(p, Dar_Not(pTempA1), Dar_Not(pTempA2), DAR_AIG_AND) );
if ( pTemp ) return Dar_Not(pTemp);
}
Count0 = (pTempA1 != NULL) + (pTempA2 != NULL);
// implement the second MUX (F' = C * x1' + C' * x0')
pTempB1 = Dar_TableLookup( p, Dar_ObjCreateGhost(p, pC, Dar_Not(p1), DAR_AIG_AND) );
pTempB2 = Dar_TableLookup( p, Dar_ObjCreateGhost(p, Dar_Not(pC), Dar_Not(p0), DAR_AIG_AND) );
if ( pTempB1 && pTempB2 )
{
pTemp = Dar_TableLookup( p, Dar_ObjCreateGhost(p, Dar_Not(pTempB1), Dar_Not(pTempB2), DAR_AIG_AND) );
if ( pTemp ) return pTemp;
}
Count1 = (pTempB1 != NULL) + (pTempB2 != NULL);
// compare and decide which one to implement
if ( Count0 >= Count1 )
{
pTempA1 = pTempA1? pTempA1 : Dar_And(p, pC, p1);
pTempA2 = pTempA2? pTempA2 : Dar_And(p, Dar_Not(pC), p0);
return Dar_Or( p, pTempA1, pTempA2 );
}
pTempB1 = pTempB1? pTempB1 : Dar_And(p, pC, Dar_Not(p1));
pTempB2 = pTempB2? pTempB2 : Dar_And(p, Dar_Not(pC), Dar_Not(p0));
return Dar_Not( Dar_Or( p, pTempB1, pTempB2 ) );
*/
return Dar_Or( p, Dar_And(p, pC, p1), Dar_And(p, Dar_Not(pC), p0) );
}
/**Function*************************************************************
Synopsis [Implements ITE operation.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Dar_Obj_t * Dar_Maj( Dar_Man_t * p, Dar_Obj_t * pA, Dar_Obj_t * pB, Dar_Obj_t * pC )
{
return Dar_Or( p, Dar_Or(p, Dar_And(p, pA, pB), Dar_And(p, pA, pC)), Dar_And(p, pB, pC) );
}
/**Function*************************************************************
Synopsis [Constructs the well-balanced tree of gates.]
Description [Disregards levels and possible logic sharing.]
SideEffects []
SeeAlso []
***********************************************************************/
Dar_Obj_t * Dar_Multi_rec( Dar_Man_t * p, Dar_Obj_t ** ppObjs, int nObjs, Dar_Type_t Type )
{
Dar_Obj_t * pObj1, * pObj2;
if ( nObjs == 1 )
return ppObjs[0];
pObj1 = Dar_Multi_rec( p, ppObjs, nObjs/2, Type );
pObj2 = Dar_Multi_rec( p, ppObjs + nObjs/2, nObjs - nObjs/2, Type );
return Dar_Oper( p, pObj1, pObj2, Type );
}
/**Function*************************************************************
Synopsis [Old code.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Dar_Obj_t * Dar_Multi( Dar_Man_t * p, Dar_Obj_t ** pArgs, int nArgs, Dar_Type_t Type )
{
assert( Type == DAR_AIG_AND || Type == DAR_AIG_EXOR );
assert( nArgs > 0 );
return Dar_Multi_rec( p, pArgs, nArgs, Type );
}
/**Function*************************************************************
Synopsis [Implements the miter.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Dar_Obj_t * Dar_Miter( Dar_Man_t * p, Vec_Ptr_t * vPairs )
{
int i;
assert( vPairs->nSize > 0 );
assert( vPairs->nSize % 2 == 0 );
// go through the cubes of the node's SOP
for ( i = 0; i < vPairs->nSize; i += 2 )
vPairs->pArray[i/2] = Dar_Not( Dar_Exor( p, vPairs->pArray[i], vPairs->pArray[i+1] ) );
vPairs->nSize = vPairs->nSize/2;
return Dar_Not( Dar_Multi_rec( p, (Dar_Obj_t **)vPairs->pArray, vPairs->nSize, DAR_AIG_AND ) );
}
/**Function*************************************************************
Synopsis [Creates AND function with nVars inputs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Dar_Obj_t * Dar_CreateAnd( Dar_Man_t * p, int nVars )
{
Dar_Obj_t * pFunc;
int i;
pFunc = Dar_ManConst1( p );
for ( i = 0; i < nVars; i++ )
pFunc = Dar_And( p, pFunc, Dar_IthVar(p, i) );
return pFunc;
}
/**Function*************************************************************
Synopsis [Creates AND function with nVars inputs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Dar_Obj_t * Dar_CreateOr( Dar_Man_t * p, int nVars )
{
Dar_Obj_t * pFunc;
int i;
pFunc = Dar_ManConst0( p );
for ( i = 0; i < nVars; i++ )
pFunc = Dar_Or( p, pFunc, Dar_IthVar(p, i) );
return pFunc;
}
/**Function*************************************************************
Synopsis [Creates AND function with nVars inputs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Dar_Obj_t * Dar_CreateExor( Dar_Man_t * p, int nVars )
{
Dar_Obj_t * pFunc;
int i;
pFunc = Dar_ManConst0( p );
for ( i = 0; i < nVars; i++ )
pFunc = Dar_Exor( p, pFunc, Dar_IthVar(p, i) );
return pFunc;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

262
src/aig/dar/darTable.c Normal file
View File

@ -0,0 +1,262 @@
/**CFile****************************************************************
FileName [darTable.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [DAG-aware AIG rewriting.]
Synopsis [Structural hashing table.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: darTable.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
#include "dar.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
// hashing the node
static unsigned long Dar_Hash( Dar_Obj_t * pObj, int TableSize )
{
unsigned long Key = Dar_ObjIsExor(pObj) * 1699;
Key ^= (long)Dar_ObjFanin0(pObj) * 7937;
Key ^= (long)Dar_ObjFanin1(pObj) * 2971;
Key ^= Dar_ObjFaninC0(pObj) * 911;
Key ^= Dar_ObjFaninC1(pObj) * 353;
return Key % TableSize;
}
// returns the place where this node is stored (or should be stored)
static Dar_Obj_t ** Dar_TableFind( Dar_Man_t * p, Dar_Obj_t * pObj )
{
Dar_Obj_t ** ppEntry;
assert( Dar_ObjChild0(pObj) && Dar_ObjChild1(pObj) );
assert( Dar_ObjFanin0(pObj)->Id < Dar_ObjFanin1(pObj)->Id );
for ( ppEntry = p->pTable + Dar_Hash(pObj, p->nTableSize); *ppEntry; ppEntry = &(*ppEntry)->pNext )
if ( *ppEntry == pObj )
return ppEntry;
assert( *ppEntry == NULL );
return ppEntry;
}
static void Dar_TableResize( Dar_Man_t * p );
static unsigned int Cudd_PrimeAig( unsigned int p );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Checks if node with the given attributes is in the hash table.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Dar_Obj_t * Dar_TableLookup( Dar_Man_t * p, Dar_Obj_t * pGhost )
{
Dar_Obj_t * pEntry;
assert( !Dar_IsComplement(pGhost) );
assert( Dar_ObjChild0(pGhost) && Dar_ObjChild1(pGhost) );
assert( Dar_ObjFanin0(pGhost)->Id < Dar_ObjFanin1(pGhost)->Id );
if ( !Dar_ObjRefs(Dar_ObjFanin0(pGhost)) || !Dar_ObjRefs(Dar_ObjFanin1(pGhost)) )
return NULL;
for ( pEntry = p->pTable[Dar_Hash(pGhost, p->nTableSize)]; pEntry; pEntry = pEntry->pNext )
{
if ( Dar_ObjChild0(pEntry) == Dar_ObjChild0(pGhost) &&
Dar_ObjChild1(pEntry) == Dar_ObjChild1(pGhost) &&
Dar_ObjType(pEntry) == Dar_ObjType(pGhost) )
return pEntry;
}
return NULL;
}
/**Function*************************************************************
Synopsis [Adds the new node to the hash table.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_TableInsert( Dar_Man_t * p, Dar_Obj_t * pObj )
{
Dar_Obj_t ** ppPlace;
assert( !Dar_IsComplement(pObj) );
assert( Dar_TableLookup(p, pObj) == NULL );
if ( (pObj->Id & 0xFF) == 0 && 2 * p->nTableSize < Dar_ManNodeNum(p) )
Dar_TableResize( p );
ppPlace = Dar_TableFind( p, pObj );
assert( *ppPlace == NULL );
*ppPlace = pObj;
}
/**Function*************************************************************
Synopsis [Deletes the node from the hash table.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_TableDelete( Dar_Man_t * p, Dar_Obj_t * pObj )
{
Dar_Obj_t ** ppPlace;
assert( !Dar_IsComplement(pObj) );
ppPlace = Dar_TableFind( p, pObj );
assert( *ppPlace == pObj ); // node should be in the table
// remove the node
*ppPlace = pObj->pNext;
pObj->pNext = NULL;
}
/**Function*************************************************************
Synopsis [Count the number of nodes in the table.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Dar_TableCountEntries( Dar_Man_t * p )
{
Dar_Obj_t * pEntry;
int i, Counter = 0;
for ( i = 0; i < p->nTableSize; i++ )
for ( pEntry = p->pTable[i]; pEntry; pEntry = pEntry->pNext )
Counter++;
return Counter;
}
/**Function*************************************************************
Synopsis [Resizes the table.]
Description [Typically this procedure should not be called.]
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_TableResize( Dar_Man_t * p )
{
Dar_Obj_t * pEntry, * pNext;
Dar_Obj_t ** pTableOld, ** ppPlace;
int nTableSizeOld, Counter, nEntries, i, clk;
clk = clock();
// save the old table
pTableOld = p->pTable;
nTableSizeOld = p->nTableSize;
// get the new table
p->nTableSize = Cudd_PrimeAig( 2 * Dar_ManNodeNum(p) );
p->pTable = ALLOC( Dar_Obj_t *, p->nTableSize );
memset( p->pTable, 0, sizeof(Dar_Obj_t *) * p->nTableSize );
// rehash the entries from the old table
Counter = 0;
for ( i = 0; i < nTableSizeOld; i++ )
for ( pEntry = pTableOld[i], pNext = pEntry? pEntry->pNext : NULL; pEntry; pEntry = pNext, pNext = pEntry? pEntry->pNext : NULL )
{
// get the place where this entry goes in the table
ppPlace = Dar_TableFind( p, pEntry );
assert( *ppPlace == NULL ); // should not be there
// add the entry to the list
*ppPlace = pEntry;
pEntry->pNext = NULL;
Counter++;
}
nEntries = Dar_ManNodeNum(p);
assert( Counter == nEntries );
printf( "Increasing the structural table size from %6d to %6d. ", nTableSizeOld, p->nTableSize );
PRT( "Time", clock() - clk );
// replace the table and the parameters
free( pTableOld );
}
/**Function********************************************************************
Synopsis [Profiles the hash table.]
Description []
SideEffects []
SeeAlso []
******************************************************************************/
void Dar_TableProfile( Dar_Man_t * p )
{
Dar_Obj_t * pEntry;
int i, Counter;
for ( i = 0; i < p->nTableSize; i++ )
{
Counter = 0;
for ( pEntry = p->pTable[i]; pEntry; pEntry = pEntry->pNext )
Counter++;
if ( Counter )
printf( "%d ", Counter );
}
}
/**Function********************************************************************
Synopsis [Returns the next prime &gt;= p.]
Description [Copied from CUDD, for stand-aloneness.]
SideEffects [None]
SeeAlso []
******************************************************************************/
unsigned int Cudd_PrimeAig( unsigned int p)
{
int i,pn;
p--;
do {
p++;
if (p&1) {
pn = 1;
i = 3;
while ((unsigned) (i * i) <= p) {
if (p % i == 0) {
pn = 0;
break;
}
i += 2;
}
} else {
pn = 0;
}
} while (!pn);
return(p);
} /* end of Cudd_Prime */
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

585
src/aig/dar/darUtil.c Normal file
View File

@ -0,0 +1,585 @@
/**CFile****************************************************************
FileName [darUtil.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [DAG-aware AIG rewriting.]
Synopsis [Various procedures.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: darUtil.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
#include "dar.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Returns the structure with default assignment of parameters.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Dar_Par_t * Dar_ManDefaultParams()
{
Dar_Par_t * p;
p = ALLOC( Dar_Par_t, 1 );
memset( p, 0, sizeof(Dar_Par_t) );
return p;
}
/**Function*************************************************************
Synopsis [Increments the current traversal ID of the network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_ManIncrementTravId( Dar_Man_t * p )
{
if ( p->nTravIds >= (1<<30)-1 )
Dar_ManCleanData( p );
p->nTravIds++;
}
/**Function*************************************************************
Synopsis [Cleans the data pointers for the nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_ManCleanData( Dar_Man_t * p )
{
Dar_Obj_t * pObj;
int i;
Dar_ManForEachObj( p, pObj, i )
pObj->pData = NULL;
}
/**Function*************************************************************
Synopsis [Recursively cleans the data pointers in the cone of the node.]
Description [Applicable to small AIGs only because no caching is performed.]
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_ObjCleanData_rec( Dar_Obj_t * pObj )
{
assert( !Dar_IsComplement(pObj) );
assert( !Dar_ObjIsPo(pObj) );
if ( Dar_ObjIsAnd(pObj) )
{
Dar_ObjCleanData_rec( Dar_ObjFanin0(pObj) );
Dar_ObjCleanData_rec( Dar_ObjFanin1(pObj) );
}
pObj->pData = NULL;
}
/**Function*************************************************************
Synopsis [Detects multi-input gate rooted at this node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_ObjCollectMulti_rec( Dar_Obj_t * pRoot, Dar_Obj_t * pObj, Vec_Ptr_t * vSuper )
{
if ( pRoot != pObj && (Dar_IsComplement(pObj) || Dar_ObjIsPi(pObj) || Dar_ObjType(pRoot) != Dar_ObjType(pObj)) )
{
Vec_PtrPushUnique(vSuper, pObj);
return;
}
Dar_ObjCollectMulti_rec( pRoot, Dar_ObjChild0(pObj), vSuper );
Dar_ObjCollectMulti_rec( pRoot, Dar_ObjChild1(pObj), vSuper );
}
/**Function*************************************************************
Synopsis [Detects multi-input gate rooted at this node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_ObjCollectMulti( Dar_Obj_t * pRoot, Vec_Ptr_t * vSuper )
{
assert( !Dar_IsComplement(pRoot) );
Vec_PtrClear( vSuper );
Dar_ObjCollectMulti_rec( pRoot, pRoot, vSuper );
}
/**Function*************************************************************
Synopsis [Returns 1 if the node is the root of MUX or EXOR/NEXOR.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Dar_ObjIsMuxType( Dar_Obj_t * pNode )
{
Dar_Obj_t * pNode0, * pNode1;
// check that the node is regular
assert( !Dar_IsComplement(pNode) );
// if the node is not AND, this is not MUX
if ( !Dar_ObjIsAnd(pNode) )
return 0;
// if the children are not complemented, this is not MUX
if ( !Dar_ObjFaninC0(pNode) || !Dar_ObjFaninC1(pNode) )
return 0;
// get children
pNode0 = Dar_ObjFanin0(pNode);
pNode1 = Dar_ObjFanin1(pNode);
// if the children are not ANDs, this is not MUX
if ( !Dar_ObjIsAnd(pNode0) || !Dar_ObjIsAnd(pNode1) )
return 0;
// otherwise the node is MUX iff it has a pair of equal grandchildren
return (Dar_ObjFanin0(pNode0) == Dar_ObjFanin0(pNode1) && (Dar_ObjFaninC0(pNode0) ^ Dar_ObjFaninC0(pNode1))) ||
(Dar_ObjFanin0(pNode0) == Dar_ObjFanin1(pNode1) && (Dar_ObjFaninC0(pNode0) ^ Dar_ObjFaninC1(pNode1))) ||
(Dar_ObjFanin1(pNode0) == Dar_ObjFanin0(pNode1) && (Dar_ObjFaninC1(pNode0) ^ Dar_ObjFaninC0(pNode1))) ||
(Dar_ObjFanin1(pNode0) == Dar_ObjFanin1(pNode1) && (Dar_ObjFaninC1(pNode0) ^ Dar_ObjFaninC1(pNode1)));
}
/**Function*************************************************************
Synopsis [Recognizes what nodes are inputs of the EXOR.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Dar_ObjRecognizeExor( Dar_Obj_t * pObj, Dar_Obj_t ** ppFan0, Dar_Obj_t ** ppFan1 )
{
Dar_Obj_t * p0, * p1;
assert( !Dar_IsComplement(pObj) );
if ( !Dar_ObjIsNode(pObj) )
return 0;
if ( Dar_ObjIsExor(pObj) )
{
*ppFan0 = Dar_ObjChild0(pObj);
*ppFan1 = Dar_ObjChild1(pObj);
return 1;
}
assert( Dar_ObjIsAnd(pObj) );
p0 = Dar_ObjChild0(pObj);
p1 = Dar_ObjChild1(pObj);
if ( !Dar_IsComplement(p0) || !Dar_IsComplement(p1) )
return 0;
p0 = Dar_Regular(p0);
p1 = Dar_Regular(p1);
if ( !Dar_ObjIsAnd(p0) || !Dar_ObjIsAnd(p1) )
return 0;
if ( Dar_ObjFanin0(p0) != Dar_ObjFanin0(p1) || Dar_ObjFanin1(p0) != Dar_ObjFanin1(p1) )
return 0;
if ( Dar_ObjFaninC0(p0) == Dar_ObjFaninC0(p1) || Dar_ObjFaninC1(p0) == Dar_ObjFaninC1(p1) )
return 0;
*ppFan0 = Dar_ObjChild0(p0);
*ppFan1 = Dar_ObjChild1(p0);
return 1;
}
/**Function*************************************************************
Synopsis [Recognizes what nodes are control and data inputs of a MUX.]
Description [If the node is a MUX, returns the control variable C.
Assigns nodes T and E to be the then and else variables of the MUX.
Node C is never complemented. Nodes T and E can be complemented.
This function also recognizes EXOR/NEXOR gates as MUXes.]
SideEffects []
SeeAlso []
***********************************************************************/
Dar_Obj_t * Dar_ObjRecognizeMux( Dar_Obj_t * pNode, Dar_Obj_t ** ppNodeT, Dar_Obj_t ** ppNodeE )
{
Dar_Obj_t * pNode0, * pNode1;
assert( !Dar_IsComplement(pNode) );
assert( Dar_ObjIsMuxType(pNode) );
// get children
pNode0 = Dar_ObjFanin0(pNode);
pNode1 = Dar_ObjFanin1(pNode);
// find the control variable
if ( Dar_ObjFanin1(pNode0) == Dar_ObjFanin1(pNode1) && (Dar_ObjFaninC1(pNode0) ^ Dar_ObjFaninC1(pNode1)) )
{
// if ( Fraig_IsComplement(pNode1->p2) )
if ( Dar_ObjFaninC1(pNode0) )
{ // pNode2->p2 is positive phase of C
*ppNodeT = Dar_Not(Dar_ObjChild0(pNode1));//pNode2->p1);
*ppNodeE = Dar_Not(Dar_ObjChild0(pNode0));//pNode1->p1);
return Dar_ObjChild1(pNode1);//pNode2->p2;
}
else
{ // pNode1->p2 is positive phase of C
*ppNodeT = Dar_Not(Dar_ObjChild0(pNode0));//pNode1->p1);
*ppNodeE = Dar_Not(Dar_ObjChild0(pNode1));//pNode2->p1);
return Dar_ObjChild1(pNode0);//pNode1->p2;
}
}
else if ( Dar_ObjFanin0(pNode0) == Dar_ObjFanin0(pNode1) && (Dar_ObjFaninC0(pNode0) ^ Dar_ObjFaninC0(pNode1)) )
{
// if ( Fraig_IsComplement(pNode1->p1) )
if ( Dar_ObjFaninC0(pNode0) )
{ // pNode2->p1 is positive phase of C
*ppNodeT = Dar_Not(Dar_ObjChild1(pNode1));//pNode2->p2);
*ppNodeE = Dar_Not(Dar_ObjChild1(pNode0));//pNode1->p2);
return Dar_ObjChild0(pNode1);//pNode2->p1;
}
else
{ // pNode1->p1 is positive phase of C
*ppNodeT = Dar_Not(Dar_ObjChild1(pNode0));//pNode1->p2);
*ppNodeE = Dar_Not(Dar_ObjChild1(pNode1));//pNode2->p2);
return Dar_ObjChild0(pNode0);//pNode1->p1;
}
}
else if ( Dar_ObjFanin0(pNode0) == Dar_ObjFanin1(pNode1) && (Dar_ObjFaninC0(pNode0) ^ Dar_ObjFaninC1(pNode1)) )
{
// if ( Fraig_IsComplement(pNode1->p1) )
if ( Dar_ObjFaninC0(pNode0) )
{ // pNode2->p2 is positive phase of C
*ppNodeT = Dar_Not(Dar_ObjChild0(pNode1));//pNode2->p1);
*ppNodeE = Dar_Not(Dar_ObjChild1(pNode0));//pNode1->p2);
return Dar_ObjChild1(pNode1);//pNode2->p2;
}
else
{ // pNode1->p1 is positive phase of C
*ppNodeT = Dar_Not(Dar_ObjChild1(pNode0));//pNode1->p2);
*ppNodeE = Dar_Not(Dar_ObjChild0(pNode1));//pNode2->p1);
return Dar_ObjChild0(pNode0);//pNode1->p1;
}
}
else if ( Dar_ObjFanin1(pNode0) == Dar_ObjFanin0(pNode1) && (Dar_ObjFaninC1(pNode0) ^ Dar_ObjFaninC0(pNode1)) )
{
// if ( Fraig_IsComplement(pNode1->p2) )
if ( Dar_ObjFaninC1(pNode0) )
{ // pNode2->p1 is positive phase of C
*ppNodeT = Dar_Not(Dar_ObjChild1(pNode1));//pNode2->p2);
*ppNodeE = Dar_Not(Dar_ObjChild0(pNode0));//pNode1->p1);
return Dar_ObjChild0(pNode1);//pNode2->p1;
}
else
{ // pNode1->p2 is positive phase of C
*ppNodeT = Dar_Not(Dar_ObjChild0(pNode0));//pNode1->p1);
*ppNodeE = Dar_Not(Dar_ObjChild1(pNode1));//pNode2->p2);
return Dar_ObjChild1(pNode0);//pNode1->p2;
}
}
assert( 0 ); // this is not MUX
return NULL;
}
/**Function*************************************************************
Synopsis [Prints Eqn formula for the AIG rooted at this node.]
Description [The formula is in terms of PIs, which should have
their names assigned in pObj->pData fields.]
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_ObjPrintEqn( FILE * pFile, Dar_Obj_t * pObj, Vec_Vec_t * vLevels, int Level )
{
Vec_Ptr_t * vSuper;
Dar_Obj_t * pFanin;
int fCompl, i;
// store the complemented attribute
fCompl = Dar_IsComplement(pObj);
pObj = Dar_Regular(pObj);
// constant case
if ( Dar_ObjIsConst1(pObj) )
{
fprintf( pFile, "%d", !fCompl );
return;
}
// PI case
if ( Dar_ObjIsPi(pObj) )
{
fprintf( pFile, "%s%s", fCompl? "!" : "", pObj->pData );
return;
}
// AND case
Vec_VecExpand( vLevels, Level );
vSuper = Vec_VecEntry(vLevels, Level);
Dar_ObjCollectMulti( pObj, vSuper );
fprintf( pFile, "%s", (Level==0? "" : "(") );
Vec_PtrForEachEntry( vSuper, pFanin, i )
{
Dar_ObjPrintEqn( pFile, Dar_NotCond(pFanin, fCompl), vLevels, Level+1 );
if ( i < Vec_PtrSize(vSuper) - 1 )
fprintf( pFile, " %s ", fCompl? "+" : "*" );
}
fprintf( pFile, "%s", (Level==0? "" : ")") );
return;
}
/**Function*************************************************************
Synopsis [Prints Verilog formula for the AIG rooted at this node.]
Description [The formula is in terms of PIs, which should have
their names assigned in pObj->pData fields.]
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_ObjPrintVerilog( FILE * pFile, Dar_Obj_t * pObj, Vec_Vec_t * vLevels, int Level )
{
Vec_Ptr_t * vSuper;
Dar_Obj_t * pFanin, * pFanin0, * pFanin1, * pFaninC;
int fCompl, i;
// store the complemented attribute
fCompl = Dar_IsComplement(pObj);
pObj = Dar_Regular(pObj);
// constant case
if ( Dar_ObjIsConst1(pObj) )
{
fprintf( pFile, "1\'b%d", !fCompl );
return;
}
// PI case
if ( Dar_ObjIsPi(pObj) )
{
fprintf( pFile, "%s%s", fCompl? "~" : "", pObj->pData );
return;
}
// EXOR case
if ( Dar_ObjIsExor(pObj) )
{
Vec_VecExpand( vLevels, Level );
vSuper = Vec_VecEntry( vLevels, Level );
Dar_ObjCollectMulti( pObj, vSuper );
fprintf( pFile, "%s", (Level==0? "" : "(") );
Vec_PtrForEachEntry( vSuper, pFanin, i )
{
Dar_ObjPrintVerilog( pFile, Dar_NotCond(pFanin, (fCompl && i==0)), vLevels, Level+1 );
if ( i < Vec_PtrSize(vSuper) - 1 )
fprintf( pFile, " ^ " );
}
fprintf( pFile, "%s", (Level==0? "" : ")") );
return;
}
// MUX case
if ( Dar_ObjIsMuxType(pObj) )
{
if ( Dar_ObjRecognizeExor( pObj, &pFanin0, &pFanin1 ) )
{
fprintf( pFile, "%s", (Level==0? "" : "(") );
Dar_ObjPrintVerilog( pFile, Dar_NotCond(pFanin0, fCompl), vLevels, Level+1 );
fprintf( pFile, " ^ " );
Dar_ObjPrintVerilog( pFile, pFanin1, vLevels, Level+1 );
fprintf( pFile, "%s", (Level==0? "" : ")") );
}
else
{
pFaninC = Dar_ObjRecognizeMux( pObj, &pFanin1, &pFanin0 );
fprintf( pFile, "%s", (Level==0? "" : "(") );
Dar_ObjPrintVerilog( pFile, pFaninC, vLevels, Level+1 );
fprintf( pFile, " ? " );
Dar_ObjPrintVerilog( pFile, Dar_NotCond(pFanin1, fCompl), vLevels, Level+1 );
fprintf( pFile, " : " );
Dar_ObjPrintVerilog( pFile, Dar_NotCond(pFanin0, fCompl), vLevels, Level+1 );
fprintf( pFile, "%s", (Level==0? "" : ")") );
}
return;
}
// AND case
Vec_VecExpand( vLevels, Level );
vSuper = Vec_VecEntry(vLevels, Level);
Dar_ObjCollectMulti( pObj, vSuper );
fprintf( pFile, "%s", (Level==0? "" : "(") );
Vec_PtrForEachEntry( vSuper, pFanin, i )
{
Dar_ObjPrintVerilog( pFile, Dar_NotCond(pFanin, fCompl), vLevels, Level+1 );
if ( i < Vec_PtrSize(vSuper) - 1 )
fprintf( pFile, " %s ", fCompl? "|" : "&" );
}
fprintf( pFile, "%s", (Level==0? "" : ")") );
return;
}
/**Function*************************************************************
Synopsis [Prints node in HAIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_ObjPrintVerbose( Dar_Obj_t * pObj, int fHaig )
{
assert( !Dar_IsComplement(pObj) );
printf( "Node %p : ", pObj );
if ( Dar_ObjIsConst1(pObj) )
printf( "constant 1" );
else if ( Dar_ObjIsPi(pObj) )
printf( "PI" );
else
printf( "AND( %p%s, %p%s )",
Dar_ObjFanin0(pObj), (Dar_ObjFaninC0(pObj)? "\'" : " "),
Dar_ObjFanin1(pObj), (Dar_ObjFaninC1(pObj)? "\'" : " ") );
printf( " (refs = %3d)", Dar_ObjRefs(pObj) );
}
/**Function*************************************************************
Synopsis [Prints node in HAIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_ManPrintVerbose( Dar_Man_t * p, int fHaig )
{
Vec_Ptr_t * vNodes;
Dar_Obj_t * pObj;
int i;
printf( "PIs: " );
Dar_ManForEachPi( p, pObj, i )
printf( " %p", pObj );
printf( "\n" );
vNodes = Dar_ManDfs( p );
Vec_PtrForEachEntry( vNodes, pObj, i )
Dar_ObjPrintVerbose( pObj, fHaig ), printf( "\n" );
printf( "\n" );
}
/**Function*************************************************************
Synopsis [Writes the AIG into the BLIF file.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_ManDumpBlif( Dar_Man_t * p, char * pFileName )
{
FILE * pFile;
Vec_Ptr_t * vNodes;
Dar_Obj_t * pObj, * pConst1 = NULL;
int i, nDigits, Counter = 0;
if ( Dar_ManPoNum(p) == 0 )
{
printf( "Dar_ManDumpBlif(): AIG manager does not have POs.\n" );
return;
}
// collect nodes in the DFS order
vNodes = Dar_ManDfs( p );
// assign IDs to objects
Dar_ManConst1(p)->pData = (void *)Counter++;
Dar_ManForEachPi( p, pObj, i )
pObj->pData = (void *)Counter++;
Dar_ManForEachPo( p, pObj, i )
pObj->pData = (void *)Counter++;
Vec_PtrForEachEntry( vNodes, pObj, i )
pObj->pData = (void *)Counter++;
nDigits = Extra_Base10Log( Counter );
// write the file
pFile = fopen( pFileName, "w" );
fprintf( pFile, "# BLIF file written by procedure Dar_ManDumpBlif() in ABC\n" );
fprintf( pFile, "# http://www.eecs.berkeley.edu/~alanmi/abc/\n" );
fprintf( pFile, ".model test\n" );
// write PIs
fprintf( pFile, ".inputs" );
Dar_ManForEachPi( p, pObj, i )
fprintf( pFile, " n%0*d", nDigits, (int)pObj->pData );
fprintf( pFile, "\n" );
// write POs
fprintf( pFile, ".outputs" );
Dar_ManForEachPo( p, pObj, i )
fprintf( pFile, " n%0*d", nDigits, (int)pObj->pData );
fprintf( pFile, "\n" );
// write nodes
Vec_PtrForEachEntry( vNodes, pObj, i )
{
fprintf( pFile, ".names n%0*d n%0*d n%0*d\n",
nDigits, (int)Dar_ObjFanin0(pObj)->pData,
nDigits, (int)Dar_ObjFanin1(pObj)->pData,
nDigits, (int)pObj->pData );
fprintf( pFile, "%d%d 1\n", !Dar_ObjFaninC0(pObj), !Dar_ObjFaninC1(pObj) );
}
// write POs
Dar_ManForEachPo( p, pObj, i )
{
fprintf( pFile, ".names n%0*d n%0*d\n",
nDigits, (int)Dar_ObjFanin0(pObj)->pData,
nDigits, (int)pObj->pData );
fprintf( pFile, "%d 1\n", !Dar_ObjFaninC0(pObj) );
if ( Dar_ObjIsConst1(Dar_ObjFanin0(pObj)) )
pConst1 = Dar_ManConst1(p);
}
if ( pConst1 )
fprintf( pFile, ".names n%0*d\n 1\n", nDigits, (int)pConst1->pData );
fprintf( pFile, ".end\n\n" );
fclose( pFile );
Vec_PtrFree( vNodes );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

48
src/aig/dar/dar_.c Normal file
View File

@ -0,0 +1,48 @@
/**CFile****************************************************************
FileName [dar_.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [DAG-aware AIG rewriting.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: dar_.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
#include "dar.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

13
src/aig/dar/module.make Normal file
View File

@ -0,0 +1,13 @@
SRC += src/aig/dar/darBalance.c \
src/aig/dar/darCheck.c \
src/aig/dar/darCore.c \
src/aig/dar/darCut.c \
src/aig/dar/darData.c \
src/aig/dar/darDfs.c \
src/aig/dar/darLib.c \
src/aig/dar/darMan.c \
src/aig/dar/darMem.c \
src/aig/dar/darObj.c \
src/aig/dar/darOper.c \
src/aig/dar/darTable.c \
src/aig/dar/darUtil.c

View File

@ -149,7 +149,7 @@ static inline int Hop_ManNodeNum( Hop_Man_t * p ) { return p->nO
static inline int Hop_ManGetCost( Hop_Man_t * p ) { return p->nObjs[AIG_AND]+3*p->nObjs[AIG_EXOR]; }
static inline int Hop_ManObjNum( Hop_Man_t * p ) { return p->nCreated - p->nDeleted; }
static inline Hop_Type_t Hop_ObjType( Hop_Obj_t * pObj ) { return pObj->Type; }
static inline Hop_Type_t Hop_ObjType( Hop_Obj_t * pObj ) { return (Hop_Type_t)pObj->Type; }
static inline int Hop_ObjIsNone( Hop_Obj_t * pObj ) { return pObj->Type == AIG_NONE; }
static inline int Hop_ObjIsConst1( Hop_Obj_t * pObj ) { assert(!Hop_IsComplement(pObj)); return pObj->Type == AIG_CONST1; }
static inline int Hop_ObjIsPi( Hop_Obj_t * pObj ) { return pObj->Type == AIG_PI; }
@ -182,8 +182,8 @@ static inline Hop_Obj_t * Hop_ObjFanin0( Hop_Obj_t * pObj ) { return Hop_R
static inline Hop_Obj_t * Hop_ObjFanin1( Hop_Obj_t * pObj ) { return Hop_Regular(pObj->pFanin1); }
static inline Hop_Obj_t * Hop_ObjChild0( Hop_Obj_t * pObj ) { return pObj->pFanin0; }
static inline Hop_Obj_t * Hop_ObjChild1( Hop_Obj_t * pObj ) { return pObj->pFanin1; }
static inline Hop_Obj_t * Hop_ObjChild0Copy( Hop_Obj_t * pObj ) { assert( !Hop_IsComplement(pObj) ); return Hop_ObjFanin0(pObj)? Hop_NotCond(Hop_ObjFanin0(pObj)->pData, Hop_ObjFaninC0(pObj)) : NULL; }
static inline Hop_Obj_t * Hop_ObjChild1Copy( Hop_Obj_t * pObj ) { assert( !Hop_IsComplement(pObj) ); return Hop_ObjFanin1(pObj)? Hop_NotCond(Hop_ObjFanin1(pObj)->pData, Hop_ObjFaninC1(pObj)) : NULL; }
static inline Hop_Obj_t * Hop_ObjChild0Copy( Hop_Obj_t * pObj ) { assert( !Hop_IsComplement(pObj) ); return Hop_ObjFanin0(pObj)? Hop_NotCond((Hop_Obj_t *)Hop_ObjFanin0(pObj)->pData, Hop_ObjFaninC0(pObj)) : NULL; }
static inline Hop_Obj_t * Hop_ObjChild1Copy( Hop_Obj_t * pObj ) { assert( !Hop_IsComplement(pObj) ); return Hop_ObjFanin1(pObj)? Hop_NotCond((Hop_Obj_t *)Hop_ObjFanin1(pObj)->pData, Hop_ObjFaninC1(pObj)) : NULL; }
static inline int Hop_ObjLevel( Hop_Obj_t * pObj ) { return pObj->nRefs; }
static inline int Hop_ObjLevelNew( Hop_Obj_t * pObj ) { return 1 + Hop_ObjIsExor(pObj) + AIG_MAX(Hop_ObjFanin0(pObj)->nRefs, Hop_ObjFanin1(pObj)->nRefs); }
static inline int Hop_ObjFaninPhase( Hop_Obj_t * pObj ) { return Hop_IsComplement(pObj)? !Hop_Regular(pObj)->fPhase : pObj->fPhase; }
@ -210,8 +210,16 @@ static inline Hop_Obj_t * Hop_ObjCreateGhost( Hop_Man_t * p, Hop_Obj_t * p0, Ho
assert( Type == AIG_PI || Hop_Regular(p0) != Hop_Regular(p1) );
pGhost = Hop_ManGhost(p);
pGhost->Type = Type;
pGhost->pFanin0 = p0 < p1? p0 : p1;
pGhost->pFanin1 = p0 < p1? p1 : p0;
if ( Hop_Regular(p0)->Id < Hop_Regular(p1)->Id )
{
pGhost->pFanin0 = p0;
pGhost->pFanin1 = p1;
}
else
{
pGhost->pFanin0 = p1;
pGhost->pFanin1 = p0;
}
return pGhost;
}

View File

@ -74,7 +74,7 @@ int Hop_ManCheck( Hop_Man_t * p )
printf( "Hop_ManCheck: The AIG has internal node \"%p\" with a NULL fanin.\n", pObj );
return 0;
}
if ( Hop_ObjFanin0(pObj) >= Hop_ObjFanin1(pObj) )
if ( Hop_ObjFanin0(pObj)->Id >= Hop_ObjFanin1(pObj)->Id )
{
printf( "Hop_ManCheck: The AIG has node \"%p\" with a wrong ordering of fanins.\n", pObj );
return 0;

View File

@ -60,6 +60,7 @@ Hop_Man_t * Hop_ManStart()
p->pConst1->fPhase = 1;
p->nCreated = 1;
// start the table
// p->nTableSize = 107;
p->nTableSize = 10007;
p->pTable = ALLOC( Hop_Obj_t *, p->nTableSize );
memset( p->pTable, 0, sizeof(Hop_Obj_t *) * p->nTableSize );

View File

@ -38,13 +38,14 @@ static unsigned long Hop_Hash( Hop_Obj_t * pObj, int TableSize )
// returns the place where this node is stored (or should be stored)
static Hop_Obj_t ** Hop_TableFind( Hop_Man_t * p, Hop_Obj_t * pObj )
{
int i;
Hop_Obj_t ** ppEntry;
assert( Hop_ObjChild0(pObj) && Hop_ObjChild1(pObj) );
assert( Hop_ObjChild0(pObj) < Hop_ObjChild1(pObj) );
for ( i = Hop_Hash(pObj, p->nTableSize); p->pTable[i]; i = (i+1) % p->nTableSize )
if ( p->pTable[i] == pObj )
break;
return p->pTable + i;
assert( Hop_ObjFanin0(pObj)->Id < Hop_ObjFanin1(pObj)->Id );
for ( ppEntry = p->pTable + Hop_Hash(pObj, p->nTableSize); *ppEntry; ppEntry = &(*ppEntry)->pNext )
if ( *ppEntry == pObj )
return ppEntry;
assert( *ppEntry == NULL );
return ppEntry;
}
static void Hop_TableResize( Hop_Man_t * p );
@ -56,7 +57,7 @@ static unsigned int Cudd_PrimeAig( unsigned int p );
/**Function*************************************************************
Synopsis [Checks if node with the given attributes is in the hash table.]
Synopsis [Checks if a node with the given attributes is in the hash table.]
Description []
@ -67,18 +68,18 @@ static unsigned int Cudd_PrimeAig( unsigned int p );
***********************************************************************/
Hop_Obj_t * Hop_TableLookup( Hop_Man_t * p, Hop_Obj_t * pGhost )
{
int i;
Hop_Obj_t * pEntry;
assert( !Hop_IsComplement(pGhost) );
assert( Hop_ObjChild0(pGhost) && Hop_ObjChild1(pGhost) );
assert( Hop_ObjChild0(pGhost) < Hop_ObjChild1(pGhost) );
assert( Hop_ObjFanin0(pGhost)->Id < Hop_ObjFanin1(pGhost)->Id );
if ( p->fRefCount && (!Hop_ObjRefs(Hop_ObjFanin0(pGhost)) || !Hop_ObjRefs(Hop_ObjFanin1(pGhost))) )
return NULL;
for ( i = Hop_Hash(pGhost, p->nTableSize); p->pTable[i]; i = (i+1) % p->nTableSize )
for ( pEntry = p->pTable[Hop_Hash(pGhost, p->nTableSize)]; pEntry; pEntry = pEntry->pNext )
{
if ( Hop_ObjChild0(p->pTable[i]) == Hop_ObjChild0(pGhost) &&
Hop_ObjChild1(p->pTable[i]) == Hop_ObjChild1(pGhost) &&
Hop_ObjType(p->pTable[i]) == Hop_ObjType(pGhost) )
return p->pTable[i];
if ( Hop_ObjChild0(pEntry) == Hop_ObjChild0(pGhost) &&
Hop_ObjChild1(pEntry) == Hop_ObjChild1(pGhost) &&
Hop_ObjType(pEntry) == Hop_ObjType(pGhost) )
return pEntry;
}
return NULL;
}
@ -99,7 +100,7 @@ void Hop_TableInsert( Hop_Man_t * p, Hop_Obj_t * pObj )
Hop_Obj_t ** ppPlace;
assert( !Hop_IsComplement(pObj) );
assert( Hop_TableLookup(p, pObj) == NULL );
if ( p->nTableSize < 2 * Hop_ManNodeNum(p) )
if ( (pObj->Id & 0xFF) == 0 && 2 * p->nTableSize < Hop_ManNodeNum(p) )
Hop_TableResize( p );
ppPlace = Hop_TableFind( p, pObj );
assert( *ppPlace == NULL );
@ -119,20 +120,13 @@ void Hop_TableInsert( Hop_Man_t * p, Hop_Obj_t * pObj )
***********************************************************************/
void Hop_TableDelete( Hop_Man_t * p, Hop_Obj_t * pObj )
{
Hop_Obj_t * pEntry, ** ppPlace;
int i;
Hop_Obj_t ** ppPlace;
assert( !Hop_IsComplement(pObj) );
ppPlace = Hop_TableFind( p, pObj );
assert( *ppPlace == pObj ); // node should be in the table
*ppPlace = NULL;
// rehash the adjacent entries
i = ppPlace - p->pTable;
for ( i = (i+1) % p->nTableSize; p->pTable[i]; i = (i+1) % p->nTableSize )
{
pEntry = p->pTable[i];
p->pTable[i] = 0;
Hop_TableInsert( p, pEntry );
}
// remove the node
*ppPlace = pObj->pNext;
pObj->pNext = NULL;
}
/**Function*************************************************************
@ -148,9 +142,11 @@ void Hop_TableDelete( Hop_Man_t * p, Hop_Obj_t * pObj )
***********************************************************************/
int Hop_TableCountEntries( Hop_Man_t * p )
{
Hop_Obj_t * pEntry;
int i, Counter = 0;
for ( i = 0; i < p->nTableSize; i++ )
Counter += (p->pTable[i] != NULL);
for ( pEntry = p->pTable[i]; pEntry; pEntry = pEntry->pNext )
Counter++;
return Counter;
}
@ -167,30 +163,32 @@ int Hop_TableCountEntries( Hop_Man_t * p )
***********************************************************************/
void Hop_TableResize( Hop_Man_t * p )
{
Hop_Obj_t * pEntry, * pNext;
Hop_Obj_t ** pTableOld, ** ppPlace;
int nTableSizeOld, Counter, nEntries, e, clk;
int nTableSizeOld, Counter, nEntries, i, clk;
clk = clock();
// save the old table
pTableOld = p->pTable;
nTableSizeOld = p->nTableSize;
// get the new table
p->nTableSize = Cudd_PrimeAig( 5 * Hop_ManNodeNum(p) );
p->nTableSize = Cudd_PrimeAig( 2 * Hop_ManNodeNum(p) );
p->pTable = ALLOC( Hop_Obj_t *, p->nTableSize );
memset( p->pTable, 0, sizeof(Hop_Obj_t *) * p->nTableSize );
// rehash the entries from the old table
Counter = 0;
for ( e = 0; e < nTableSizeOld; e++ )
for ( i = 0; i < nTableSizeOld; i++ )
for ( pEntry = pTableOld[i], pNext = pEntry? pEntry->pNext : NULL; pEntry; pEntry = pNext, pNext = pEntry? pEntry->pNext : NULL )
{
if ( pTableOld[e] == 0 )
continue;
// get the place where this entry goes in the table
ppPlace = Hop_TableFind( p, pEntry );
assert( *ppPlace == NULL ); // should not be there
// add the entry to the list
*ppPlace = pEntry;
pEntry->pNext = NULL;
Counter++;
// get the place where this entry goes in the table table
ppPlace = Hop_TableFind( p, pTableOld[e] );
assert( *ppPlace == NULL ); // should not be in the table
*ppPlace = pTableOld[e];
}
nEntries = Hop_ManNodeNum(p);
// assert( Counter == nEntries );
assert( Counter == nEntries );
// printf( "Increasing the structural table size from %6d to %6d. ", nTableSizeOld, p->nTableSize );
// PRT( "Time", clock() - clk );
// replace the table and the parameters
@ -210,16 +208,15 @@ clk = clock();
******************************************************************************/
void Hop_TableProfile( Hop_Man_t * p )
{
int i, Counter = 0;
Hop_Obj_t * pEntry;
int i, Counter;
for ( i = 0; i < p->nTableSize; i++ )
{
if ( p->pTable[i] )
Counter = 0;
for ( pEntry = p->pTable[i]; pEntry; pEntry = pEntry->pNext )
Counter++;
else if ( Counter )
{
if ( Counter )
printf( "%d ", Counter );
Counter = 0;
}
}
}
@ -237,7 +234,6 @@ void Hop_TableProfile( Hop_Man_t * p )
unsigned int Cudd_PrimeAig( unsigned int p)
{
int i,pn;
p--;
do {
p++;

View File

@ -330,7 +330,7 @@ static inline bool Abc_NtkIsComb( Abc_Ntk_t * pNtk ) { return Ab
static inline bool Abc_NtkHasOnlyLatchBoxes(Abc_Ntk_t * pNtk ){ return Abc_NtkLatchNum(pNtk) == Abc_NtkBoxNum(pNtk); }
// creating simple objects
extern inline Abc_Obj_t * Abc_NtkCreateObj( Abc_Ntk_t * pNtk, Abc_ObjType_t Type );
extern Abc_Obj_t * Abc_NtkCreateObj( Abc_Ntk_t * pNtk, Abc_ObjType_t Type );
static inline Abc_Obj_t * Abc_NtkCreatePi( Abc_Ntk_t * pNtk ) { return Abc_NtkCreateObj( pNtk, ABC_OBJ_PI ); }
static inline Abc_Obj_t * Abc_NtkCreatePo( Abc_Ntk_t * pNtk ) { return Abc_NtkCreateObj( pNtk, ABC_OBJ_PO ); }
static inline Abc_Obj_t * Abc_NtkCreateBi( Abc_Ntk_t * pNtk ) { return Abc_NtkCreateObj( pNtk, ABC_OBJ_BI ); }
@ -417,8 +417,8 @@ static inline Abc_Obj_t * Abc_ObjChild1( Abc_Obj_t * pObj ) { return Ab
static inline Abc_Obj_t * Abc_ObjChildCopy( Abc_Obj_t * pObj, int i ){ return Abc_ObjNotCond( Abc_ObjFanin(pObj,i)->pCopy, Abc_ObjFaninC(pObj,i) ); }
static inline Abc_Obj_t * Abc_ObjChild0Copy( Abc_Obj_t * pObj ) { return Abc_ObjNotCond( Abc_ObjFanin0(pObj)->pCopy, Abc_ObjFaninC0(pObj) ); }
static inline Abc_Obj_t * Abc_ObjChild1Copy( Abc_Obj_t * pObj ) { return Abc_ObjNotCond( Abc_ObjFanin1(pObj)->pCopy, Abc_ObjFaninC1(pObj) ); }
static inline Abc_Obj_t * Abc_ObjChild0Data( Abc_Obj_t * pObj ) { return Abc_ObjNotCond( Abc_ObjFanin0(pObj)->pData, Abc_ObjFaninC0(pObj) ); }
static inline Abc_Obj_t * Abc_ObjChild1Data( Abc_Obj_t * pObj ) { return Abc_ObjNotCond( Abc_ObjFanin1(pObj)->pData, Abc_ObjFaninC1(pObj) ); }
static inline Abc_Obj_t * Abc_ObjChild0Data( Abc_Obj_t * pObj ) { return Abc_ObjNotCond( (Abc_Obj_t *)Abc_ObjFanin0(pObj)->pData, Abc_ObjFaninC0(pObj) ); }
static inline Abc_Obj_t * Abc_ObjChild1Data( Abc_Obj_t * pObj ) { return Abc_ObjNotCond( (Abc_Obj_t *)Abc_ObjFanin1(pObj)->pData, Abc_ObjFaninC1(pObj) ); }
static inline Hop_Obj_t * Abc_ObjChild0Equiv( Abc_Obj_t * pObj ) { return Hop_NotCond( Abc_ObjFanin0(pObj)->pEquiv, Abc_ObjFaninC0(pObj) ); }
static inline Hop_Obj_t * Abc_ObjChild1Equiv( Abc_Obj_t * pObj ) { return Hop_NotCond( Abc_ObjFanin1(pObj)->pEquiv, Abc_ObjFaninC1(pObj) ); }
@ -452,17 +452,17 @@ static inline int Abc_LatchInit( Abc_Obj_t * pLatch ) { assert(Ab
// global BDDs of the nodes
static inline void * Abc_NtkGlobalBdd( Abc_Ntk_t * pNtk ) { return (void *)Vec_PtrEntry(pNtk->vAttrs, VEC_ATTR_GLOBAL_BDD); }
static inline DdManager * Abc_NtkGlobalBddMan( Abc_Ntk_t * pNtk ) { return (DdManager *)Vec_AttMan( Abc_NtkGlobalBdd(pNtk) ); }
static inline DdNode ** Abc_NtkGlobalBddArray( Abc_Ntk_t * pNtk ) { return (DdNode **)Vec_AttArray( Abc_NtkGlobalBdd(pNtk) ); }
static inline DdNode * Abc_ObjGlobalBdd( Abc_Obj_t * pObj ) { return (DdNode *)Vec_AttEntry( Abc_NtkGlobalBdd(pObj->pNtk), pObj->Id ); }
static inline void Abc_ObjSetGlobalBdd( Abc_Obj_t * pObj, DdNode * bF ) { Vec_AttWriteEntry( Abc_NtkGlobalBdd(pObj->pNtk), pObj->Id, bF ); }
static inline DdManager * Abc_NtkGlobalBddMan( Abc_Ntk_t * pNtk ) { return (DdManager *)Vec_AttMan( (Vec_Att_t *)Abc_NtkGlobalBdd(pNtk) ); }
static inline DdNode ** Abc_NtkGlobalBddArray( Abc_Ntk_t * pNtk ) { return (DdNode **)Vec_AttArray( (Vec_Att_t *)Abc_NtkGlobalBdd(pNtk) ); }
static inline DdNode * Abc_ObjGlobalBdd( Abc_Obj_t * pObj ) { return (DdNode *)Vec_AttEntry( (Vec_Att_t *)Abc_NtkGlobalBdd(pObj->pNtk), pObj->Id ); }
static inline void Abc_ObjSetGlobalBdd( Abc_Obj_t * pObj, DdNode * bF ) { Vec_AttWriteEntry( (Vec_Att_t *)Abc_NtkGlobalBdd(pObj->pNtk), pObj->Id, bF ); }
// MV variables of the nodes
static inline void * Abc_NtkMvVar( Abc_Ntk_t * pNtk ) { return Vec_PtrEntry(pNtk->vAttrs, VEC_ATTR_MVVAR); }
static inline void * Abc_NtkMvVarMan( Abc_Ntk_t * pNtk ) { return Abc_NtkMvVar(pNtk)? Vec_AttMan( Abc_NtkMvVar(pNtk) ) : NULL; }
static inline void * Abc_ObjMvVar( Abc_Obj_t * pObj ) { return Abc_NtkMvVar(pObj->pNtk)? Vec_AttEntry( Abc_NtkMvVar(pObj->pNtk), pObj->Id ) : NULL; }
static inline void * Abc_NtkMvVarMan( Abc_Ntk_t * pNtk ) { return Abc_NtkMvVar(pNtk)? Vec_AttMan( (Vec_Att_t *)Abc_NtkMvVar(pNtk) ) : NULL; }
static inline void * Abc_ObjMvVar( Abc_Obj_t * pObj ) { return Abc_NtkMvVar(pObj->pNtk)? Vec_AttEntry( (Vec_Att_t *)Abc_NtkMvVar(pObj->pNtk), pObj->Id ) : NULL; }
static inline int Abc_ObjMvVarNum( Abc_Obj_t * pObj ) { return (Abc_NtkMvVar(pObj->pNtk) && Abc_ObjMvVar(pObj))? *((int*)Abc_ObjMvVar(pObj)) : 2; }
static inline void Abc_ObjSetMvVar( Abc_Obj_t * pObj, void * pV) { Vec_AttWriteEntry( Abc_NtkMvVar(pObj->pNtk), pObj->Id, pV ); }
static inline void Abc_ObjSetMvVar( Abc_Obj_t * pObj, void * pV) { Vec_AttWriteEntry( (Vec_Att_t *)Abc_NtkMvVar(pObj->pNtk), pObj->Id, pV ); }
// outputs the runtime in seconds
#define PRT(a,t) printf("%s = ", (a)); printf("%6.2f sec\n", (float)(t)/(float)(CLOCKS_PER_SEC))

View File

@ -329,6 +329,8 @@ void Abc_Init( Abc_Frame_t * pAbc )
// Abc_NtkPrint256();
// Kit_TruthCountMintermsPrecomp();
// Kit_DsdPrecompute4Vars();
Dar_LibStart();
}
/**Function*************************************************************
@ -344,6 +346,8 @@ void Abc_Init( Abc_Frame_t * pAbc )
***********************************************************************/
void Abc_End()
{
Dar_LibStop();
Abc_NtkFraigStoreClean();
// Rwt_Man4ExplorePrint();
}
@ -6034,13 +6038,16 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
// Abc_NtkCompareSupports( pNtk );
// Abc_NtkCompareCones( pNtk );
/*
{
extern Vec_Vec_t * Abc_NtkPartitionSmart( Abc_Ntk_t * pNtk, int fVerbose );
Vec_Vec_t * vParts;
vParts = Abc_NtkPartitionSmart( pNtk, 1 );
Vec_VecFree( vParts );
}
*/
// Abc_Ntk4VarTable( pNtk );
// Dat_NtkGenerateArrays( pNtk );
return 0;
@ -7677,7 +7684,8 @@ int Abc_CommandFraigSweep( Abc_Frame_t * pAbc, int argc, char ** argv )
int fUseInv;
int fExdc;
int fVerbose;
extern bool Abc_NtkFraigSweep( Abc_Ntk_t * pNtk, int fUseInv, int fExdc, int fVerbose );
int fVeryVerbose;
extern bool Abc_NtkFraigSweep( Abc_Ntk_t * pNtk, int fUseInv, int fExdc, int fVerbose, int fVeryVerbose );
pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
@ -7687,8 +7695,9 @@ int Abc_CommandFraigSweep( Abc_Frame_t * pAbc, int argc, char ** argv )
fUseInv = 1;
fExdc = 0;
fVerbose = 0;
fVeryVerbose = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "ievh" ) ) != EOF )
while ( ( c = Extra_UtilGetopt( argc, argv, "ievwh" ) ) != EOF )
{
switch ( c )
{
@ -7701,6 +7710,9 @@ int Abc_CommandFraigSweep( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'v':
fVerbose ^= 1;
break;
case 'w':
fVeryVerbose ^= 1;
break;
case 'h':
goto usage;
default:
@ -7724,7 +7736,7 @@ int Abc_CommandFraigSweep( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1;
}
// modify the current network
if ( !Abc_NtkFraigSweep( pNtk, fUseInv, fExdc, fVerbose ) )
if ( !Abc_NtkFraigSweep( pNtk, fUseInv, fExdc, fVerbose, fVeryVerbose ) )
{
fprintf( pErr, "Sweeping has failed.\n" );
return 1;
@ -7732,10 +7744,11 @@ int Abc_CommandFraigSweep( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
fprintf( pErr, "usage: fraig_sweep [-evh]\n" );
fprintf( pErr, "usage: fraig_sweep [-evwh]\n" );
fprintf( pErr, "\t performs technology-dependent sweep\n" );
fprintf( pErr, "\t-e : toggle functional sweeping using EXDC [default = %s]\n", fExdc? "yes": "no" );
fprintf( pErr, "\t-v : prints verbose information [default = %s]\n", fVerbose? "yes": "no" );
fprintf( pErr, "\t-w : prints equivalence class information [default = %s]\n", fVeryVerbose? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
}
@ -8284,7 +8297,7 @@ int Abc_CommandMap( Abc_Frame_t * pAbc, int argc, char ** argv )
int fVerbose;
int c;
extern Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, int fSwitching, int fVerbose );
extern bool Abc_NtkFraigSweep( Abc_Ntk_t * pNtk, int fUseInv, int fExdc, int fVerbose );
extern bool Abc_NtkFraigSweep( Abc_Ntk_t * pNtk, int fUseInv, int fExdc, int fVerbose, int fVeryVerbose );
pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
@ -8375,7 +8388,7 @@ int Abc_CommandMap( Abc_Frame_t * pAbc, int argc, char ** argv )
}
if ( fSweep )
Abc_NtkFraigSweep( pNtkRes, 0, 0, 0 );
Abc_NtkFraigSweep( pNtkRes, 0, 0, 0, 0 );
// replace the current network
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
@ -10346,11 +10359,12 @@ int Abc_CommandCec( Abc_Frame_t * pAbc, int argc, char ** argv )
int nPartSize;
int nConfLimit;
int nInsLimit;
int fPartition;
extern void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nInsLimit );
extern void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fVerbose );
extern void Abc_NtkCecFraigPart( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int nPartSize, int fVerbose );
extern void Abc_NtkCecFraigPartAuto( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fVerbose );
pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
@ -10363,8 +10377,9 @@ int Abc_CommandCec( Abc_Frame_t * pAbc, int argc, char ** argv )
nPartSize = 0;
nConfLimit = 10000;
nInsLimit = 0;
fPartition = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "TCIPsvh" ) ) != EOF )
while ( ( c = Extra_UtilGetopt( argc, argv, "TCIPpsvh" ) ) != EOF )
{
switch ( c )
{
@ -10412,6 +10427,9 @@ int Abc_CommandCec( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( nPartSize < 0 )
goto usage;
break;
case 'p':
fPartition ^= 1;
break;
case 's':
fSat ^= 1;
break;
@ -10429,7 +10447,9 @@ int Abc_CommandCec( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1;
// perform equivalence checking
if ( nPartSize )
if ( fPartition )
Abc_NtkCecFraigPartAuto( pNtk1, pNtk2, nSeconds, fVerbose );
else if ( nPartSize )
Abc_NtkCecFraigPart( pNtk1, pNtk2, nSeconds, nPartSize, fVerbose );
else if ( fSat )
Abc_NtkCecSat( pNtk1, pNtk2, nConfLimit, nInsLimit );
@ -10445,12 +10465,13 @@ usage:
strcpy( Buffer, "unused" );
else
sprintf( Buffer, "%d", nPartSize );
fprintf( pErr, "usage: cec [-T num] [-C num] [-I num] [-P num] [-svh] <file1> <file2>\n" );
fprintf( pErr, "usage: cec [-T num] [-C num] [-I num] [-P num] [-psvh] <file1> <file2>\n" );
fprintf( pErr, "\t performs combinational equivalence checking\n" );
fprintf( pErr, "\t-T num : approximate runtime limit in seconds [default = %d]\n", nSeconds );
fprintf( pErr, "\t-C num : limit on the number of conflicts [default = %d]\n", nConfLimit );
fprintf( pErr, "\t-I num : limit on the number of clause inspections [default = %d]\n", nInsLimit );
fprintf( pErr, "\t-P num : partition size for multi-output networks [default = %s]\n", Buffer );
fprintf( pErr, "\t-p : toggle automatic partitioning [default = %s]\n", fPartition? "yes": "no" );
fprintf( pErr, "\t-s : toggle \"SAT only\" and \"FRAIG + SAT\" [default = %s]\n", fSat? "SAT only": "FRAIG + SAT" );
fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");

154
src/base/abci/abcDar.c Normal file
View File

@ -0,0 +1,154 @@
/**CFile****************************************************************
FileName [abcDar.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [DAG-aware rewriting.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abcDar.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abc.h"
#include "dar.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static Dar_Man_t * Abc_NtkToDar( Abc_Ntk_t * pNtk );
static Abc_Ntk_t * Abc_NtkFromDar( Abc_Ntk_t * pNtkOld, Dar_Man_t * pMan );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Gives the current ABC network to AIG manager for processing.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkDar( Abc_Ntk_t * pNtk )
{
Abc_Ntk_t * pNtkAig;
Dar_Man_t * pMan;//, * pTemp;
assert( Abc_NtkIsStrash(pNtk) );
// convert to the AIG manager
pMan = Abc_NtkToDar( pNtk );
if ( pMan == NULL )
return NULL;
if ( !Dar_ManCheck( pMan ) )
{
printf( "Abc_NtkDar: AIG check has failed.\n" );
Dar_ManStop( pMan );
return NULL;
}
// perform balance
Dar_ManPrintStats( pMan );
// Dar_ManDumpBlif( pMan, "aig_temp.blif" );
pMan->pPars = Dar_ManDefaultParams();
Dar_ManRewrite( pMan );
Dar_ManPrintStats( pMan );
// convert from the AIG manager
pNtkAig = Abc_NtkFromDar( pNtk, pMan );
if ( pNtkAig == NULL )
return NULL;
Dar_ManStop( pMan );
// make sure everything is okay
if ( !Abc_NtkCheck( pNtkAig ) )
{
printf( "Abc_NtkDar: The network check has failed.\n" );
Abc_NtkDelete( pNtkAig );
return NULL;
}
return pNtkAig;
}
/**Function*************************************************************
Synopsis [Converts the network from the AIG manager into ABC.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Dar_Man_t * Abc_NtkToDar( Abc_Ntk_t * pNtk )
{
Dar_Man_t * pMan;
Abc_Obj_t * pObj;
int i;
// create the manager
pMan = Dar_ManStart( Abc_NtkNodeNum(pNtk) );
// transfer the pointers to the basic nodes
Abc_AigConst1(pNtk)->pCopy = (Abc_Obj_t *)Dar_ManConst1(pMan);
Abc_NtkForEachCi( pNtk, pObj, i )
pObj->pCopy = (Abc_Obj_t *)Dar_ObjCreatePi(pMan);
// perform the conversion of the internal nodes (assumes DFS ordering)
Abc_NtkForEachNode( pNtk, pObj, i )
pObj->pCopy = (Abc_Obj_t *)Dar_And( pMan, (Dar_Obj_t *)Abc_ObjChild0Copy(pObj), (Dar_Obj_t *)Abc_ObjChild1Copy(pObj) );
// create the POs
Abc_NtkForEachCo( pNtk, pObj, i )
Dar_ObjCreatePo( pMan, (Dar_Obj_t *)Abc_ObjChild0Copy(pObj) );
Dar_ManCleanup( pMan );
return pMan;
}
/**Function*************************************************************
Synopsis [Converts the network from the AIG manager into ABC.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkFromDar( Abc_Ntk_t * pNtk, Dar_Man_t * pMan )
{
Vec_Ptr_t * vNodes;
Abc_Ntk_t * pNtkNew;
Dar_Obj_t * pObj;
int i;
// perform strashing
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_STRASH, ABC_FUNC_AIG );
// transfer the pointers to the basic nodes
Dar_ManConst1(pMan)->pData = Abc_AigConst1(pNtkNew);
Dar_ManForEachPi( pMan, pObj, i )
pObj->pData = Abc_NtkCi(pNtkNew, i);
// rebuild the AIG
vNodes = Dar_ManDfs( pMan );
Vec_PtrForEachEntry( vNodes, pObj, i )
pObj->pData = Abc_AigAnd( pNtkNew->pManFunc, (Abc_Obj_t *)Dar_ObjChild0Copy(pObj), (Abc_Obj_t *)Dar_ObjChild1Copy(pObj) );
Vec_PtrFree( vNodes );
// connect the PO nodes
Dar_ManForEachPo( pMan, pObj, i )
Abc_ObjAddFanin( Abc_NtkCo(pNtkNew, i), (Abc_Obj_t *)Dar_ObjChild0Copy(pObj) );
if ( !Abc_NtkCheck( pNtkNew ) )
fprintf( stdout, "Abc_NtkFromDar(): Network check has failed.\n" );
return pNtkNew;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -992,6 +992,73 @@ If_Obj_t * Abc_LutIfManMap_New_rec( Lut_Man_t * p, Kit_DsdNtk_t * pNtk, int iLit
return If_NotCond( pObjNew, fCompl );
}
/**Function*************************************************************
Synopsis [Find the best cofactoring variable.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
/*
int Abc_LutFindBestCofactoring( Lut_Man_t * p, Kit_DsdNtk_t * pNtk, unsigned * pTruth, int nVars )
{
Kit_DsdNtk_t * pNtk0, * pNtk1, * pTemp;
// Kit_DsdObj_t * pRoot;
unsigned * pCofs2[2] = { pNtk->pMem, pNtk->pMem + Kit_TruthWordNum(pNtk->nVars) };
unsigned i, * pTruth;
int MaxBlock
Verbose = 0;
int RetValue = 0;
if ( fVerbose )
{
printf( "Function: " );
// Extra_PrintBinary( stdout, pTruth, (1 << nVars) );
Extra_PrintHexadecimal( stdout, pTruth, nVars );
printf( "\n" );
Kit_DsdPrint( stdout, pNtk );
}
for ( i = 0; i < nVars; i++ )
{
Kit_TruthCofactor0New( pCofs2[0], pTruth, nVars, i );
pNtk0 = Kit_DsdDecompose( pCofs2[0], nVars );
pNtk0 = Kit_DsdExpand( pTemp = pNtk0 );
Kit_DsdNtkFree( pTemp );
if ( fVerbose )
{
printf( "Cof%d0: ", i );
Kit_DsdPrint( stdout, pNtk0 );
}
Kit_TruthCofactor1New( pCofs2[1], pTruth, nVars, i );
pNtk1 = Kit_DsdDecompose( pCofs2[1], nVars );
pNtk1 = Kit_DsdExpand( pTemp = pNtk1 );
Kit_DsdNtkFree( pTemp );
if ( fVerbose )
{
printf( "Cof%d1: ", i );
Kit_DsdPrint( stdout, pNtk1 );
}
if ( Kit_DsdCheckVar4Dec2( pNtk0, pNtk1 ) )
RetValue = 1;
Kit_DsdNtkFree( pNtk0 );
Kit_DsdNtkFree( pNtk1 );
}
if ( fVerbose )
printf( "\n" );
return RetValue;
}
*/
/**Function*************************************************************
Synopsis [Prepares the mapping manager.]
@ -1220,6 +1287,7 @@ clk = clock();
pTruth = Abc_LutCutTruth( p, pCut );
p->timeTruth += clock() - clk;
/*
// evaluate the result of decomposition
Result = Kit_DsdEval( pTruth, pCut->nLeaves, 3 );
@ -1247,6 +1315,18 @@ p->timeEval += clock() - clk;
continue;
}
*/
/*
if ( pCut->nLeaves > 6 && pCut->nLeaves < 12 && Kit_DsdNonDsdSizeMax(pDsdNtk) == pCut->nLeaves )
{
// Abc_NtkPrintMeasures( pTruth, pCut->nLeaves );
// Kit_DsdTestCofs( pDsdNtk, pTruth );
// Abc_NtkPrintOneDecomp( pTruth, pCut->nLeaves );
Abc_NtkPrintOneDec( pTruth, pCut->nLeaves );
}
*/
if ( p->pPars->fVeryVerbose )
{
// Extra_PrintHexadecimal( stdout, pTruth, pCut->nLeaves ); printf( "\n" );

View File

@ -525,6 +525,8 @@ int Abc_NtkIvyProve( Abc_Ntk_t ** ppNtk, void * pPars )
if ( pParams->fUseRewriting && Abc_NtkNodeNum(pNtk) > 500 )
{
pParams->fUseRewriting = 0;
pNtk = Abc_NtkBalance( pNtkTemp = pNtk, 0, 0, 0 );
Abc_NtkDelete( pNtkTemp );
Abc_NtkRewrite( pNtk, 0, 0, 0, 0, 0 );
pNtk = Abc_NtkBalance( pNtkTemp = pNtk, 0, 0, 0 );
Abc_NtkDelete( pNtkTemp );

478
src/base/abci/abcMeasure.c Normal file
View File

@ -0,0 +1,478 @@
/**CFile****************************************************************
FileName [abc_.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abc_.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abc.h"
#include "kit.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkPrintMeasures( unsigned * pTruth, int nVars )
{
unsigned uCofs[10][32];
int i, k, nOnes;
// total pairs
nOnes = Kit_TruthCountOnes( uCofs[0], nVars );
printf( "Total = %d.\n", nOnes * ((1 << nVars) - nOnes) );
// print measures for individual variables
for ( i = 0; i < nVars; i++ )
{
Kit_TruthUniqueNew( uCofs[0], pTruth, nVars, i );
nOnes = Kit_TruthCountOnes( uCofs[0], nVars );
printf( "%7d ", nOnes );
}
printf( "\n" );
// consider pairs
for ( i = 0; i < nVars; i++ )
for ( k = 0; k < nVars; k++ )
{
if ( i == k )
{
printf( " " );
continue;
}
Kit_TruthCofactor0New( uCofs[0], pTruth, nVars, i );
Kit_TruthCofactor1New( uCofs[1], pTruth, nVars, i );
Kit_TruthCofactor0New( uCofs[2], uCofs[0], nVars, k ); // 00
Kit_TruthCofactor1New( uCofs[3], uCofs[0], nVars, k ); // 01
Kit_TruthCofactor0New( uCofs[4], uCofs[1], nVars, k ); // 10
Kit_TruthCofactor1New( uCofs[5], uCofs[1], nVars, k ); // 11
Kit_TruthAndPhase( uCofs[6], uCofs[2], uCofs[5], nVars, 0, 1 ); // 00 & 11'
Kit_TruthAndPhase( uCofs[7], uCofs[2], uCofs[5], nVars, 1, 0 ); // 00' & 11
Kit_TruthAndPhase( uCofs[8], uCofs[3], uCofs[4], nVars, 0, 1 ); // 01 & 10'
Kit_TruthAndPhase( uCofs[9], uCofs[3], uCofs[4], nVars, 1, 0 ); // 01' & 10
nOnes = Kit_TruthCountOnes( uCofs[6], nVars ) +
Kit_TruthCountOnes( uCofs[7], nVars ) +
Kit_TruthCountOnes( uCofs[8], nVars ) +
Kit_TruthCountOnes( uCofs[9], nVars );
printf( "%7d ", nOnes );
if ( k == nVars - 1 )
printf( "\n" );
}
printf( "\n" );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_Ntk4VarObjPrint_rec( Abc_Obj_t * pObj )
{
if ( pObj == Abc_AigConst1(pObj->pNtk) )
{
printf( "1" );
return;
}
if ( Abc_ObjIsPi(pObj) )
{
printf( "%c", pObj->Id - 1 + 'a' );
return;
}
printf( "(" );
Abc_Ntk4VarObjPrint_rec( Abc_ObjFanin0(pObj) );
if ( Abc_ObjFaninC0(pObj) )
printf( "\'" );
Abc_Ntk4VarObjPrint_rec( Abc_ObjFanin1(pObj) );
if ( Abc_ObjFaninC1(pObj) )
printf( "\'" );
printf( ")" );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
unsigned Abc_Ntk4VarObj( Vec_Ptr_t * vNodes )
{
Abc_Obj_t * pObj;
unsigned uTruth0, uTruth1;
int i;
Vec_PtrForEachEntry( vNodes, pObj, i )
{
uTruth0 = (unsigned)(Abc_ObjFanin0(pObj)->pCopy);
uTruth1 = (unsigned)(Abc_ObjFanin1(pObj)->pCopy);
if ( Abc_ObjFaninC0(pObj) )
uTruth0 = ~uTruth0;
if ( Abc_ObjFaninC1(pObj) )
uTruth1 = ~uTruth1;
pObj->pCopy = (void *)(uTruth0 & uTruth1);
}
return uTruth0 & uTruth1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_Ntk4VarTable( Abc_Ntk_t * pNtk )
{
static unsigned u4VarTruths[4] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00 };
static unsigned u4VarTts[222] = {
0x0000, 0x0001, 0x0003, 0x0006, 0x0007, 0x000f, 0x0016, 0x0017, 0x0018, 0x0019,
0x001b, 0x001e, 0x001f, 0x003c, 0x003d, 0x003f, 0x0069, 0x006b, 0x006f, 0x007e,
0x007f, 0x00ff, 0x0116, 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011e, 0x011f,
0x012c, 0x012d, 0x012f, 0x013c, 0x013d, 0x013e, 0x013f, 0x0168, 0x0169, 0x016a,
0x016b, 0x016e, 0x016f, 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0186,
0x0187, 0x0189, 0x018b, 0x018f, 0x0196, 0x0197, 0x0198, 0x0199, 0x019a, 0x019b,
0x019e, 0x019f, 0x01a8, 0x01a9, 0x01aa, 0x01ab, 0x01ac, 0x01ad, 0x01ae, 0x01af,
0x01bc, 0x01bd, 0x01be, 0x01bf, 0x01e8, 0x01e9, 0x01ea, 0x01eb, 0x01ee, 0x01ef,
0x01fe, 0x033c, 0x033d, 0x033f, 0x0356, 0x0357, 0x0358, 0x0359, 0x035a, 0x035b,
0x035e, 0x035f, 0x0368, 0x0369, 0x036a, 0x036b, 0x036c, 0x036d, 0x036e, 0x036f,
0x037c, 0x037d, 0x037e, 0x03c0, 0x03c1, 0x03c3, 0x03c5, 0x03c6, 0x03c7, 0x03cf,
0x03d4, 0x03d5, 0x03d6, 0x03d7, 0x03d8, 0x03d9, 0x03db, 0x03dc, 0x03dd, 0x03de,
0x03fc, 0x0660, 0x0661, 0x0662, 0x0663, 0x0666, 0x0667, 0x0669, 0x066b, 0x066f,
0x0672, 0x0673, 0x0676, 0x0678, 0x0679, 0x067a, 0x067b, 0x067e, 0x0690, 0x0691,
0x0693, 0x0696, 0x0697, 0x069f, 0x06b0, 0x06b1, 0x06b2, 0x06b3, 0x06b4, 0x06b5,
0x06b6, 0x06b7, 0x06b9, 0x06bd, 0x06f0, 0x06f1, 0x06f2, 0x06f6, 0x06f9, 0x0776,
0x0778, 0x0779, 0x077a, 0x077e, 0x07b0, 0x07b1, 0x07b4, 0x07b5, 0x07b6, 0x07bc,
0x07e0, 0x07e1, 0x07e2, 0x07e3, 0x07e6, 0x07e9, 0x07f0, 0x07f1, 0x07f2, 0x07f8,
0x0ff0, 0x1668, 0x1669, 0x166a, 0x166b, 0x166e, 0x167e, 0x1681, 0x1683, 0x1686,
0x1687, 0x1689, 0x168b, 0x168e, 0x1696, 0x1697, 0x1698, 0x1699, 0x169a, 0x169b,
0x169e, 0x16a9, 0x16ac, 0x16ad, 0x16bc, 0x16e9, 0x177e, 0x178e, 0x1796, 0x1798,
0x179a, 0x17ac, 0x17e8, 0x18e7, 0x19e1, 0x19e3, 0x19e6, 0x1bd8, 0x1be4, 0x1ee1,
0x3cc3, 0x6996
};
int Counters[222] = {0};
Vec_Ptr_t * vNodes;
Abc_Obj_t * pObj;
unsigned uTruth;
int i, k, Count = 0;
unsigned short * puCanons = NULL;
unsigned char * puMap = NULL;
Extra_Truth4VarNPN( &puCanons, NULL, NULL, &puMap );
// set elementary truth tables
assert( Abc_NtkPiNum(pNtk) == 4 );
Abc_AigConst1(pNtk)->pCopy = (void *)0xFFFFFFFF;
Abc_NtkForEachPi( pNtk, pObj, i )
pObj->pCopy = (void *)u4VarTruths[i];
// create truth tables
Abc_NtkForEachPo( pNtk, pObj, i )
{
vNodes = Abc_NtkDfsNodes( pNtk, &pObj, 1 );
if ( Vec_PtrSize(vNodes) == 0 )
uTruth = (unsigned)Abc_ObjFanin0(pObj)->pCopy;
else
uTruth = Abc_Ntk4VarObj( vNodes );
if ( (uTruth & 0xFFFF) < (~uTruth & 0xFFFF) )
uTruth = uTruth & 0xFFFF;
else
uTruth = ~uTruth & 0xFFFF;
for ( k = 0; k < 222; k++ )
if ( u4VarTts[k] == uTruth )
break;
if ( k == 222 )
continue;
/*
// if ( uTruth == 1725 )
if ( k == 96 )
{
printf( "%d : ", Vec_PtrSize(vNodes) );
Abc_Ntk4VarObjPrint_rec( Abc_ObjFanin0(pObj) );
printf( "\n" );
}
*/
Counters[k]++;
// Counters[ puMap[uTruth & 0xFFFF] ]++;
Vec_PtrFree( vNodes );
}
free( puCanons );
free( puMap );
Count = 0;
for ( k = 0; k < 222; k++ )
{
printf( "%d/%x/%d ", k, u4VarTts[k], Counters[k] );
Count += Counters[k];
}
printf( " Total = %d\n", Count );
}
/**Function*************************************************************
Synopsis [Returns 1 if there are no more than 2 unique cofactors.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkPrintOneDecompCheckCofList( unsigned * uCofs, int nCofs )
{
int i, Ind = -1;
assert( nCofs > 2 );
for ( i = 1; i < nCofs; i++ )
{
if ( uCofs[i] == uCofs[0] )
continue;
if ( Ind == -1 )
{
Ind = i;
continue;
}
if ( uCofs[i] == uCofs[Ind] )
continue;
return 0;
}
return 1;
}
/**Function*************************************************************
Synopsis [Checks all cofactors with the given mask.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkPrintOneDecompCheck( unsigned * uCofs, int nCofs, unsigned uMask )
{
unsigned pCofs[32][32];
int nCofNums[32] = {0};
int uMasks[32];
int nGroups = 0;
int i, k;
for ( i = 0; i < nCofs; i++ )
{
// find group of this cof
for ( k = 0; k < nGroups; k++ )
if ( (int)(i & uMask) == uMasks[k] )
break;
if ( k == nGroups )
{
uMasks[k] = (i & uMask);
nGroups++;
}
// save cof in the group
pCofs[k][ nCofNums[k]++ ] = uCofs[i];
assert( nCofNums[k] <= 32 );
assert( nGroups <= 32 );
}
// check the groups
for ( i = 0; i < nGroups; i++ )
if ( !Abc_NtkPrintOneDecompCheckCofList(pCofs[i], nCofNums[i]) )
return 0;
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkPrintOneDecomp_rec( unsigned * uCofs, int nCofs, int nVars, unsigned uMask, int * pBestSize, unsigned * puBestMask )
{
unsigned uMaskNew;
int v, last, Counter = 0;
// find the last variable in the mask
for ( v = 0; v < nVars; v++ )
if ( uMask & (1<<v) )
{
last = v;
Counter++;
}
if ( Counter > 3 )
return;
// try adding one variable after the last
for ( v = last + 1; v < nVars; v++ )
{
uMaskNew = uMask | (1 << v);
if ( !Abc_NtkPrintOneDecompCheck( uCofs, nCofs, uMaskNew ) )
continue;
if ( *pBestSize < Counter + 1 )
{
*pBestSize = Counter + 1;
*puBestMask = uMaskNew;
}
// try other masks
Abc_NtkPrintOneDecomp_rec( uCofs, nCofs, nVars, uMaskNew, pBestSize, puBestMask );
}
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkPrintOneDecomp( unsigned * pTruth, int nVars )
{
int BoundSet = 6;
unsigned uCofs[64], uMask, uBestMask = 0;
int i, nCofs, nMints, nMintShift, BestSize = 1;
assert( nVars > BoundSet );
assert( nVars <= BoundSet + 5 ); // at most 5 variable cofactors
// collect the cofactors
nCofs = (1 << BoundSet);
nMints = (1 << (nVars-BoundSet));
nMintShift = 0;
uMask = Kit_CubeMask( nMints );
for ( i = 0; i < nCofs; i++ )
{
uCofs[i] = (pTruth[nMintShift/32] >> (nMintShift % 32)) & uMask;
nMintShift += nMints;
}
// try removing variables
for ( i = 0; i < BoundSet; i++ )
Abc_NtkPrintOneDecomp_rec( uCofs, nCofs, nVars, (1 << i), &BestSize, &uBestMask );
printf( "Best size = %d ", BestSize );
printf( "Best mask = " );
Extra_PrintBinary( stdout, &uBestMask, nVars );
printf( "\n" );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkPrintOneDec( unsigned * pTruth, int nVars )
{
unsigned uCof[(1<<11)], * pOut = uCof, * pIn = pTruth, * pTemp;
int nDiffs[16];
int Order[16];
int i, fChange, Temp, Counter;
// find the ordering
for ( i = 0; i < nVars; i++ )
{
Kit_TruthUniqueNew( uCof, pTruth, nVars, i );
nDiffs[i] = Kit_TruthCountOnes( uCof, nVars );
Order[i] = i;
}
// permute truth table to least active variable first
Counter = 0;
do {
fChange = 0;
for ( i = 0; i < nVars-1; i++ )
{
if ( nDiffs[i] <= nDiffs[i+1] )
continue;
fChange = 1;
Counter++;
Temp = nDiffs[i];
nDiffs[i] = nDiffs[i+1];
nDiffs[i+1] = Temp;
Temp = Order[i];
Order[i] = Order[i+1];
Order[i+1] = Temp;
Extra_TruthSwapAdjacentVars( pOut, pIn, nVars, i );
pTemp = pIn; pIn = pOut; pOut = pTemp;
}
} while ( fChange );
// swap if it was moved an even number of times
if ( Counter & 1 )
Extra_TruthCopy( pOut, pIn, nVars );
// call the decomposition
Abc_NtkPrintOneDecomp( pTruth, nVars );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -74,9 +74,9 @@ Vec_Ptr_t * Abc_NtkPartitionCollectSupps( Abc_Ntk_t * pNtk )
SeeAlso []
***********************************************************************/
int Abc_NtkPartitionSmartFindPart( Vec_Ptr_t * vPartSuppsAll, Vec_Int_t * vOne )
int Abc_NtkPartitionSmartFindPart( Vec_Ptr_t * vPartSuppsAll, Vec_Ptr_t * vPartsAll, int nPartSizeLimit, Vec_Int_t * vOne )
{
Vec_Int_t * vPartSupp;
Vec_Int_t * vPartSupp, * vPart;
double Attract, Repulse, Cost, CostBest;
int i, nCommon, iBest;
iBest = -1;
@ -84,6 +84,11 @@ int Abc_NtkPartitionSmartFindPart( Vec_Ptr_t * vPartSuppsAll, Vec_Int_t * vOne )
Vec_PtrForEachEntry( vPartSuppsAll, vPartSupp, i )
{
nCommon = Vec_IntTwoCountCommon( vPartSupp, vOne );
if ( nCommon == 0 )
continue;
vPart = Vec_PtrEntry( vPartsAll, i );
if ( nPartSizeLimit > 0 && Vec_IntSize(vPart) > nPartSizeLimit )
continue;
if ( nCommon == Vec_IntSize(vOne) )
return i;
Attract = 1.0 * nCommon / Vec_IntSize(vOne);
@ -143,17 +148,20 @@ void Abc_NtkPartitionPrint( Abc_Ntk_t * pNtk, Vec_Ptr_t * vPartsAll, Vec_Ptr_t *
SeeAlso []
***********************************************************************/
void Abc_NtkPartitionCompact( Vec_Ptr_t * vPartsAll, Vec_Ptr_t * vPartSuppsAll )
void Abc_NtkPartitionCompact( Vec_Ptr_t * vPartsAll, Vec_Ptr_t * vPartSuppsAll, int nPartSizeLimit )
{
Vec_Int_t * vOne, * vPart, * vPartSupp, * vTemp;
int i, iPart;
if ( nPartSizeLimit == 0 )
nPartSizeLimit = 200;
// pack smaller partitions into larger blocks
iPart = 0;
vPart = vPartSupp = NULL;
Vec_PtrForEachEntry( vPartSuppsAll, vOne, i )
{
if ( Vec_IntSize(vOne) < 200 )
if ( Vec_IntSize(vOne) < nPartSizeLimit )
{
if ( vPartSupp == NULL )
{
@ -169,7 +177,7 @@ void Abc_NtkPartitionCompact( Vec_Ptr_t * vPartsAll, Vec_Ptr_t * vPartSuppsAll )
Vec_IntFree( vTemp );
Vec_IntFree( Vec_PtrEntry(vPartsAll, i) );
}
if ( Vec_IntSize(vPartSupp) < 200 )
if ( Vec_IntSize(vPartSupp) < nPartSizeLimit )
continue;
}
else
@ -212,7 +220,7 @@ void Abc_NtkPartitionCompact( Vec_Ptr_t * vPartsAll, Vec_Ptr_t * vPartSuppsAll )
SeeAlso []
***********************************************************************/
Vec_Vec_t * Abc_NtkPartitionSmart( Abc_Ntk_t * pNtk, int fVerbose )
Vec_Vec_t * Abc_NtkPartitionSmart( Abc_Ntk_t * pNtk, int nPartSizeLimit, int fVerbose )
{
Vec_Ptr_t * vSupps, * vPartsAll, * vPartsAll2, * vPartSuppsAll, * vPartPtr;
Vec_Int_t * vOne, * vPart, * vPartSupp, * vTemp;
@ -235,7 +243,7 @@ clk = clock();
// get the output number
iOut = Vec_IntPop(vOne);
// find closely matching part
iPart = Abc_NtkPartitionSmartFindPart( vPartSuppsAll, vOne );
iPart = Abc_NtkPartitionSmartFindPart( vPartSuppsAll, vPartsAll, nPartSizeLimit, vOne );
if ( iPart == -1 )
{
// create new partition
@ -280,7 +288,7 @@ clk = clock();
// compact small partitions
// Abc_NtkPartitionPrint( pNtk, vPartsAll, vPartSuppsAll );
Abc_NtkPartitionCompact( vPartsAll, vPartSuppsAll );
Abc_NtkPartitionCompact( vPartsAll, vPartSuppsAll, nPartSizeLimit );
if ( fVerbose )
Abc_NtkPartitionPrint( pNtk, vPartsAll, vPartSuppsAll );
if ( fVerbose )
@ -668,7 +676,7 @@ Abc_Ntk_t * Abc_NtkFraigPartitioned( Abc_Ntk_t * pNtk, void * pParams )
// perform partitioning
assert( Abc_NtkIsStrash(pNtk) );
// vParts = Abc_NtkPartitionNaive( pNtk, 20 );
vParts = Abc_NtkPartitionSmart( pNtk, 0 );
vParts = Abc_NtkPartitionSmart( pNtk, 0, 0 );
Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "unset progressbar" );

View File

@ -26,7 +26,7 @@
////////////////////////////////////////////////////////////////////////
static void Abc_NtkFraigSweepUsingExdc( Fraig_Man_t * pMan, Abc_Ntk_t * pNtk );
static stmm_table * Abc_NtkFraigEquiv( Abc_Ntk_t * pNtk, int fUseInv, bool fVerbose );
static stmm_table * Abc_NtkFraigEquiv( Abc_Ntk_t * pNtk, int fUseInv, int fVerbose, int fVeryVerbose );
static void Abc_NtkFraigTransform( Abc_Ntk_t * pNtk, stmm_table * tEquiv, int fUseInv, bool fVerbose );
static void Abc_NtkFraigMergeClassMapped( Abc_Ntk_t * pNtk, Abc_Obj_t * pChain, int fUseInv, int fVerbose );
static void Abc_NtkFraigMergeClass( Abc_Ntk_t * pNtk, Abc_Obj_t * pChain, int fUseInv, int fVerbose );
@ -54,7 +54,7 @@ static void Abc_NodeComplementInput( Abc_Obj_t * pNode, Abc_Obj_t * pF
SeeAlso []
***********************************************************************/
bool Abc_NtkFraigSweep( Abc_Ntk_t * pNtk, int fUseInv, int fExdc, int fVerbose )
bool Abc_NtkFraigSweep( Abc_Ntk_t * pNtk, int fUseInv, int fExdc, int fVerbose, int fVeryVerbose )
{
Fraig_Params_t Params;
Abc_Ntk_t * pNtkAig;
@ -100,9 +100,11 @@ bool Abc_NtkFraigSweep( Abc_Ntk_t * pNtk, int fUseInv, int fExdc, int fVerbose )
else
Abc_NtkFraigSweepUsingExdc( pMan, pNtk );
}
// assign levels to the nodes of the network
Abc_NtkLevel( pNtk );
// collect the classes of equivalent nets
tEquiv = Abc_NtkFraigEquiv( pNtk, fUseInv, fVerbose );
tEquiv = Abc_NtkFraigEquiv( pNtk, fUseInv, fVerbose, fVeryVerbose );
// transform the network into the equivalent one
Abc_NtkFraigTransform( pNtk, tEquiv, fUseInv, fVerbose );
@ -113,7 +115,11 @@ bool Abc_NtkFraigSweep( Abc_Ntk_t * pNtk, int fUseInv, int fExdc, int fVerbose )
Abc_NtkDelete( pNtkAig );
// cleanup the dangling nodes
Abc_NtkCleanup( pNtk, fVerbose );
if ( Abc_NtkHasMapping(pNtk) )
Abc_NtkCleanup( pNtk, fVerbose );
else
Abc_NtkSweep( pNtk, fVerbose );
// check
if ( !Abc_NtkCheck( pNtk ) )
{
@ -175,7 +181,7 @@ void Abc_NtkFraigSweepUsingExdc( Fraig_Man_t * pMan, Abc_Ntk_t * pNtk )
SeeAlso []
***********************************************************************/
stmm_table * Abc_NtkFraigEquiv( Abc_Ntk_t * pNtk, int fUseInv, bool fVerbose )
stmm_table * Abc_NtkFraigEquiv( Abc_Ntk_t * pNtk, int fUseInv, int fVerbose, int fVeryVerbose )
{
Abc_Obj_t * pList, * pNode, * pNodeAig;
Fraig_Node_t * gNode;
@ -225,22 +231,22 @@ stmm_table * Abc_NtkFraigEquiv( Abc_Ntk_t * pNtk, int fUseInv, bool fVerbose )
// count nodes in the non-trival classes
for ( pNode = pList; pNode; pNode = pNode->pNext )
Counter++;
/*
if ( fVerbose )
if ( fVeryVerbose )
{
printf( "Class %2d : {", c );
for ( pNode = pList; pNode; pNode = pNode->pNext )
{
pNode->pCopy = NULL;
printf( " %s", Abc_ObjName(pNode) );
if ( pNode->fPhase ) printf( "(*)" );
printf( "(%c)", pNode->fPhase? '-' : '+' );
printf( "(%d)", pNode->Level );
}
printf( " }\n" );
c++;
}
*/
}
if ( fVerbose )
if ( fVerbose || fVeryVerbose )
{
printf( "Sweeping stats for network \"%s\":\n", pNtk->pName );
printf( "Internal nodes = %d. Different functions (up to compl) = %d.\n", Abc_NtkNodeNum(pNtk), stmm_count(tStrash2Net) );
@ -268,8 +274,6 @@ void Abc_NtkFraigTransform( Abc_Ntk_t * pNtk, stmm_table * tEquiv, int fUseInv,
Abc_Obj_t * pList;
if ( stmm_count(tEquiv) == 0 )
return;
// assign levels to the nodes of the network
Abc_NtkLevel( pNtk );
// merge nodes in the classes
if ( Abc_NtkHasMapping( pNtk ) )
{

View File

@ -311,6 +311,123 @@ void Abc_NtkCecFraigPart( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, in
Abc_NtkDelete( pMiter );
}
/**Function*************************************************************
Synopsis [Verifies sequential equivalence by fraiging followed by SAT.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkCecFraigPartAuto( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fVerbose )
{
extern int Abc_NtkCombinePos( Abc_Ntk_t * pNtk, int fAnd );
extern Vec_Vec_t * Abc_NtkPartitionSmart( Abc_Ntk_t * pNtk, int nPartSizeLimit, int fVerbose );
extern int Cmd_CommandExecute( void * pAbc, char * sCommand );
extern void * Abc_FrameGetGlobalFrame();
Vec_Vec_t * vParts;
Vec_Ptr_t * vOne;
Prove_Params_t Params, * pParams = &Params;
Abc_Ntk_t * pMiter, * pMiterPart;
int i, RetValue, Status, nOutputs;
// solve the CNF using the SAT solver
Prove_ParamsSetDefault( pParams );
pParams->nItersMax = 5;
// pParams->fVerbose = 1;
// get the miter of the two networks
pMiter = Abc_NtkMiter( pNtk1, pNtk2, 1, 1 );
if ( pMiter == NULL )
{
printf( "Miter computation has failed.\n" );
return;
}
RetValue = Abc_NtkMiterIsConstant( pMiter );
if ( RetValue == 0 )
{
printf( "Networks are NOT EQUIVALENT after structural hashing.\n" );
// report the error
pMiter->pModel = Abc_NtkVerifyGetCleanModel( pMiter, 1 );
Abc_NtkVerifyReportError( pNtk1, pNtk2, pMiter->pModel );
FREE( pMiter->pModel );
Abc_NtkDelete( pMiter );
return;
}
if ( RetValue == 1 )
{
printf( "Networks are equivalent after structural hashing.\n" );
Abc_NtkDelete( pMiter );
return;
}
Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "unset progressbar" );
// partition the outputs
vParts = Abc_NtkPartitionSmart( pMiter, 50, 0 );
// fraig each partition
Status = 1;
nOutputs = 0;
Vec_VecForEachLevel( vParts, vOne, i )
{
// get this part of the miter
pMiterPart = Abc_NtkCreateConeArray( pMiter, vOne, 0 );
Abc_NtkCombinePos( pMiterPart, 0 );
// check the miter for being constant
RetValue = Abc_NtkMiterIsConstant( pMiterPart );
if ( RetValue == 0 )
{
printf( "Networks are NOT EQUIVALENT after partitioning.\n" );
Abc_NtkDelete( pMiterPart );
break;
}
if ( RetValue == 1 )
{
Abc_NtkDelete( pMiterPart );
continue;
}
// solve the problem
RetValue = Abc_NtkIvyProve( &pMiterPart, pParams );
if ( RetValue == -1 )
{
printf( "Networks are undecided (resource limits is reached).\r" );
Status = -1;
}
else if ( RetValue == 0 )
{
int * pSimInfo = Abc_NtkVerifySimulatePattern( pMiterPart, pMiterPart->pModel );
if ( pSimInfo[0] != 1 )
printf( "ERROR in Abc_NtkMiterProve(): Generated counter-example is invalid.\n" );
else
printf( "Networks are NOT EQUIVALENT. \n" );
free( pSimInfo );
Status = 0;
Abc_NtkDelete( pMiterPart );
break;
}
else
{
printf( "Finished part %d (out of %d)\r", i+1, Vec_VecSize(vParts) );
nOutputs += Vec_PtrSize(vOne);
}
Abc_NtkDelete( pMiterPart );
}
Vec_VecFree( vParts );
Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "set progressbar" );
if ( Status == 1 )
printf( "Networks are equivalent. \n" );
else if ( Status == -1 )
printf( "Timed out after verifying %d outputs (out of %d).\n", nOutputs, Abc_NtkCoNum(pNtk1) );
Abc_NtkDelete( pMiter );
}
/**Function*************************************************************
Synopsis [Verifies sequential equivalence by brute-force SAT.]

View File

@ -7,6 +7,7 @@ SRC += src/base/abci/abc.c \
src/base/abci/abcClpBdd.c \
src/base/abci/abcClpSop.c \
src/base/abci/abcCut.c \
src/base/abci/abcDar.c \
src/base/abci/abcDebug.c \
src/base/abci/abcDress.c \
src/base/abci/abcDsd.c \

155
src/base/abci/xaaaa.c Normal file
View File

@ -0,0 +1,155 @@
/**CFile****************************************************************
FileName [abc_.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abc_.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abc.h"
#include "kit.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkPrintMeasures( unsigned * pTruth, int nVars )
{
unsigned uCofs[10][32];
int i, k, nOnes;
// total pairs
nOnes = Kit_TruthCountOnes( uCofs[0], nVars );
printf( "Total = %d.\n", nOnes * ((1 << nVars) - nOnes) );
// print measures for individual variables
for ( i = 0; i < nVars; i++ )
{
Kit_TruthUniqueNew( uCofs[0], pTruth, nVars, i );
nOnes = Kit_TruthCountOnes( uCofs[0], nVars );
printf( "%7d ", nOnes );
}
printf( "\n" );
// consider pairs
for ( i = 0; i < nVars; i++ )
for ( k = 0; k < nVars; k++ )
{
if ( i == k )
{
printf( " " );
continue;
}
Kit_TruthCofactor0New( uCofs[0], pTruth, nVars, i );
Kit_TruthCofactor1New( uCofs[1], pTruth, nVars, i );
Kit_TruthCofactor0New( uCofs[2], uCofs[0], nVars, k ); // 00
Kit_TruthCofactor1New( uCofs[3], uCofs[0], nVars, k ); // 01
Kit_TruthCofactor0New( uCofs[4], uCofs[1], nVars, k ); // 10
Kit_TruthCofactor1New( uCofs[5], uCofs[1], nVars, k ); // 11
Kit_TruthAndPhase( uCofs[6], uCofs[2], uCofs[5], nVars, 0, 1 ); // 00 & 11'
Kit_TruthAndPhase( uCofs[7], uCofs[2], uCofs[5], nVars, 1, 0 ); // 00' & 11
Kit_TruthAndPhase( uCofs[8], uCofs[3], uCofs[4], nVars, 0, 1 ); // 01 & 10'
Kit_TruthAndPhase( uCofs[9], uCofs[3], uCofs[4], nVars, 1, 0 ); // 01' & 10
nOnes = Kit_TruthCountOnes( uCofs[6], nVars ) +
Kit_TruthCountOnes( uCofs[7], nVars ) +
Kit_TruthCountOnes( uCofs[8], nVars ) +
Kit_TruthCountOnes( uCofs[9], nVars );
printf( "%7d ", nOnes );
if ( k == nVars - 1 )
printf( "\n" );
}
printf( "\n" );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_Ntk4VarTable( Abc_Ntk_t * pNtk )
{
static u4VarTts[222] = {
0x0000, 0x0001, 0x0003, 0x0006, 0x0007, 0x000f, 0x0016, 0x0017, 0x0018, 0x0019,
0x001b, 0x001e, 0x001f, 0x003c, 0x003d, 0x003f, 0x0069, 0x006b, 0x006f, 0x007e,
0x007f, 0x00ff, 0x0116, 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011e, 0x011f,
0x012c, 0x012d, 0x012f, 0x013c, 0x013d, 0x013e, 0x013f, 0x0168, 0x0169, 0x016a,
0x016b, 0x016e, 0x016f, 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0186,
0x0187, 0x0189, 0x018b, 0x018f, 0x0196, 0x0197, 0x0198, 0x0199, 0x019a, 0x019b,
0x019e, 0x019f, 0x01a8, 0x01a9, 0x01aa, 0x01ab, 0x01ac, 0x01ad, 0x01ae, 0x01af,
0x01bc, 0x01bd, 0x01be, 0x01bf, 0x01e8, 0x01e9, 0x01ea, 0x01eb, 0x01ee, 0x01ef,
0x01fe, 0x033c, 0x033d, 0x033f, 0x0356, 0x0357, 0x0358, 0x0359, 0x035a, 0x035b,
0x035e, 0x035f, 0x0368, 0x0369, 0x036a, 0x036b, 0x036c, 0x036d, 0x036e, 0x036f,
0x037c, 0x037d, 0x037e, 0x03c0, 0x03c1, 0x03c3, 0x03c5, 0x03c6, 0x03c7, 0x03cf,
0x03d4, 0x03d5, 0x03d6, 0x03d7, 0x03d8, 0x03d9, 0x03db, 0x03dc, 0x03dd, 0x03de,
0x03fc, 0x0660, 0x0661, 0x0662, 0x0663, 0x0666, 0x0667, 0x0669, 0x066b, 0x066f,
0x0672, 0x0673, 0x0676, 0x0678, 0x0679, 0x067a, 0x067b, 0x067e, 0x0690, 0x0691,
0x0693, 0x0696, 0x0697, 0x069f, 0x06b0, 0x06b1, 0x06b2, 0x06b3, 0x06b4, 0x06b5,
0x06b6, 0x06b7, 0x06b9, 0x06bd, 0x06f0, 0x06f1, 0x06f2, 0x06f6, 0x06f9, 0x0776,
0x0778, 0x0779, 0x077a, 0x077e, 0x07b0, 0x07b1, 0x07b4, 0x07b5, 0x07b6, 0x07bc,
0x07e0, 0x07e1, 0x07e2, 0x07e3, 0x07e6, 0x07e9, 0x07f0, 0x07f1, 0x07f2, 0x07f8,
0x0ff0, 0x1668, 0x1669, 0x166a, 0x166b, 0x166e, 0x167e, 0x1681, 0x1683, 0x1686,
0x1687, 0x1689, 0x168b, 0x168e, 0x1696, 0x1697, 0x1698, 0x1699, 0x169a, 0x169b,
0x169e, 0x16a9, 0x16ac, 0x16ad, 0x16bc, 0x16e9, 0x177e, 0x178e, 0x1796, 0x1798,
0x179a, 0x17ac, 0x17e8, 0x18e7, 0x19e1, 0x19e3, 0x19e6, 0x1bd8, 0x1be4, 0x1ee1,
0x3cc3, 0x6996
};
int Counters[222];
Vec_Ptr_t * vNodes;
Abc_Obj_t * pObj;
int i;
// set elementary truth tables
Abc_NtkForEachPi( pNtk, pObj, i )
pObj
Abc_NtkForEachPo( pNtk, pObj, i )
{
vNodes = Abc_NtkDfsNodes( pNtk, &pObj, i );
Vec_PtrFree( vNodes );
}
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -25,7 +25,7 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static unsigned Io_ReadAigerDecode( char ** ppPos );
unsigned Io_ReadAigerDecode( char ** ppPos );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///

View File

@ -129,7 +129,7 @@ static unsigned Io_ObjMakeLit( int Var, int fCompl ) { return (V
static unsigned Io_ObjAigerNum( Abc_Obj_t * pObj ) { return (unsigned)pObj->pCopy; }
static void Io_ObjSetAigerNum( Abc_Obj_t * pObj, unsigned Num ) { pObj->pCopy = (void *)Num; }
static int Io_WriteAigerEncode( char * pBuffer, int Pos, unsigned x );
int Io_WriteAigerEncode( char * pBuffer, int Pos, unsigned x );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///

View File

@ -213,17 +213,33 @@ void Io_WriteVerilogPis( FILE * pFile, Abc_Ntk_t * pNtk, int Start )
***********************************************************************/
void Io_WriteVerilogPos( FILE * pFile, Abc_Ntk_t * pNtk, int Start )
{
Abc_Obj_t * pTerm, * pNet;
Abc_Obj_t * pTerm, * pNet, * pSkip;
int LineLength;
int AddedLength;
int NameCounter;
int i;
int nskip;
pSkip = 0;
nskip = 0;
LineLength = Start;
NameCounter = 0;
Abc_NtkForEachPo( pNtk, pTerm, i )
{
pNet = Abc_ObjFanin0(pTerm);
if ( Abc_ObjIsPi(Abc_ObjFanin0(pNet)) )
{
// Skip this output since it is a feedthrough -- the same
// name will appear as an input and an output which other
// tools reading verilog do not like.
nskip++;
pSkip = pNet; // save an example of skipped net
continue;
}
// get the line length after this name is written
AddedLength = strlen(Io_WriteVerilogGetName(Abc_ObjName(pNet))) + 2;
if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
@ -237,6 +253,14 @@ void Io_WriteVerilogPos( FILE * pFile, Abc_Ntk_t * pNtk, int Start )
LineLength += AddedLength;
NameCounter++;
}
if (nskip != 0)
{
assert (pSkip);
printf( "Io_WriteVerilogPos(): Omitted %d feedthrough nets from output list of module (e.g. %s).\n", nskip, Abc_ObjName(pSkip) );
return;
}
}
/**Function*************************************************************

View File

@ -18,8 +18,8 @@
***********************************************************************/
#ifndef __Abc_INT_H__
#define __Abc_INT_H__
#ifndef __MAIN_INT_H__
#define __MAIN_INT_H__
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///

View File

@ -196,7 +196,7 @@ static inline Vec_Ptr_t * Vec_PtrAllocTruthTables( int nVars )
p = Vec_PtrAllocSimInfo( nVars, nWords );
for ( i = 0; i < nVars; i++ )
{
pTruth = p->pArray[i];
pTruth = (unsigned *)p->pArray[i];
if ( i < 5 )
{
for ( k = 0; k < nWords; k++ )

View File

@ -477,6 +477,7 @@ extern void Kit_TruthExistSet( unsigned * pRes, unsigned * pTruth, in
extern void Kit_TruthForall( unsigned * pTruth, int nVars, int iVar );
extern void Kit_TruthForallNew( unsigned * pRes, unsigned * pTruth, int nVars, int iVar );
extern void Kit_TruthForallSet( unsigned * pRes, unsigned * pTruth, int nVars, unsigned uMask );
extern void Kit_TruthUniqueNew( unsigned * pRes, unsigned * pTruth, int nVars, int iVar );
extern void Kit_TruthMux( unsigned * pOut, unsigned * pCof0, unsigned * pCof1, int nVars, int iVar );
extern void Kit_TruthChangePhase( unsigned * pTruth, int nVars, int iVar );
extern int Kit_TruthMinCofSuppOverlap( unsigned * pTruth, int nVars, int * pVarMin );

View File

@ -1068,7 +1068,7 @@ int Kit_DsdTestCofs( Kit_DsdNtk_t * pNtk, unsigned * pTruthInit )
// Kit_DsdObj_t * pRoot;
unsigned * pCofs2[2] = { pNtk->pMem, pNtk->pMem + Kit_TruthWordNum(pNtk->nVars) };
unsigned i, * pTruth;
int fVerbose = 0;
int fVerbose = 1;
int RetValue = 0;
pTruth = pTruthInit;
@ -1108,8 +1108,8 @@ int Kit_DsdTestCofs( Kit_DsdNtk_t * pNtk, unsigned * pTruthInit )
Kit_DsdPrint( stdout, pNtk1 );
}
if ( Kit_DsdCheckVar4Dec2( pNtk0, pNtk1 ) )
RetValue = 1;
// if ( Kit_DsdCheckVar4Dec2( pNtk0, pNtk1 ) )
// RetValue = 1;
Kit_DsdNtkFree( pNtk0 );
Kit_DsdNtkFree( pNtk1 );

View File

@ -767,6 +767,61 @@ void Kit_TruthForallNew( unsigned * pRes, unsigned * pTruth, int nVars, int iVar
}
}
/**Function*************************************************************
Synopsis [Universally quantifies the variable.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Kit_TruthUniqueNew( unsigned * pRes, unsigned * pTruth, int nVars, int iVar )
{
int nWords = Kit_TruthWordNum( nVars );
int i, k, Step;
assert( iVar < nVars );
switch ( iVar )
{
case 0:
for ( i = 0; i < nWords; i++ )
pRes[i] = pTruth[i] ^ (((pTruth[i] & 0xAAAAAAAA) >> 1) | ((pTruth[i] & 0x55555555) << 1));
return;
case 1:
for ( i = 0; i < nWords; i++ )
pRes[i] = pTruth[i] ^ (((pTruth[i] & 0xCCCCCCCC) >> 2) | ((pTruth[i] & 0x33333333) << 2));
return;
case 2:
for ( i = 0; i < nWords; i++ )
pRes[i] = pTruth[i] ^ (((pTruth[i] & 0xF0F0F0F0) >> 4) | ((pTruth[i] & 0x0F0F0F0F) << 4));
return;
case 3:
for ( i = 0; i < nWords; i++ )
pRes[i] = pTruth[i] ^ (((pTruth[i] & 0xFF00FF00) >> 8) | ((pTruth[i] & 0x00FF00FF) << 8));
return;
case 4:
for ( i = 0; i < nWords; i++ )
pRes[i] = pTruth[i] ^ (((pTruth[i] & 0xFFFF0000) >> 16) | ((pTruth[i] & 0x0000FFFF) << 16));
return;
default:
Step = (1 << (iVar - 5));
for ( k = 0; k < nWords; k += 2*Step )
{
for ( i = 0; i < Step; i++ )
{
pRes[i] = pTruth[i] ^ pTruth[Step+i];
pRes[Step+i] = pRes[i];
}
pRes += 2*Step;
pTruth += 2*Step;
}
return;
}
}
/**Function*************************************************************
Synopsis [Universally quantifies the set of variables.]