mirror of https://github.com/YosysHQ/abc.git
DSD manager.
This commit is contained in:
parent
30b8c3d422
commit
abefcf8fc8
|
|
@ -2005,6 +2005,10 @@ SOURCE=.\src\opt\dau\dauInt.h
|
|||
|
||||
SOURCE=.\src\opt\dau\dauMerge.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\dau\dauTree.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Group
|
||||
# Begin Group "map"
|
||||
|
|
|
|||
|
|
@ -188,6 +188,8 @@ struct If_Man_t_
|
|||
int nChoices; // the number of choice nodes
|
||||
Vec_Int_t * vSwitching; // switching activity of each node
|
||||
Vec_Int_t ** pDriverCuts; // temporary driver cuts
|
||||
int pPerm[3][IF_MAX_LUTSIZE]; // permutations
|
||||
int nShared; // the number of shared variables
|
||||
// SOP balancing
|
||||
Vec_Int_t * vCover; // used to compute ISOP
|
||||
Vec_Wrd_t * vAnds; // intermediate storage
|
||||
|
|
@ -437,7 +439,7 @@ extern int If_ManPerformMappingComb( If_Man_t * p );
|
|||
extern int If_CutFilter( If_Set_t * pCutSet, If_Cut_t * pCut );
|
||||
extern void If_CutSort( If_Man_t * p, If_Set_t * pCutSet, If_Cut_t * pCut );
|
||||
extern void If_CutOrder( If_Cut_t * pCut );
|
||||
extern int If_CutMerge( If_Cut_t * pCut0, If_Cut_t * pCut1, If_Cut_t * pCut );
|
||||
extern int If_CutMerge( If_Man_t * p, If_Cut_t * pCut0, If_Cut_t * pCut1, If_Cut_t * pCut );
|
||||
extern int If_CutCheck( If_Cut_t * pCut );
|
||||
extern void If_CutPrint( If_Cut_t * pCut );
|
||||
extern void If_CutPrintTiming( If_Man_t * p, If_Cut_t * pCut );
|
||||
|
|
|
|||
|
|
@ -231,13 +231,12 @@ static inline int If_CutMergeOrderedOld( If_Cut_t * pC0, If_Cut_t * pC1, If_Cut_
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int If_CutMergeOrdered( If_Cut_t * pC0, If_Cut_t * pC1, If_Cut_t * pC )
|
||||
static inline int If_CutMergeOrdered( If_Man_t * p, If_Cut_t * pC0, If_Cut_t * pC1, If_Cut_t * pC )
|
||||
{
|
||||
int nLimit = pC0->nLimit;
|
||||
int nSizeC0 = pC0->nLeaves;
|
||||
int nSizeC1 = pC1->nLeaves;
|
||||
int i, k, c;
|
||||
assert( nSizeC0 >= nSizeC1 );
|
||||
int nLimit = pC0->nLimit;
|
||||
int i, k, c, s;
|
||||
|
||||
// the case when one of the cuts is the largest
|
||||
if ( nSizeC0 == nLimit )
|
||||
|
|
@ -246,43 +245,37 @@ static inline int If_CutMergeOrdered( If_Cut_t * pC0, If_Cut_t * pC1, If_Cut_t *
|
|||
if ( nSizeC1 == nLimit )
|
||||
{
|
||||
for ( i = 0; i < nSizeC0; i++ )
|
||||
{
|
||||
if ( pC0->pLeaves[i] != pC1->pLeaves[i] )
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( i = 0; i < nSizeC1; i++ )
|
||||
{
|
||||
for ( k = nSizeC0 - 1; k >= 0; k-- )
|
||||
if ( pC0->pLeaves[k] == pC1->pLeaves[i] )
|
||||
break;
|
||||
if ( k == -1 ) // did not find
|
||||
return 0;
|
||||
p->pPerm[0][i] = p->pPerm[1][i] = p->pPerm[2][i] = i;
|
||||
pC->pLeaves[i] = pC0->pLeaves[i];
|
||||
}
|
||||
pC->nLeaves = nLimit;
|
||||
return 1;
|
||||
}
|
||||
for ( i = 0; i < nSizeC0; i++ )
|
||||
pC->pLeaves[i] = pC0->pLeaves[i];
|
||||
pC->nLeaves = nLimit;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// compare two cuts with different numbers
|
||||
i = k = c = 0;
|
||||
i = k = c = s = 0;
|
||||
while ( 1 )
|
||||
{
|
||||
if ( c == nLimit ) return 0;
|
||||
if ( pC0->pLeaves[i] < pC1->pLeaves[k] )
|
||||
{
|
||||
p->pPerm[0][i] = c;
|
||||
pC->pLeaves[c++] = pC0->pLeaves[i++];
|
||||
if ( i >= nSizeC0 ) goto FlushCut1;
|
||||
}
|
||||
else if ( pC0->pLeaves[i] > pC1->pLeaves[k] )
|
||||
{
|
||||
p->pPerm[1][k] = c;
|
||||
pC->pLeaves[c++] = pC1->pLeaves[k++];
|
||||
if ( k >= nSizeC1 ) goto FlushCut0;
|
||||
}
|
||||
else
|
||||
{
|
||||
p->pPerm[0][i] = p->pPerm[1][k] = p->pPerm[2][s++] = c;
|
||||
pC->pLeaves[c++] = pC0->pLeaves[i++]; k++;
|
||||
if ( i >= nSizeC0 ) goto FlushCut1;
|
||||
if ( k >= nSizeC1 ) goto FlushCut0;
|
||||
|
|
@ -292,14 +285,20 @@ static inline int If_CutMergeOrdered( If_Cut_t * pC0, If_Cut_t * pC1, If_Cut_t *
|
|||
FlushCut0:
|
||||
if ( c + nSizeC0 > nLimit + i ) return 0;
|
||||
while ( i < nSizeC0 )
|
||||
{
|
||||
p->pPerm[0][i] = c;
|
||||
pC->pLeaves[c++] = pC0->pLeaves[i++];
|
||||
}
|
||||
pC->nLeaves = c;
|
||||
return 1;
|
||||
|
||||
FlushCut1:
|
||||
if ( c + nSizeC1 > nLimit + k ) return 0;
|
||||
while ( k < nSizeC1 )
|
||||
{
|
||||
p->pPerm[1][k] = c;
|
||||
pC->pLeaves[c++] = pC1->pLeaves[k++];
|
||||
}
|
||||
pC->nLeaves = c;
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -369,18 +368,18 @@ static inline int If_CutMergeOrdered2( If_Cut_t * pC0, If_Cut_t * pC1, If_Cut_t
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int If_CutMerge( If_Cut_t * pCut0, If_Cut_t * pCut1, If_Cut_t * pCut )
|
||||
int If_CutMerge2( If_Man_t * p, If_Cut_t * pCut0, If_Cut_t * pCut1, If_Cut_t * pCut )
|
||||
{
|
||||
assert( pCut->nLimit > 0 );
|
||||
// merge the nodes
|
||||
if ( pCut0->nLeaves < pCut1->nLeaves )
|
||||
{
|
||||
if ( !If_CutMergeOrdered( pCut1, pCut0, pCut ) )
|
||||
if ( !If_CutMergeOrdered( p, pCut1, pCut0, pCut ) )
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !If_CutMergeOrdered( pCut0, pCut1, pCut ) )
|
||||
if ( !If_CutMergeOrdered( p, pCut0, pCut1, pCut ) )
|
||||
return 0;
|
||||
}
|
||||
pCut->uSign = pCut0->uSign | pCut1->uSign;
|
||||
|
|
@ -388,6 +387,91 @@ int If_CutMerge( If_Cut_t * pCut0, If_Cut_t * pCut1, If_Cut_t * pCut )
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prepares the object for FPGA mapping.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int If_CutMerge( If_Man_t * p, If_Cut_t * pC0, If_Cut_t * pC1, If_Cut_t * pC )
|
||||
{
|
||||
int nSizeC0 = pC0->nLeaves;
|
||||
int nSizeC1 = pC1->nLeaves;
|
||||
int nLimit = pC0->nLimit;
|
||||
int i, k, c, s;
|
||||
|
||||
// both cuts are the largest
|
||||
if ( nSizeC0 == nLimit && nSizeC1 == nLimit )
|
||||
{
|
||||
for ( i = 0; i < nSizeC0; i++ )
|
||||
{
|
||||
if ( pC0->pLeaves[i] != pC1->pLeaves[i] )
|
||||
return 0;
|
||||
p->pPerm[0][i] = p->pPerm[1][i] = p->pPerm[2][i] = i;
|
||||
pC->pLeaves[i] = pC0->pLeaves[i];
|
||||
}
|
||||
p->nShared = nLimit;
|
||||
pC->nLeaves = nLimit;
|
||||
pC->uSign = pC0->uSign | pC1->uSign;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// compare two cuts with different numbers
|
||||
i = k = c = s = 0;
|
||||
while ( 1 )
|
||||
{
|
||||
if ( c == nLimit ) return 0;
|
||||
if ( pC0->pLeaves[i] < pC1->pLeaves[k] )
|
||||
{
|
||||
p->pPerm[0][i] = c;
|
||||
pC->pLeaves[c++] = pC0->pLeaves[i++];
|
||||
if ( i == nSizeC0 ) goto FlushCut1;
|
||||
}
|
||||
else if ( pC0->pLeaves[i] > pC1->pLeaves[k] )
|
||||
{
|
||||
p->pPerm[1][k] = c;
|
||||
pC->pLeaves[c++] = pC1->pLeaves[k++];
|
||||
if ( k == nSizeC1 ) goto FlushCut0;
|
||||
}
|
||||
else
|
||||
{
|
||||
p->pPerm[0][i] = p->pPerm[1][k] = p->pPerm[2][s++] = c;
|
||||
pC->pLeaves[c++] = pC0->pLeaves[i++]; k++;
|
||||
if ( i == nSizeC0 ) goto FlushCut1;
|
||||
if ( k == nSizeC1 ) goto FlushCut0;
|
||||
}
|
||||
}
|
||||
|
||||
FlushCut0:
|
||||
if ( c + nSizeC0 > nLimit + i ) return 0;
|
||||
while ( i < nSizeC0 )
|
||||
{
|
||||
p->pPerm[0][i] = c;
|
||||
pC->pLeaves[c++] = pC0->pLeaves[i++];
|
||||
}
|
||||
p->nShared = s;
|
||||
pC->nLeaves = c;
|
||||
pC->uSign = pC0->uSign | pC1->uSign;
|
||||
return 1;
|
||||
|
||||
FlushCut1:
|
||||
if ( c + nSizeC1 > nLimit + k ) return 0;
|
||||
while ( k < nSizeC1 )
|
||||
{
|
||||
p->pPerm[1][k] = c;
|
||||
pC->pLeaves[c++] = pC1->pLeaves[k++];
|
||||
}
|
||||
p->nShared = s;
|
||||
pC->nLeaves = c;
|
||||
pC->uSign = pC0->uSign | pC1->uSign;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prepares the object for FPGA mapping.]
|
||||
|
|
|
|||
|
|
@ -243,8 +243,9 @@ void If_ObjPerformMappingAnd( If_Man_t * p, If_Obj_t * pObj, int Mode, int fPrep
|
|||
if ( If_WordCountOnes(pCut0->uSign | pCut1->uSign) > p->pPars->nLutSize )
|
||||
continue;
|
||||
// merge the cuts
|
||||
if ( !If_CutMerge( pCut0, pCut1, pCut ) )
|
||||
if ( !If_CutMerge( p, pCut0, pCut1, pCut ) )
|
||||
continue;
|
||||
assert( If_CutCheck( pCut ) );
|
||||
if ( pObj->fSpec && pCut->nLeaves == (unsigned)p->pPars->nLutSize )
|
||||
continue;
|
||||
assert( p->pPars->fSeqMap || pCut->nLeaves > 1 );
|
||||
|
|
|
|||
|
|
@ -498,7 +498,7 @@ static inline int If_CutTruthMinimize6( If_Man_t * p, If_Cut_t * pCut )
|
|||
// assert( nSuppSize == Abc_TtSupportSize(If_CutTruthW(pCut), nVars) );
|
||||
return 1;
|
||||
}
|
||||
static inline word If_TruthStretch6( word Truth, If_Cut_t * pCut, If_Cut_t * pCut0 )
|
||||
static inline word If_TruthStretch6_( word Truth, If_Cut_t * pCut, If_Cut_t * pCut0 )
|
||||
{
|
||||
int i, k;
|
||||
for ( i = (int)pCut->nLeaves - 1, k = (int)pCut0->nLeaves - 1; i >= 0 && k >= 0; i-- )
|
||||
|
|
@ -512,13 +512,23 @@ static inline word If_TruthStretch6( word Truth, If_Cut_t * pCut, If_Cut_t * pCu
|
|||
}
|
||||
return Truth;
|
||||
}
|
||||
static inline word If_TruthStretch6( word Truth, int nVars, int * pPerm, int nVarsCut )
|
||||
{
|
||||
int i;
|
||||
for ( i = nVarsCut - 1; i >= 0; i-- )
|
||||
if ( i < pPerm[i] )
|
||||
Abc_TtSwapVars( &Truth, nVars, i, pPerm[i] );
|
||||
return Truth;
|
||||
}
|
||||
static inline int If_CutComputeTruth6( If_Man_t * p, If_Cut_t * pCut, If_Cut_t * pCut0, If_Cut_t * pCut1, int fCompl0, int fCompl1 )
|
||||
{
|
||||
word t0 = (fCompl0 ^ pCut0->fCompl) ? ~*If_CutTruthW(pCut0) : *If_CutTruthW(pCut0);
|
||||
word t1 = (fCompl1 ^ pCut1->fCompl) ? ~*If_CutTruthW(pCut1) : *If_CutTruthW(pCut1);
|
||||
assert( pCut->nLimit <= 6 );
|
||||
t0 = If_TruthStretch6( t0, pCut, pCut0 );
|
||||
t1 = If_TruthStretch6( t1, pCut, pCut1 );
|
||||
// t0 = If_TruthStretch6( t0, pCut, pCut0 );
|
||||
// t1 = If_TruthStretch6( t1, pCut, pCut1 );
|
||||
t0 = If_TruthStretch6( t0, pCut->nLimit, p->pPerm[0], pCut0->nLeaves );
|
||||
t1 = If_TruthStretch6( t1, pCut->nLimit, p->pPerm[1], pCut1->nLeaves );
|
||||
*If_CutTruthW(pCut) = t0 & t1;
|
||||
|
||||
#ifdef IF_TRY_NEW
|
||||
|
|
@ -615,7 +625,7 @@ static inline int If_CutTruthMinimize2( If_Man_t * p, If_Cut_t * pCut )
|
|||
// assert( nSuppSize == Abc_TtSupportSize(If_CutTruthW(pCut), nVars) );
|
||||
return 1;
|
||||
}
|
||||
static inline void If_TruthStretch2( word * pTruth, If_Cut_t * pCut, If_Cut_t * pCut0 )
|
||||
static inline void If_TruthStretch2_( word * pTruth, If_Cut_t * pCut, If_Cut_t * pCut0 )
|
||||
{
|
||||
int i, k;
|
||||
for ( i = (int)pCut->nLeaves - 1, k = (int)pCut0->nLeaves - 1; i >= 0 && k >= 0; i-- )
|
||||
|
|
@ -628,6 +638,13 @@ static inline void If_TruthStretch2( word * pTruth, If_Cut_t * pCut, If_Cut_t *
|
|||
k--;
|
||||
}
|
||||
}
|
||||
static inline void If_TruthStretch2( word * pTruth, int nVars, int * pPerm, int nVarsCut )
|
||||
{
|
||||
int i;
|
||||
for ( i = nVarsCut - 1; i >= 0; i-- )
|
||||
if ( i < pPerm[i] )
|
||||
Abc_TtSwapVars( pTruth, nVars, i, pPerm[i] );
|
||||
}
|
||||
inline int If_CutComputeTruth2( If_Man_t * p, If_Cut_t * pCut, If_Cut_t * pCut0, If_Cut_t * pCut1, int fCompl0, int fCompl1 )
|
||||
{
|
||||
int nWords;
|
||||
|
|
@ -636,8 +653,10 @@ inline int If_CutComputeTruth2( If_Man_t * p, If_Cut_t * pCut, If_Cut_t * pCut0,
|
|||
nWords = Abc_TtWordNum( pCut->nLimit );
|
||||
Abc_TtCopy( (word *)p->puTemp[0], If_CutTruthW(pCut0), nWords, fCompl0 ^ pCut0->fCompl );
|
||||
Abc_TtCopy( (word *)p->puTemp[1], If_CutTruthW(pCut1), nWords, fCompl1 ^ pCut1->fCompl );
|
||||
If_TruthStretch2( (word *)p->puTemp[0], pCut, pCut0 );
|
||||
If_TruthStretch2( (word *)p->puTemp[1], pCut, pCut1 );
|
||||
// If_TruthStretch2( (word *)p->puTemp[0], pCut, pCut0 );
|
||||
// If_TruthStretch2( (word *)p->puTemp[1], pCut, pCut1 );
|
||||
If_TruthStretch2( (word *)p->puTemp[0], pCut->nLimit, p->pPerm[0], pCut0->nLeaves );
|
||||
If_TruthStretch2( (word *)p->puTemp[1], pCut->nLimit, p->pPerm[1], pCut1->nLeaves );
|
||||
Abc_TtAnd( If_CutTruthW(pCut), (word *)p->puTemp[0], (word *)p->puTemp[1], nWords, 0 );
|
||||
|
||||
#ifdef IF_TRY_NEW
|
||||
|
|
|
|||
|
|
@ -40,20 +40,35 @@
|
|||
ABC_NAMESPACE_HEADER_START
|
||||
|
||||
#define DAU_MAX_VAR 12 // should be 6 or more
|
||||
#define DAU_MAX_STR 2048
|
||||
#define DAU_MAX_STR 256
|
||||
#define DAU_MAX_WORD (1<<(DAU_MAX_VAR-6))
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// network types
|
||||
typedef enum {
|
||||
DAU_DSD_NONE = 0, // 0: unknown
|
||||
DAU_DSD_CONST0, // 1: constant
|
||||
DAU_DSD_VAR, // 2: variable
|
||||
DAU_DSD_AND, // 3: AND
|
||||
DAU_DSD_XOR, // 4: XOR
|
||||
DAU_DSD_MUX, // 5: MUX
|
||||
DAU_DSD_PRIME // 6: PRIME
|
||||
} Dau_DsdType_t;
|
||||
|
||||
typedef struct Dss_Man_t_ Dss_Man_t;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline int Dau_DsdIsConst( char * p ) { return (p[0] == '0' || p[0] == '1') && p[1] == 0; }
|
||||
static inline int Dau_DsdIsConst0( char * p ) { return p[0] == '0' && p[1] == 0; }
|
||||
static inline int Dau_DsdIsConst1( char * p ) { return p[0] == '1' && p[1] == 0; }
|
||||
static inline int Dau_DsdIsConst( char * p ) { return (p[0] == '0' || p[0] == '1') && p[1] == 0; }
|
||||
static inline int Dau_DsdIsConst0( char * p ) { return p[0] == '0' && p[1] == 0; }
|
||||
static inline int Dau_DsdIsConst1( char * p ) { return p[0] == '1' && p[1] == 0; }
|
||||
static inline int Dau_DsdIsVar( char * p ) { if ( *p == '!' ) p++; return *p >= 'a' && *p <= 'z'; }
|
||||
static inline int Dau_DsdReadVar( char * p ) { if ( *p == '!' ) p++; return *p - 'a'; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DECLARATIONS ///
|
||||
|
|
|
|||
|
|
@ -26,17 +26,6 @@ ABC_NAMESPACE_IMPL_START
|
|||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// network types
|
||||
typedef enum {
|
||||
DAU_DSD_NONE = 0, // 0: unknown
|
||||
DAU_DSD_CONST0, // 1: constant
|
||||
DAU_DSD_VAR, // 2: variable
|
||||
DAU_DSD_AND, // 3: AND
|
||||
DAU_DSD_XOR, // 4: XOR
|
||||
DAU_DSD_MUX, // 5: MUX
|
||||
DAU_DSD_PRIME // 6: PRIME
|
||||
} Dau_DsdType_t;
|
||||
|
||||
typedef struct Dau_Dsd_t_ Dau_Dsd_t;
|
||||
struct Dau_Dsd_t_
|
||||
{
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
***********************************************************************/
|
||||
|
||||
#include "dauInt.h"
|
||||
#include "dau.h"
|
||||
#include "misc/util/utilTruth.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
|
@ -88,7 +87,7 @@ Vec_Int_t * Dau_DsdDivisors( word * pTruth, int nVars )
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
void Dau_DsdTest()
|
||||
void Dau_DsdTest000()
|
||||
{
|
||||
// char * pDsd = "!(!(abc)!(def))";
|
||||
// char * pDsd = "[(abc)(def)]";
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
***********************************************************************/
|
||||
|
||||
#include "dau.h"
|
||||
#include "dauInt.h"
|
||||
#include "misc/util/utilTruth.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include <assert.h>
|
||||
#include <time.h>
|
||||
#include "misc/vec/vec.h"
|
||||
#include "dau.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
***********************************************************************/
|
||||
|
||||
#include "dau.h"
|
||||
#include "dauInt.h"
|
||||
#include "misc/util/utilTruth.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,837 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [dauTree.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [DAG-aware unmapping.]
|
||||
|
||||
Synopsis [Canonical DSD package.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: dauTree.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "dauInt.h"
|
||||
#include "misc/mem/mem.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Dss_Obj_t_ Dss_Obj_t;
|
||||
struct Dss_Obj_t_
|
||||
{
|
||||
unsigned Id; // node ID
|
||||
unsigned Next; // next node
|
||||
unsigned Mirror : 30; // node ID
|
||||
unsigned fMark0 : 1; // user mark
|
||||
unsigned fMark1 : 1; // user mark
|
||||
unsigned iVar : 8; // variable
|
||||
unsigned nSupp : 8; // variable
|
||||
unsigned Data : 8; // variable
|
||||
unsigned Type : 3; // node type
|
||||
unsigned nFans : 5; // fanin count
|
||||
unsigned pFans[0]; // fanins
|
||||
};
|
||||
|
||||
typedef struct Dss_Ntk_t_ Dss_Ntk_t;
|
||||
struct Dss_Ntk_t_
|
||||
{
|
||||
int nVars; // the number of variables
|
||||
int nMem; // memory used
|
||||
int nMemAlloc; // memory allocated
|
||||
Dss_Obj_t * pMem; // memory array
|
||||
Dss_Obj_t * pRoot; // root node
|
||||
Vec_Ptr_t * vObjs; // internal nodes
|
||||
};
|
||||
|
||||
struct Dss_Man_t_
|
||||
{
|
||||
int nVars; // variable number
|
||||
int nBins; // table size
|
||||
unsigned * pBins; // hash table
|
||||
Mem_Flex_t * pMem; // memory for nodes
|
||||
Vec_Ptr_t * vObjs; // objects
|
||||
Vec_Int_t * vLeaves; // temp
|
||||
};
|
||||
|
||||
static inline Dss_Obj_t * Dss_Regular( Dss_Obj_t * p ) { return (Dss_Obj_t *)((ABC_PTRUINT_T)(p) & ~01); }
|
||||
static inline Dss_Obj_t * Dss_Not( Dss_Obj_t * p ) { return (Dss_Obj_t *)((ABC_PTRUINT_T)(p) ^ 01); }
|
||||
static inline Dss_Obj_t * Dss_NotCond( Dss_Obj_t * p, int c ) { return (Dss_Obj_t *)((ABC_PTRUINT_T)(p) ^ (c)); }
|
||||
static inline int Dss_IsComplement( Dss_Obj_t * p ) { return (int)((ABC_PTRUINT_T)(p) & 01); }
|
||||
|
||||
static inline void Dss_ObjClean( Dss_Obj_t * pObj ) { memset( pObj, 0, sizeof(Dss_Obj_t) ); }
|
||||
static inline int Dss_ObjId( Dss_Obj_t * pObj ) { return pObj->Id; }
|
||||
static inline int Dss_ObjType( Dss_Obj_t * pObj ) { return pObj->Type; }
|
||||
static inline int Dss_ObjFaninNum( Dss_Obj_t * pObj ) { return pObj->nFans; }
|
||||
static inline int Dss_ObjFaninC( Dss_Obj_t * pObj, int i ) { assert(i < (int)pObj->nFans); return Abc_LitIsCompl(pObj->pFans[i]); }
|
||||
static inline word * Dss_ObjTruth( Dss_Obj_t * pObj ) { return (word *)(pObj->pFans + pObj->nFans + (pObj->nFans & 1)); }
|
||||
|
||||
static inline Dss_Obj_t * Dss_NtkObj( Dss_Ntk_t * p, int Id ) { return (Dss_Obj_t *)Vec_PtrEntry(p->vObjs, Id); }
|
||||
static inline Dss_Obj_t * Dss_NtkConst0( Dss_Ntk_t * p ) { return Dss_NtkObj( p, 0 ); }
|
||||
static inline Dss_Obj_t * Dss_NtkVar( Dss_Ntk_t * p, int v ) { assert( v >= 0 && v < p->nVars ); return Dss_NtkObj( p, v+1 ); }
|
||||
|
||||
static inline Dss_Obj_t * Dss_Lit2ObjNtk( Dss_Ntk_t * p, int iLit ) { return Dss_NotCond(Dss_NtkObj(p, Abc_Lit2Var(iLit)), Abc_LitIsCompl(iLit)); }
|
||||
static inline Dss_Obj_t * Dss_ObjFaninNtk( Dss_Ntk_t * p, Dss_Obj_t * pObj,int i) { assert(i < (int)pObj->nFans); return Dss_NtkObj( p, Abc_Lit2Var(pObj->pFans[i]) ); }
|
||||
static inline Dss_Obj_t * Dss_ObjChildNtk( Dss_Ntk_t * p, Dss_Obj_t * pObj,int i) { assert(i < (int)pObj->nFans); return Dss_Lit2ObjNtk(p, pObj->pFans[i]); }
|
||||
|
||||
static inline Dss_Obj_t * Dss_ManObj( Dss_Man_t * p, int Id ) { return (Dss_Obj_t *)Vec_PtrEntry(p->vObjs, Id); }
|
||||
static inline Dss_Obj_t * Dss_ManConst0( Dss_Man_t * p ) { return Dss_ManObj( p, 0 ); }
|
||||
static inline Dss_Obj_t * Dss_ManVar( Dss_Man_t * p, int v ) { assert( v >= 0 && v < p->nVars ); return Dss_ManObj( p, v+1 ); }
|
||||
|
||||
static inline int Dss_Obj2Lit( Dss_Obj_t * pObj ) { return Abc_Var2Lit(Dss_Regular(pObj)->Id, Dss_IsComplement(pObj)); }
|
||||
static inline Dss_Obj_t * Dss_Lit2Obj( Dss_Man_t * p, int iLit ) { return Dss_NotCond(Dss_ManObj(p, Abc_Lit2Var(iLit)), Abc_LitIsCompl(iLit)); }
|
||||
static inline Dss_Obj_t * Dss_ObjFanin( Dss_Man_t * p, Dss_Obj_t * pObj, int i ) { assert(i < (int)pObj->nFans); return Dss_ManObj(p, Abc_Lit2Var(pObj->pFans[i])); }
|
||||
static inline Dss_Obj_t * Dss_ObjChild( Dss_Man_t * p, Dss_Obj_t * pObj, int i ) { assert(i < (int)pObj->nFans); return Dss_Lit2Obj(p, pObj->pFans[i]); }
|
||||
|
||||
#define Dss_NtkForEachNode( p, pObj, i ) \
|
||||
Vec_PtrForEachEntryStart( Dss_Obj_t *, p->vObjs, pObj, i, p->nVars + 1 )
|
||||
#define Dss_ObjForEachFaninNtk( p, pObj, pFanin, i ) \
|
||||
for ( i = 0; (i < Dss_ObjFaninNum(pObj)) && ((pFanin) = Dss_ObjFaninNtk(p, pObj, i)); i++ )
|
||||
#define Dss_ObjForEachChildNtk( p, pObj, pFanin, i ) \
|
||||
for ( i = 0; (i < Dss_ObjFaninNum(pObj)) && ((pFanin) = Dss_ObjChildNtk(p, pObj, i)); i++ )
|
||||
|
||||
#define Dss_ManForEachObjVec( vLits, p, pObj, i ) \
|
||||
for ( i = 0; (i < Vec_IntSize(vLits)) && ((pObj) = Dss_Lit2Obj(p, Vec_IntEntry(vLits,i))); i++ )
|
||||
#define Dss_ObjForEachFanin( p, pObj, pFanin, i ) \
|
||||
for ( i = 0; (i < Dss_ObjFaninNum(pObj)) && ((pFanin) = Dss_ObjFanin(p, pObj, i)); i++ )
|
||||
#define Dss_ObjForEachChild( p, pObj, pFanin, i ) \
|
||||
for ( i = 0; (i < Dss_ObjFaninNum(pObj)) && ((pFanin) = Dss_ObjChild(p, pObj, i)); i++ )
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creating DSD network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Dss_Obj_t * Dss_ObjAllocNtk( Dss_Ntk_t * p, int Type, int nFans, int nTruthVars )
|
||||
{
|
||||
int nStructs = 1 + (nFans / sizeof(Dss_Obj_t)) + (nFans % sizeof(Dss_Obj_t) > 0);
|
||||
Dss_Obj_t * pObj = p->pMem + p->nMem;
|
||||
p->nMem += nStructs;
|
||||
assert( p->nMem < p->nMemAlloc );
|
||||
Dss_ObjClean( pObj );
|
||||
pObj->Type = Type;
|
||||
pObj->nFans = nFans;
|
||||
pObj->Id = Vec_PtrSize( p->vObjs );
|
||||
pObj->iVar = 31;
|
||||
pObj->Mirror = ~0;
|
||||
Vec_PtrPush( p->vObjs, pObj );
|
||||
return pObj;
|
||||
}
|
||||
Dss_Obj_t * Dss_ObjCreateNtk( Dss_Ntk_t * p, int Type, Vec_Int_t * vFaninLits )
|
||||
{
|
||||
Dss_Obj_t * pObj;
|
||||
int i, Entry;
|
||||
pObj = Dss_ObjAllocNtk( p, Type, Vec_IntSize(vFaninLits), 0 );
|
||||
Vec_IntForEachEntry( vFaninLits, Entry, i )
|
||||
{
|
||||
pObj->pFans[i] = Entry;
|
||||
pObj->nSupp += Dss_ObjFaninNtk(p, pObj, i)->nSupp;
|
||||
}
|
||||
assert( i == (int)pObj->nFans );
|
||||
return pObj;
|
||||
}
|
||||
Dss_Ntk_t * Dss_NtkAlloc( int nVars )
|
||||
{
|
||||
Dss_Ntk_t * p;
|
||||
Dss_Obj_t * pObj;
|
||||
int i;
|
||||
p = ABC_CALLOC( Dss_Ntk_t, 1 );
|
||||
p->nVars = nVars;
|
||||
p->nMemAlloc = DAU_MAX_STR;
|
||||
p->pMem = ABC_ALLOC( Dss_Obj_t, p->nMemAlloc );
|
||||
p->vObjs = Vec_PtrAlloc( 100 );
|
||||
Dss_ObjAllocNtk( p, DAU_DSD_CONST0, 0, 0 );
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
{
|
||||
pObj = Dss_ObjAllocNtk( p, DAU_DSD_VAR, 0, 0 );
|
||||
pObj->iVar = i;
|
||||
pObj->nSupp = 1;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
void Dss_NtkFree( Dss_Ntk_t * p )
|
||||
{
|
||||
Vec_PtrFree( p->vObjs );
|
||||
ABC_FREE( p->pMem );
|
||||
ABC_FREE( p );
|
||||
}
|
||||
void Dss_NtkPrint_rec( Dss_Ntk_t * p, Dss_Obj_t * pObj )
|
||||
{
|
||||
char OpenType[7] = {0, 0, 0, '(', '[', '<', '{'};
|
||||
char CloseType[7] = {0, 0, 0, ')', ']', '>', '}'};
|
||||
Dss_Obj_t * pFanin;
|
||||
int i;
|
||||
assert( !Dss_IsComplement(pObj) );
|
||||
if ( pObj->Type == DAU_DSD_VAR )
|
||||
{ printf( "%c", 'a' + pObj->iVar ); return; }
|
||||
printf( "%c", OpenType[pObj->Type] );
|
||||
Dss_ObjForEachFaninNtk( p, pObj, pFanin, i )
|
||||
{
|
||||
printf( "%s", Dss_ObjFaninC(pObj, i) ? "!":"" );
|
||||
Dss_NtkPrint_rec( p, pFanin );
|
||||
}
|
||||
printf( "%c", CloseType[pObj->Type] );
|
||||
}
|
||||
void Dss_NtkPrint( Dss_Ntk_t * p )
|
||||
{
|
||||
if ( Dss_Regular(p->pRoot)->Type == DAU_DSD_CONST0 )
|
||||
printf( "%d", Dss_IsComplement(p->pRoot) );
|
||||
else
|
||||
{
|
||||
printf( "%s", Dss_IsComplement(p->pRoot) ? "!":"" );
|
||||
if ( Dss_Regular(p->pRoot)->Type == DAU_DSD_VAR )
|
||||
printf( "%s%d", Dss_Regular(p->pRoot)->iVar );
|
||||
else
|
||||
Dss_NtkPrint_rec( p, Dss_Regular(p->pRoot) );
|
||||
}
|
||||
printf( "\n" );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creating DSD network from SOP.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Dau_DsdMergeMatches( char * pDsd, int * pMatches )
|
||||
{
|
||||
int pNested[DAU_MAX_VAR];
|
||||
int i, nNested = 0;
|
||||
for ( i = 0; pDsd[i]; i++ )
|
||||
{
|
||||
pMatches[i] = 0;
|
||||
if ( pDsd[i] == '(' || pDsd[i] == '[' || pDsd[i] == '<' || pDsd[i] == '{' )
|
||||
pNested[nNested++] = i;
|
||||
else if ( pDsd[i] == ')' || pDsd[i] == ']' || pDsd[i] == '>' || pDsd[i] == '}' )
|
||||
pMatches[pNested[--nNested]] = i;
|
||||
assert( nNested < DAU_MAX_VAR );
|
||||
}
|
||||
assert( nNested == 0 );
|
||||
}
|
||||
int Dss_NtkCreate_rec( char * pStr, char ** p, int * pMatches, Dss_Ntk_t * pNtk )
|
||||
{
|
||||
int fCompl = 0;
|
||||
if ( **p == '!' )
|
||||
{
|
||||
fCompl = 1;
|
||||
(*p)++;
|
||||
}
|
||||
while ( (**p >= 'A' && **p <= 'F') || (**p >= '0' && **p <= '9') )
|
||||
(*p)++;
|
||||
if ( **p == '<' )
|
||||
{
|
||||
char * q = pStr + pMatches[ *p - pStr ];
|
||||
if ( *(q+1) == '{' )
|
||||
*p = q+1;
|
||||
}
|
||||
if ( **p >= 'a' && **p <= 'z' ) // var
|
||||
return Abc_Var2Lit( Dss_ObjId(Dss_NtkVar(pNtk, **p - 'a')), fCompl );
|
||||
if ( **p == '(' || **p == '[' || **p == '<' || **p == '{' ) // and/or/xor
|
||||
{
|
||||
Dss_Obj_t * pObj;
|
||||
Vec_Int_t * vFaninLits = Vec_IntAlloc( 10 );
|
||||
char * q = pStr + pMatches[ *p - pStr ];
|
||||
int Type;
|
||||
if ( **p == '(' )
|
||||
Type = DAU_DSD_AND;
|
||||
else if ( **p == '[' )
|
||||
Type = DAU_DSD_XOR;
|
||||
else if ( **p == '<' )
|
||||
Type = DAU_DSD_MUX;
|
||||
else if ( **p == '{' )
|
||||
Type = DAU_DSD_PRIME;
|
||||
else assert( 0 );
|
||||
assert( *q == **p + 1 + (**p != '(') );
|
||||
for ( (*p)++; *p < q; (*p)++ )
|
||||
Vec_IntPush( vFaninLits, Dss_NtkCreate_rec(pStr, p, pMatches, pNtk) );
|
||||
assert( *p == q );
|
||||
pObj = Dss_ObjCreateNtk( pNtk, Type, vFaninLits );
|
||||
Vec_IntFree( vFaninLits );
|
||||
return Abc_LitNotCond( Dss_Obj2Lit(pObj), fCompl );
|
||||
}
|
||||
assert( 0 );
|
||||
return -1;
|
||||
}
|
||||
Dss_Ntk_t * Dss_NtkCreate( char * pDsd, int nVars )
|
||||
{
|
||||
int fCompl = 0;
|
||||
Dss_Ntk_t * pNtk = Dss_NtkAlloc( nVars );
|
||||
if ( *pDsd == '!' )
|
||||
pDsd++, fCompl = 1;
|
||||
if ( Dau_DsdIsConst(pDsd) )
|
||||
pNtk->pRoot = Dss_NtkConst0(pNtk);
|
||||
else if ( Dau_DsdIsVar(pDsd) )
|
||||
pNtk->pRoot = Dss_NtkVar(pNtk, Dau_DsdReadVar(pDsd));
|
||||
else
|
||||
{
|
||||
int iLit, pMatches[DAU_MAX_STR];
|
||||
Dau_DsdMergeMatches( pDsd, pMatches );
|
||||
iLit = Dss_NtkCreate_rec( pDsd, &pDsd, pMatches, pNtk );
|
||||
pNtk->pRoot = Dss_Lit2ObjNtk( pNtk, iLit );
|
||||
}
|
||||
if ( fCompl )
|
||||
pNtk->pRoot = Dss_Not(pNtk->pRoot);
|
||||
return pNtk;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Comparing two DSD nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Dss_ObjCompareNtk( Dss_Ntk_t * p, Dss_Obj_t * p0i, Dss_Obj_t * p1i )
|
||||
{
|
||||
Dss_Obj_t * p0 = Dss_Regular(p0i);
|
||||
Dss_Obj_t * p1 = Dss_Regular(p1i);
|
||||
Dss_Obj_t * pChild0, * pChild1;
|
||||
int i, Res;
|
||||
if ( Dss_ObjType(p0) < Dss_ObjType(p1) )
|
||||
return -1;
|
||||
if ( Dss_ObjType(p0) > Dss_ObjType(p1) )
|
||||
return 1;
|
||||
if ( Dss_ObjType(p0) < DAU_DSD_AND )
|
||||
return 0;
|
||||
if ( Dss_ObjFaninNum(p0) < Dss_ObjFaninNum(p1) )
|
||||
return -1;
|
||||
if ( Dss_ObjFaninNum(p0) > Dss_ObjFaninNum(p1) )
|
||||
return 1;
|
||||
for ( i = 0; i < Dss_ObjFaninNum(p0); i++ )
|
||||
{
|
||||
pChild0 = Dss_ObjChildNtk( p, p0, i );
|
||||
pChild1 = Dss_ObjChildNtk( p, p1, i );
|
||||
Res = Dss_ObjCompareNtk( p, pChild0, pChild1 );
|
||||
if ( Res != 0 )
|
||||
return Res;
|
||||
}
|
||||
if ( Dss_IsComplement(p0i) < Dss_IsComplement(p1i) )
|
||||
return -1;
|
||||
if ( Dss_IsComplement(p0i) > Dss_IsComplement(p1i) )
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
void Dss_ObjSortNtk( Dss_Ntk_t * p, Dss_Obj_t ** pNodes, int nNodes )
|
||||
{
|
||||
int i, j, best_i;
|
||||
for ( i = 0; i < nNodes-1; i++ )
|
||||
{
|
||||
best_i = i;
|
||||
for ( j = i+1; j < nNodes; j++ )
|
||||
if ( Dss_ObjCompareNtk(p, pNodes[best_i], pNodes[j]) == 1 )
|
||||
best_i = j;
|
||||
if ( i == best_i )
|
||||
continue;
|
||||
ABC_SWAP( Dss_Obj_t *, pNodes[i], pNodes[best_i] );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creating DSD network from SOP.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Dss_NtkCheck( Dss_Ntk_t * p )
|
||||
{
|
||||
Dss_Obj_t * pObj, * pFanin;
|
||||
int i, k;
|
||||
Dss_NtkForEachNode( p, pObj, i )
|
||||
{
|
||||
Dss_ObjForEachFaninNtk( p, pObj, pFanin, k )
|
||||
{
|
||||
if ( pObj->Type == DAU_DSD_AND && pFanin->Type == DAU_DSD_AND )
|
||||
assert( Dss_ObjFaninC(pObj, k) );
|
||||
else if ( pObj->Type == DAU_DSD_XOR )
|
||||
assert( pFanin->Type != DAU_DSD_XOR );
|
||||
else if ( pObj->Type == DAU_DSD_MUX )
|
||||
assert( !Dss_ObjFaninC(pObj, 0) );
|
||||
}
|
||||
}
|
||||
}
|
||||
void Dss_NtkTransform( Dss_Ntk_t * p )
|
||||
{
|
||||
Dss_Obj_t * pChildren[DAU_MAX_VAR];
|
||||
Vec_Ptr_t Fanins, * vFanins = &Fanins;
|
||||
Dss_Obj_t * pObj, * pChild;
|
||||
int i, k;
|
||||
Dss_NtkForEachNode( p, pObj, i )
|
||||
{
|
||||
Dss_ObjForEachChildNtk( p, pObj, pChild, k )
|
||||
pChildren[k] = pChild;
|
||||
Dss_ObjSortNtk( p, pChildren, Dss_ObjFaninNum(pObj) );
|
||||
for ( k = 0; k < Dss_ObjFaninNum(pObj); k++ )
|
||||
pObj->pFans[k] = Dss_Obj2Lit( pChildren[k] );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Comparing two DSD nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Dss_ObjCompare( Dss_Man_t * p, Dss_Obj_t * p0i, Dss_Obj_t * p1i )
|
||||
{
|
||||
Dss_Obj_t * p0 = Dss_Regular(p0i);
|
||||
Dss_Obj_t * p1 = Dss_Regular(p1i);
|
||||
Dss_Obj_t * pChild0, * pChild1;
|
||||
int i, Res;
|
||||
if ( Dss_ObjType(p0) < Dss_ObjType(p1) )
|
||||
return -1;
|
||||
if ( Dss_ObjType(p0) > Dss_ObjType(p1) )
|
||||
return 1;
|
||||
if ( Dss_ObjType(p0) < DAU_DSD_AND )
|
||||
{
|
||||
assert( !Dss_IsComplement(p0i) );
|
||||
assert( !Dss_IsComplement(p1i) );
|
||||
return 0;
|
||||
}
|
||||
if ( Dss_ObjFaninNum(p0) < Dss_ObjFaninNum(p1) )
|
||||
return -1;
|
||||
if ( Dss_ObjFaninNum(p0) > Dss_ObjFaninNum(p1) )
|
||||
return 1;
|
||||
for ( i = 0; i < Dss_ObjFaninNum(p0); i++ )
|
||||
{
|
||||
pChild0 = Dss_ObjChild( p, p0, i );
|
||||
pChild1 = Dss_ObjChild( p, p1, i );
|
||||
Res = Dss_ObjCompare( p, pChild0, pChild1 );
|
||||
if ( Res != 0 )
|
||||
return Res;
|
||||
}
|
||||
if ( Dss_IsComplement(p0i) < Dss_IsComplement(p1i) )
|
||||
return -1;
|
||||
if ( Dss_IsComplement(p0i) > Dss_IsComplement(p1i) )
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
void Dss_ObjSort( Dss_Man_t * p, Dss_Obj_t ** pNodes, int nNodes )
|
||||
{
|
||||
int i, j, best_i;
|
||||
for ( i = 0; i < nNodes-1; i++ )
|
||||
{
|
||||
best_i = i;
|
||||
for ( j = i+1; j < nNodes; j++ )
|
||||
if ( Dss_ObjCompare(p, pNodes[best_i], pNodes[j]) == 1 )
|
||||
best_i = j;
|
||||
if ( i == best_i )
|
||||
continue;
|
||||
ABC_SWAP( Dss_Obj_t *, pNodes[i], pNodes[best_i] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Dss_Obj_t * Dss_ObjAlloc( Dss_Man_t * p, int Type, int nFans, int nTruthVars )
|
||||
{
|
||||
int nInts = sizeof(Dss_Obj_t) / sizeof(int) + nFans;
|
||||
int nWords = (nInts >> 1) + (nInts & 1) + (nTruthVars ? Abc_Truth6WordNum(nTruthVars) : 0);
|
||||
Dss_Obj_t * pObj = (Dss_Obj_t *)Mem_FlexEntryFetch( p->pMem, sizeof(word) * nWords );
|
||||
Dss_ObjClean( pObj );
|
||||
pObj->Type = Type;
|
||||
pObj->nFans = nFans;
|
||||
pObj->Id = Vec_PtrSize( p->vObjs );
|
||||
pObj->iVar = 31;
|
||||
pObj->Mirror = ~0;
|
||||
Vec_PtrPush( p->vObjs, pObj );
|
||||
return pObj;
|
||||
}
|
||||
Dss_Obj_t * Dss_ObjCreate( Dss_Man_t * p, int Type, Vec_Int_t * vFaninLits )
|
||||
{
|
||||
Dss_Obj_t * pObj, * pFanin, * pPrev = NULL;
|
||||
int i, Entry;
|
||||
// check that leaves are in good order
|
||||
Dss_ManForEachObjVec( vFaninLits, p, pFanin, i )
|
||||
{
|
||||
assert( pPrev == NULL || Dss_ObjCompare(p, pPrev, pFanin) <= 0 );
|
||||
pPrev = pFanin;
|
||||
}
|
||||
// create new node
|
||||
pObj = Dss_ObjAlloc( p, Type, Vec_IntSize(vFaninLits), 0 );
|
||||
Vec_IntForEachEntry( vFaninLits, Entry, i )
|
||||
{
|
||||
pObj->pFans[i] = Entry;
|
||||
pObj->nSupp += Dss_ObjFanin(p, pObj, i)->nSupp;
|
||||
}
|
||||
return pObj;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline unsigned Dss_ObjHashKey( Dss_Man_t * p, int Type, Vec_Int_t * vFaninLits )
|
||||
{
|
||||
static int s_Primes[8] = { 1699, 4177, 5147, 5647, 6343, 7103, 7873, 8147 };
|
||||
int i, Entry;
|
||||
unsigned uHash = Type * 7873 + Vec_IntSize(vFaninLits) * 8147;
|
||||
Vec_IntForEachEntry( vFaninLits, Entry, i )
|
||||
uHash += Entry * s_Primes[i & 0x7];
|
||||
return uHash % p->nBins;
|
||||
}
|
||||
unsigned * Dss_ObjHashLookup( Dss_Man_t * p, int Type, Vec_Int_t * vFaninLits )
|
||||
{
|
||||
Dss_Obj_t * pObj;
|
||||
unsigned * pSpot = p->pBins + Dss_ObjHashKey(p, Type, vFaninLits);
|
||||
for ( ; *pSpot; pSpot = &pObj->Next )
|
||||
{
|
||||
pObj = Dss_ManObj( p, *pSpot );
|
||||
if ( (int)pObj->Type == Type && (int)pObj->nFans == Vec_IntSize(vFaninLits) && !memcmp(pObj->pFans, Vec_IntArray(vFaninLits), sizeof(int)*pObj->nFans) ) // equal
|
||||
return pSpot;
|
||||
}
|
||||
return pSpot;
|
||||
}
|
||||
Dss_Obj_t * Dss_ObjFindOrAdd( Dss_Man_t * p, int Type, Vec_Int_t * vFaninLits )
|
||||
{
|
||||
Dss_Obj_t * pObj;
|
||||
unsigned * pSpot = Dss_ObjHashLookup( p, Type, vFaninLits );
|
||||
if ( *pSpot )
|
||||
return Dss_ManObj( p, *pSpot );
|
||||
pObj = Dss_ObjCreate( p, Type, vFaninLits );
|
||||
*pSpot = pObj->Id;
|
||||
return pObj;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Dss_Man_t * Dss_ManAlloc( int nVars )
|
||||
{
|
||||
Dss_Man_t * p;
|
||||
Dss_Obj_t * pObj;
|
||||
int i;
|
||||
p = ABC_CALLOC( Dss_Man_t, 1 );
|
||||
p->nVars = nVars;
|
||||
p->nBins = Abc_PrimeCudd( 1000 );
|
||||
p->pBins = ABC_CALLOC( int, p->nBins );
|
||||
p->pMem = Mem_FlexStart();
|
||||
p->vObjs = Vec_PtrAlloc( 1000 );
|
||||
Dss_ObjAlloc( p, DAU_DSD_CONST0, 0, 0 );
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
{
|
||||
pObj = Dss_ObjAlloc( p, DAU_DSD_VAR, 0, 0 );
|
||||
pObj->iVar = i;
|
||||
pObj->nSupp = 1;
|
||||
pObj->Mirror = 1;
|
||||
}
|
||||
p->vLeaves = Vec_IntAlloc( 32 );
|
||||
return p;
|
||||
|
||||
}
|
||||
void Dss_ManFree( Dss_Man_t * p )
|
||||
{
|
||||
Vec_IntFreeP( &p->vLeaves );
|
||||
Vec_PtrFreeP( &p->vObjs );
|
||||
Mem_FlexStop( p->pMem, 0 );
|
||||
ABC_FREE( p->pBins );
|
||||
ABC_FREE( p );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Dss_Obj_t * Dss_ManShiftTree( Dss_Man_t * p, Dss_Obj_t * pObj, int Shift )
|
||||
{
|
||||
Vec_Int_t * vFaninLits;
|
||||
Dss_Obj_t * pFanin, * pObjNew;
|
||||
int i;
|
||||
assert( !Dss_IsComplement(pObj) );
|
||||
assert( pObj->Mirror == pObj->Id );
|
||||
if ( pObj->Type == DAU_DSD_VAR )
|
||||
{
|
||||
assert( (int)pObj->iVar + Shift < p->nVars );
|
||||
return Dss_ManVar( p, pObj->iVar + Shift );
|
||||
}
|
||||
// collect fanins
|
||||
vFaninLits = Vec_IntAlloc( 10 );
|
||||
Dss_ObjForEachFanin( p, pObj, pFanin, i )
|
||||
{
|
||||
pFanin = Dss_ManShiftTree( p, pFanin, Shift );
|
||||
Vec_IntPush( vFaninLits, Abc_Var2Lit(pFanin->Id, Dss_ObjFaninC(pObj, i)) );
|
||||
}
|
||||
// create new graph
|
||||
pObjNew = Dss_ObjFindOrAdd( p, pObj->Type, vFaninLits );
|
||||
pObjNew->Mirror = pObj->Id;
|
||||
Vec_IntFree( vFaninLits );
|
||||
return pObjNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Dss_ManOperation( Dss_Man_t * p, int Type, int * pLits, int nLits, int * pPerm )
|
||||
{
|
||||
Dss_Obj_t * pChildren[DAU_MAX_VAR];
|
||||
Dss_Obj_t * pObj, * pFanin, * pChild, * pMirror;
|
||||
int i, k, nChildren = 0, fCompl = 0, nSupp = 0;
|
||||
|
||||
if ( Type == DAU_DSD_AND )
|
||||
{
|
||||
for ( k = 0; k < nLits; k++ )
|
||||
{
|
||||
pObj = Dss_Lit2Obj(p, pLits[k]);
|
||||
if ( Dss_IsComplement(pObj) || pObj->Type != DAU_DSD_AND )
|
||||
pChildren[nChildren++] = pObj;
|
||||
else
|
||||
Dss_ObjForEachChild( p, pObj, pChild, i )
|
||||
pChildren[nChildren++] = pChild;
|
||||
}
|
||||
Dss_ObjSort( p, pChildren, nChildren );
|
||||
}
|
||||
else if ( Type == DAU_DSD_XOR )
|
||||
{
|
||||
for ( k = 0; k < nLits; k++ )
|
||||
{
|
||||
fCompl ^= Abc_LitIsCompl(pLits[k]);
|
||||
pObj = Dss_Lit2Obj(p, Abc_LitRegular(pLits[k]));
|
||||
if ( pObj->Type != DAU_DSD_XOR )
|
||||
pChildren[nChildren++] = pObj;
|
||||
else
|
||||
Dss_ObjForEachChild( p, pObj, pChild, i )
|
||||
{
|
||||
assert( !Dss_IsComplement(pChild) );
|
||||
pChildren[nChildren++] = pChild;
|
||||
}
|
||||
}
|
||||
Dss_ObjSort( p, pChildren, nChildren );
|
||||
}
|
||||
else if ( Type == DAU_DSD_MUX )
|
||||
{
|
||||
fCompl = Abc_LitIsCompl(pLits[1]) && Abc_LitIsCompl(pLits[2]);
|
||||
if ( Abc_LitIsCompl(pLits[0]) )
|
||||
{
|
||||
pChildren[nChildren++] = Dss_Lit2Obj(p, Abc_LitNotCond(pLits[0], 1));
|
||||
pChildren[nChildren++] = Dss_Lit2Obj(p, Abc_LitNotCond(pLits[2], fCompl));
|
||||
pChildren[nChildren++] = Dss_Lit2Obj(p, Abc_LitNotCond(pLits[1], fCompl));
|
||||
}
|
||||
else
|
||||
{
|
||||
pChildren[nChildren++] = Dss_Lit2Obj(p, Abc_LitNotCond(pLits[0], 0));
|
||||
pChildren[nChildren++] = Dss_Lit2Obj(p, Abc_LitNotCond(pLits[1], fCompl));
|
||||
pChildren[nChildren++] = Dss_Lit2Obj(p, Abc_LitNotCond(pLits[2], fCompl));
|
||||
}
|
||||
}
|
||||
else if ( Type == DAU_DSD_PRIME )
|
||||
{
|
||||
for ( k = 0; k < nLits; k++ )
|
||||
pChildren[nChildren++] = Dss_Lit2Obj(p, pLits[k]);
|
||||
}
|
||||
else assert( 0 );
|
||||
|
||||
// shift subgraphs
|
||||
nSupp = 0;
|
||||
Vec_IntClear( p->vLeaves );
|
||||
for ( i = 0; i < nChildren; i++ )
|
||||
{
|
||||
pMirror = Dss_ManObj( p, Dss_Regular(pChildren[i])->Mirror );
|
||||
pFanin = Dss_ManShiftTree( p, pMirror, nSupp );
|
||||
assert( !Dss_IsComplement(pFanin) );
|
||||
assert( pFanin->nSupp > 0 );
|
||||
nSupp += pFanin->nSupp;
|
||||
Vec_IntPush( p->vLeaves, Abc_Var2Lit(pFanin->Id, Dss_IsComplement(pChildren[i])) );
|
||||
}
|
||||
// create new graph
|
||||
pObj = Dss_ObjFindOrAdd( p, Type, p->vLeaves );
|
||||
pObj->Mirror = pObj->Id;
|
||||
return Abc_Var2Lit( pObj->Id, fCompl );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Dau_DsdTest()
|
||||
{
|
||||
int nVars = 8;
|
||||
// char * pDsd = "[(ab)(cd)]";
|
||||
char * pDsd = "(!(a!(bh))[cde]!(fg))";
|
||||
Dss_Ntk_t * pNtk = Dss_NtkCreate( pDsd, nVars );
|
||||
// Dss_NtkPrint( pNtk );
|
||||
// Dss_NtkCheck( pNtk );
|
||||
// Dss_NtkTransform( pNtk );
|
||||
// Dss_NtkPrint( pNtk );
|
||||
Dss_NtkFree( pNtk );
|
||||
nVars = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Dau_DsdTest_()
|
||||
{
|
||||
int nVars = 8;
|
||||
Vec_Vec_t * vFuncs = Vec_VecStart( nVars+1 );
|
||||
Vec_Int_t * vOne, * vTwo, * vThree;
|
||||
Dss_Man_t * p;
|
||||
int pEntries[3];
|
||||
int e0, e1, e2, iLit;
|
||||
int i, j, k, s;
|
||||
|
||||
|
||||
assert( nVars < DAU_MAX_VAR );
|
||||
p = Dss_ManAlloc( nVars );
|
||||
|
||||
// init
|
||||
Vec_VecPushInt( vFuncs, 1, Dss_Obj2Lit(Dss_ManVar(p, 0)) );
|
||||
|
||||
// enumerate
|
||||
for ( s = 2; s <= nVars; s++ )
|
||||
{
|
||||
for ( i = 1; i < s; i++ )
|
||||
for ( k = i; k < s; k++ )
|
||||
if ( i + k == s )
|
||||
{
|
||||
vOne = Vec_VecEntryInt( vFuncs, i );
|
||||
vTwo = Vec_VecEntryInt( vFuncs, k );
|
||||
Vec_IntForEachEntry( vOne, pEntries[0], e0 )
|
||||
Vec_IntForEachEntry( vTwo, pEntries[1], e1 )
|
||||
{
|
||||
iLit = Dss_ManOperation( p, DAU_DSD_AND, pEntries, 2, NULL );
|
||||
Vec_VecPushInt( vFuncs, s, iLit );
|
||||
|
||||
pEntries[0] = Abc_LitNot( pEntries[0] );
|
||||
iLit = Dss_ManOperation( p, DAU_DSD_AND, pEntries, 2, NULL );
|
||||
Vec_VecPushInt( vFuncs, s, iLit );
|
||||
|
||||
pEntries[1] = Abc_LitNot( pEntries[1] );
|
||||
iLit = Dss_ManOperation( p, DAU_DSD_AND, pEntries, 2, NULL );
|
||||
Vec_VecPushInt( vFuncs, s, iLit );
|
||||
|
||||
pEntries[0] = Abc_LitNot( pEntries[0] );
|
||||
iLit = Dss_ManOperation( p, DAU_DSD_AND, pEntries, 2, NULL );
|
||||
Vec_VecPushInt( vFuncs, s, iLit );
|
||||
|
||||
pEntries[1] = Abc_LitNot( pEntries[1] );
|
||||
iLit = Dss_ManOperation( p, DAU_DSD_XOR, pEntries, 2, NULL );
|
||||
Vec_VecPushInt( vFuncs, s, iLit );
|
||||
}
|
||||
}
|
||||
|
||||
for ( i = 1; i < s; i++ )
|
||||
for ( k = i; k < s; k++ )
|
||||
for ( j = i; j < s; j++ )
|
||||
if ( i + k + j == s )
|
||||
{
|
||||
vOne = Vec_VecEntryInt( vFuncs, i );
|
||||
vTwo = Vec_VecEntryInt( vFuncs, k );
|
||||
vThree = Vec_VecEntryInt( vFuncs, j );
|
||||
Vec_IntForEachEntry( vOne, pEntries[0], e0 )
|
||||
Vec_IntForEachEntry( vTwo, pEntries[1], e1 )
|
||||
Vec_IntForEachEntry( vTwo, pEntries[2], e2 )
|
||||
{
|
||||
iLit = Dss_ManOperation( p, DAU_DSD_AND, pEntries, 3, NULL );
|
||||
Vec_VecPushInt( vFuncs, s, iLit );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Dss_ManFree( p );
|
||||
Vec_VecFree( vFuncs );
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
@ -4,4 +4,5 @@ SRC += src/opt/dau/dau.c \
|
|||
src/opt/dau/dauDivs.c \
|
||||
src/opt/dau/dauDsd.c \
|
||||
src/opt/dau/dauEnum.c \
|
||||
src/opt/dau/dauMerge.c
|
||||
src/opt/dau/dauMerge.c \
|
||||
src/opt/dau/dauTree.c
|
||||
|
|
|
|||
Loading…
Reference in New Issue