mirror of https://github.com/YosysHQ/abc.git
Version abc70428
This commit is contained in:
parent
c09d4d499c
commit
feb8fb692e
72
abc.dsp
72
abc.dsp
|
|
@ -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
1
abc.rc
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -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 >= 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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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++;
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -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" );
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -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" );
|
||||
|
||||
|
|
|
|||
|
|
@ -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 ) )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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.]
|
||||
|
|
|
|||
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -25,7 +25,7 @@
|
|||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static unsigned Io_ReadAigerDecode( char ** ppPos );
|
||||
unsigned Io_ReadAigerDecode( char ** ppPos );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
|
|
|
|||
|
|
@ -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 ///
|
||||
|
|
|
|||
|
|
@ -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*************************************************************
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@
|
|||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __Abc_INT_H__
|
||||
#define __Abc_INT_H__
|
||||
#ifndef __MAIN_INT_H__
|
||||
#define __MAIN_INT_H__
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
|
|
|
|||
|
|
@ -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++ )
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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.]
|
||||
|
|
|
|||
Loading…
Reference in New Issue