mirror of https://github.com/YosysHQ/abc.git
Version abc61206
This commit is contained in:
parent
38254947a5
commit
4cf99cae95
48
abc.dsp
48
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\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" /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\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" /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\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" /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\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" /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"
|
||||
|
|
@ -630,10 +630,6 @@ SOURCE=.\src\aig\ivy\ivyFastMap.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\ivy\ivyFpga.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\ivy\ivyFraig.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
@ -642,10 +638,6 @@ SOURCE=.\src\aig\ivy\ivyHaig.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\ivy\ivyIsop.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\ivy\ivyMan.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
@ -1597,6 +1589,42 @@ SOURCE=.\src\opt\ret\retInt.h
|
|||
SOURCE=.\src\opt\ret\retLvalue.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "kit"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\kit\kit.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\kit\kitBdd.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\kit\kitFactor.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\kit\kitGraph.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\kit\kitHop.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\kit\kitIsop.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\kit\kitSop.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\kit\kitTruth.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Group
|
||||
# Begin Group "map"
|
||||
|
||||
|
|
|
|||
|
|
@ -466,8 +466,6 @@ extern void Ivy_ManHaigPostprocess( Ivy_Man_t * p, int fVerbose );
|
|||
extern void Ivy_ManHaigCreateObj( Ivy_Man_t * p, Ivy_Obj_t * pObj );
|
||||
extern void Ivy_ManHaigCreateChoice( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew );
|
||||
extern void Ivy_ManHaigSimulate( Ivy_Man_t * p );
|
||||
/*=== ivyIsop.c ==========================================================*/
|
||||
extern int Ivy_TruthIsop( unsigned * puTruth, int nVars, Vec_Int_t * vCover, int fTryBoth );
|
||||
/*=== ivyMan.c ==========================================================*/
|
||||
extern Ivy_Man_t * Ivy_ManStart();
|
||||
extern Ivy_Man_t * Ivy_ManStartFrom( Ivy_Man_t * p );
|
||||
|
|
|
|||
|
|
@ -1,783 +0,0 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [ivyFactor.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [And-Inverter Graph package.]
|
||||
|
||||
Synopsis [Factoring the cover up to 16 inputs.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 11, 2006.]
|
||||
|
||||
Revision [$Id: ivyFactor.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "ivy.h"
|
||||
#include "dec.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ISOP computation fails if intermediate memory usage exceed this limit
|
||||
#define IVY_FACTOR_MEM_LIMIT 16*4096
|
||||
|
||||
// intermediate ISOP representation
|
||||
typedef struct Ivy_Sop_t_ Ivy_Sop_t;
|
||||
struct Ivy_Sop_t_
|
||||
{
|
||||
unsigned * uCubes;
|
||||
int nCubes;
|
||||
};
|
||||
|
||||
static inline int Ivy_CubeHasLit( unsigned uCube, int i ) { return (uCube & (unsigned)(1<<i)) > 0;}
|
||||
static inline unsigned Ivy_CubeSetLit( unsigned uCube, int i ) { return uCube | (unsigned)(1<<i); }
|
||||
static inline unsigned Ivy_CubeXorLit( unsigned uCube, int i ) { return uCube ^ (unsigned)(1<<i); }
|
||||
static inline unsigned Ivy_CubeRemLit( unsigned uCube, int i ) { return uCube & ~(unsigned)(1<<i); }
|
||||
|
||||
static inline int Ivy_CubeContains( unsigned uLarge, unsigned uSmall ) { return (uLarge & uSmall) == uSmall; }
|
||||
static inline unsigned Ivy_CubeSharp( unsigned uCube, unsigned uPart ) { return uCube & ~uPart; }
|
||||
static inline unsigned Ivy_CubeMask( int nVar ) { return (~(unsigned)0) >> (32-nVar); }
|
||||
|
||||
static inline int Ivy_CubeIsMarked( unsigned uCube ) { return Ivy_CubeHasLit( uCube, 31 ); }
|
||||
static inline void Ivy_CubeMark( unsigned uCube ) { Ivy_CubeSetLit( uCube, 31 ); }
|
||||
static inline void Ivy_CubeUnmark( unsigned uCube ) { Ivy_CubeRemLit( uCube, 31 ); }
|
||||
|
||||
static inline int Ivy_SopCubeNum( Ivy_Sop_t * cSop ) { return cSop->nCubes; }
|
||||
static inline unsigned Ivy_SopCube( Ivy_Sop_t * cSop, int i ) { return cSop->uCubes[i]; }
|
||||
static inline void Ivy_SopAddCube( Ivy_Sop_t * cSop, unsigned uCube ) { cSop->uCubes[cSop->nCubes++] = uCube; }
|
||||
static inline void Ivy_SopSetCube( Ivy_Sop_t * cSop, unsigned uCube, int i ) { cSop->uCubes[i] = uCube; }
|
||||
static inline void Ivy_SopShrink( Ivy_Sop_t * cSop, int nCubesNew ) { cSop->nCubes = nCubesNew; }
|
||||
|
||||
// iterators
|
||||
#define Ivy_SopForEachCube( cSop, uCube, i ) \
|
||||
for ( i = 0; (i < Ivy_SopCubeNum(cSop)) && ((uCube) = Ivy_SopCube(cSop, i)); i++ )
|
||||
#define Ivy_CubeForEachLiteral( uCube, Lit, nLits, i ) \
|
||||
for ( i = 0; (i < (nLits)) && ((Lit) = Ivy_CubeHasLit(uCube, i)); i++ )
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Divides cover by one cube.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_SopDivideByCube( Vec_Int_t * vStore, int nVars, Ivy_Sop_t * cSop, Ivy_Sop_t * cDiv, Ivy_Sop_t * vQuo, Ivy_Sop_t * vRem )
|
||||
{
|
||||
unsigned uCube, uDiv;
|
||||
int i;
|
||||
// get the only cube
|
||||
assert( Ivy_SopCubeNum(cDiv) == 1 );
|
||||
uDiv = Ivy_SopCube(cDiv, 0);
|
||||
// allocate covers
|
||||
vQuo->nCubes = 0;
|
||||
vQuo->uCubes = Vec_IntFetch( vStore, Ivy_SopCubeNum(cSop) );
|
||||
vRem->nCubes = 0;
|
||||
vRem->uCubes = Vec_IntFetch( vStore, Ivy_SopCubeNum(cSop) );
|
||||
// sort the cubes
|
||||
Ivy_SopForEachCube( cSop, uCube, i )
|
||||
{
|
||||
if ( Ivy_CubeContains( uCube, uDiv ) )
|
||||
Ivy_SopAddCube( vQuo, Ivy_CubeSharp(uCube, uDiv) );
|
||||
else
|
||||
Ivy_SopAddCube( vRem, uCube );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Divides cover by one cube.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_SopDivideInternal( Vec_Int_t * vStore, int nVars, Ivy_Sop_t * cSop, Ivy_Sop_t * cDiv, Ivy_Sop_t * vQuo, Ivy_Sop_t * vRem )
|
||||
{
|
||||
unsigned uCube, uCube2, uDiv, uDiv2, uQuo;
|
||||
int i, i2, k, k2;
|
||||
assert( Ivy_SopCubeNum(cSop) >= Ivy_SopCubeNum(cDiv) );
|
||||
if ( Ivy_SopCubeNum(cDiv) == 1 )
|
||||
{
|
||||
Ivy_SopDivideByCube( cSop, cDiv, vQuo, vRem );
|
||||
return;
|
||||
}
|
||||
// allocate quotient
|
||||
vQuo->nCubes = 0;
|
||||
vQuo->uCubes = Vec_IntFetch( vStore, Ivy_SopCubeNum(cSop) / Ivy_SopCubeNum(cDiv) );
|
||||
// for each cube of the cover
|
||||
// it either belongs to the quotient or to the remainder
|
||||
Ivy_SopForEachCube( cSop, uCube, i )
|
||||
{
|
||||
// skip taken cubes
|
||||
if ( Ivy_CubeIsMarked(uCube) )
|
||||
continue;
|
||||
// mark the cube
|
||||
Ivy_SopSetCube( cSop, Ivy_CubeMark(uCube), i );
|
||||
// find a matching cube in the divisor
|
||||
Ivy_SopForEachCube( cDiv, uDiv, k )
|
||||
if ( Ivy_CubeContains( uCube, uDiv ) )
|
||||
break;
|
||||
// the case when the cube is not found
|
||||
// (later we will add marked cubes to the remainder)
|
||||
if ( k == Ivy_SopCubeNum(cDiv) )
|
||||
continue;
|
||||
// if the quotient cube exist, it will be
|
||||
uQuo = Ivy_CubeSharp( uCube, uDiv );
|
||||
// try to find other cubes of the divisor
|
||||
Ivy_SopForEachCube( cDiv, uDiv2, k2 )
|
||||
{
|
||||
if ( k2 == k )
|
||||
continue;
|
||||
// find a matching cube
|
||||
Ivy_SopForEachCube( cSop, uCube2, i2 )
|
||||
{
|
||||
// skip taken cubes
|
||||
if ( Ivy_CubeIsMarked(uCube2) )
|
||||
continue;
|
||||
// check if the cube can be used
|
||||
if ( Ivy_CubeContains( uCube2, uDiv2 ) && uQuo == Ivy_CubeSharp( uCube2, uDiv2 ) )
|
||||
break;
|
||||
}
|
||||
// the case when the cube is not found
|
||||
if ( i2 == Ivy_SopCubeNum(cSop) )
|
||||
break;
|
||||
// the case when the cube is found - mark it and keep going
|
||||
Ivy_SopSetCube( cSop, Ivy_CubeMark(uCube2), i2 );
|
||||
}
|
||||
// if we did not find some cube, continue
|
||||
// (later we will add marked cubes to the remainder)
|
||||
if ( k2 != Ivy_SopCubeNum(cDiv) )
|
||||
continue;
|
||||
// we found all cubes - add the quotient cube
|
||||
Ivy_SopAddCube( vQuo, uQuo );
|
||||
}
|
||||
// allocate remainder
|
||||
vRem->nCubes = 0;
|
||||
vRem->uCubes = Vec_IntFetch( vStore, Ivy_SopCubeNum(cSop) - Ivy_SopCubeNum(vQuo) * Ivy_SopCubeNum(cDiv) );
|
||||
// finally add the remaining cubes to the remainder
|
||||
// and clean the marked cubes in the cover
|
||||
Ivy_SopForEachCube( cSop, uCube, i )
|
||||
{
|
||||
if ( !Ivy_CubeIsMarked(uCube) )
|
||||
continue;
|
||||
Ivy_SopSetCube( cSop, Ivy_CubeUnmark(uCube), i );
|
||||
Ivy_SopAddCube( vRem, Ivy_CubeUnmark(uCube) );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives the quotient of division by literal.]
|
||||
|
||||
Description [Reduces the cover to be the equal to the result of
|
||||
division of the given cover by the literal.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_SopDivideByLiteralQuo( Ivy_Sop_t * cSop, int iLit )
|
||||
{
|
||||
unsigned uCube;
|
||||
int i, k = 0;
|
||||
Ivy_SopForEachCube( cSop, uCube, i )
|
||||
{
|
||||
if ( Ivy_CubeHasLit(uCube, iLit) )
|
||||
Ivy_SopSetCube( cSop, Ivy_CubeRemLit(uCube, iLit), k++ );
|
||||
}
|
||||
Ivy_SopShrink( cSop, k );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_SopCommonCubeCover( Ivy_Sop_t * cSop, Ivy_Sop_t * vCommon, Vec_Int_t * vStore )
|
||||
{
|
||||
unsigned uTemp, uCube;
|
||||
int i;
|
||||
uCube = ~(unsigned)0;
|
||||
Ivy_SopForEachCube( cSop, uTemp, i )
|
||||
uCube &= uTemp;
|
||||
vCommon->nCubes = 0;
|
||||
vCommon->uCubes = Vec_IntFetch( vStore, 1 );
|
||||
Ivy_SopPush( vCommon, uCube );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_SopCreateInverse( Ivy_Sop_t * cSop, Vec_Int_t * vInput, int nVars, Vec_Int_t * vStore )
|
||||
{
|
||||
unsigned uCube, uMask;
|
||||
int i;
|
||||
// start the cover
|
||||
cSop->nCubes = 0;
|
||||
cSop->uCubes = Vec_IntFetch( vStore, Vec_IntSize(vInput) );
|
||||
// add the cubes
|
||||
uMask = Ivy_CubeMask( nVars );
|
||||
Vec_IntForEachEntry( vInput, uCube, i )
|
||||
Vec_IntPush( cSop, Ivy_CubeSharp(uMask, uCube) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_SopDup( Ivy_Sop_t * cSop, Ivy_Sop_t * vCopy, Vec_Int_t * vStore )
|
||||
{
|
||||
unsigned uCube;
|
||||
int i;
|
||||
// start the cover
|
||||
vCopy->nCubes = 0;
|
||||
vCopy->uCubes = Vec_IntFetch( vStore, Vec_IntSize(cSop) );
|
||||
// add the cubes
|
||||
Ivy_SopForEachCube( cSop, uTemp, i )
|
||||
Ivy_SopPush( vCopy, uTemp );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find the least often occurring literal.]
|
||||
|
||||
Description [Find the least often occurring literal among those
|
||||
that occur more than once.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_SopWorstLiteral( Ivy_Sop_t * cSop, int nLits )
|
||||
{
|
||||
unsigned uCube;
|
||||
int nWord, nBit;
|
||||
int i, k, iMin, nLitsMin, nLitsCur;
|
||||
int fUseFirst = 1;
|
||||
|
||||
// go through each literal
|
||||
iMin = -1;
|
||||
nLitsMin = 1000000;
|
||||
for ( i = 0; i < nLits; i++ )
|
||||
{
|
||||
// go through all the cubes
|
||||
nLitsCur = 0;
|
||||
Ivy_SopForEachCube( cSop, uCube, k )
|
||||
if ( Ivy_CubeHasLit(uCube, i) )
|
||||
nLitsCur++;
|
||||
// skip the literal that does not occur or occurs once
|
||||
if ( nLitsCur < 2 )
|
||||
continue;
|
||||
// check if this is the best literal
|
||||
if ( fUseFirst )
|
||||
{
|
||||
if ( nLitsMin > nLitsCur )
|
||||
{
|
||||
nLitsMin = nLitsCur;
|
||||
iMin = i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( nLitsMin >= nLitsCur )
|
||||
{
|
||||
nLitsMin = nLitsCur;
|
||||
iMin = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( nLitsMin < 1000000 )
|
||||
return iMin;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes a level-zero kernel.]
|
||||
|
||||
Description [Modifies the cover to contain one level-zero kernel.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_SopMakeCubeFree( Ivy_Sop_t * cSop )
|
||||
{
|
||||
unsigned uMask;
|
||||
int i;
|
||||
assert( Ivy_SopCubeNum(cSop) > 0 );
|
||||
// find the common cube
|
||||
uMask = ~(unsigned)0;
|
||||
Ivy_SopForEachCube( cSop, uCube, i )
|
||||
uMask &= uCube;
|
||||
if ( uMask == 0 )
|
||||
return;
|
||||
// remove the common cube
|
||||
Ivy_SopForEachCube( cSop, uCube, i )
|
||||
Ivy_SopSetCube( cSop, Ivy_CubeSharp(uCube, uMask), i );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes a level-zero kernel.]
|
||||
|
||||
Description [Modifies the cover to contain one level-zero kernel.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_SopDivisorZeroKernel_rec( Ivy_Sop_t * cSop, int nLits )
|
||||
{
|
||||
int iLit;
|
||||
// find any literal that occurs at least two times
|
||||
iLit = Ivy_SopWorstLiteral( cSop, nLits );
|
||||
if ( iLit == -1 )
|
||||
return;
|
||||
// derive the cube-free quotient
|
||||
Ivy_SopDivideByLiteralQuo( cSop, iLit ); // the same cover
|
||||
Ivy_SopMakeCubeFree( cSop ); // the same cover
|
||||
// call recursively
|
||||
Ivy_SopDivisorZeroKernel_rec( cSop ); // the same cover
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the quick divisor of the cover.]
|
||||
|
||||
Description [Returns NULL, if there is not divisor other than
|
||||
trivial.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_SopDivisor( Ivy_Sop_t * cSop, int nLits, Ivy_Sop_t * cDiv, Vec_Int_t * vStore )
|
||||
{
|
||||
if ( Ivy_SopCubeNum(cSop) <= 1 )
|
||||
return 0;
|
||||
if ( Ivy_SopWorstLiteral( cSop, nLits ) == -1 )
|
||||
return 0;
|
||||
// duplicate the cover
|
||||
Ivy_SopDup( cSop, cDiv, vStore );
|
||||
// perform the kerneling
|
||||
Ivy_SopDivisorZeroKernel_rec( cDiv, int nLits );
|
||||
assert( Ivy_SopCubeNum(cDiv) > 0 );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
extern Dec_Edge_t Dec_Factor32_rec( Dec_Graph_t * pFForm, Vec_Int_t * cSop, int nVars );
|
||||
extern Dec_Edge_t Dec_Factor32LF_rec( Dec_Graph_t * pFForm, Vec_Int_t * cSop, int nVars, Vec_Int_t * vSimple );
|
||||
extern Dec_Edge_t Dec_Factor32Trivial( Dec_Graph_t * pFForm, Vec_Int_t * cSop, int nVars );
|
||||
extern Dec_Edge_t Dec_Factor32TrivialCube( Dec_Graph_t * pFForm, Vec_Int_t * cSop, int nVars, unsigned uCube, Vec_Int_t * vEdgeLits );
|
||||
extern Dec_Edge_t Dec_Factor32TrivialTree_rec( Dec_Graph_t * pFForm, Dec_Edge_t * peNodes, int nNodes, int fNodeOr );
|
||||
extern int Dec_Factor32Verify( Vec_Int_t * cSop, Dec_Graph_t * pFForm )
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Factors the cover.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Dec_Graph_t * Dec_Factor32( Vec_Int_t * cSop, int nVars, Vec_Int_t * vStore )
|
||||
{
|
||||
Ivy_Sop_t cSop, cRes;
|
||||
Ivy_Sop_t * pcSop = &cSop, * pcRes = &cRes;
|
||||
Dec_Graph_t * pFForm;
|
||||
Dec_Edge_t eRoot;
|
||||
|
||||
assert( nVars < 16 );
|
||||
|
||||
// check for trivial functions
|
||||
if ( Vec_IntSize(cSop) == 0 )
|
||||
return Dec_GraphCreateConst0();
|
||||
if ( Vec_IntSize(cSop) == 1 && Vec_IntEntry(cSop, 0) == Ivy_CubeMask(nVars) )
|
||||
return Dec_GraphCreateConst1();
|
||||
|
||||
// prepare memory manager
|
||||
Vec_IntClear( vStore );
|
||||
Vec_IntGrow( vStore, IVY_FACTOR_MEM_LIMIT );
|
||||
|
||||
// perform CST
|
||||
Ivy_SopCreateInverse( cSop, pcSop, nVars, vStore ); // CST
|
||||
|
||||
// start the factored form
|
||||
pFForm = Dec_GraphCreate( nVars );
|
||||
// factor the cover
|
||||
eRoot = Dec_Factor32_rec( pFForm, cSop, 2 * nVars );
|
||||
// finalize the factored form
|
||||
Dec_GraphSetRoot( pFForm, eRoot );
|
||||
|
||||
// verify the factored form
|
||||
if ( !Dec_Factor32Verify( pSop, pFForm, nVars ) )
|
||||
printf( "Verification has failed.\n" );
|
||||
return pFForm;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Internal recursive factoring procedure.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Dec_Edge_t Dec_Factor32_rec( Dec_Graph_t * pFForm, Vec_Int_t * cSop, int nLits )
|
||||
{
|
||||
Vec_Int_t * cDiv, * vQuo, * vRem, * vCom;
|
||||
Dec_Edge_t eNodeDiv, eNodeQuo, eNodeRem;
|
||||
Dec_Edge_t eNodeAnd, eNode;
|
||||
|
||||
// make sure the cover contains some cubes
|
||||
assert( Vec_IntSize(cSop) );
|
||||
|
||||
// get the divisor
|
||||
cDiv = Ivy_SopDivisor( cSop, nLits );
|
||||
if ( cDiv == NULL )
|
||||
return Dec_Factor32Trivial( pFForm, cSop, nLits );
|
||||
|
||||
// divide the cover by the divisor
|
||||
Ivy_SopDivideInternal( cSop, nLits, cDiv, &vQuo, &vRem );
|
||||
assert( Vec_IntSize(vQuo) );
|
||||
|
||||
Vec_IntFree( cDiv );
|
||||
Vec_IntFree( vRem );
|
||||
|
||||
// check the trivial case
|
||||
if ( Vec_IntSize(vQuo) == 1 )
|
||||
{
|
||||
eNode = Dec_Factor32LF_rec( pFForm, cSop, nLits, vQuo );
|
||||
Vec_IntFree( vQuo );
|
||||
return eNode;
|
||||
}
|
||||
|
||||
// make the quotient cube free
|
||||
Ivy_SopMakeCubeFree( vQuo );
|
||||
|
||||
// divide the cover by the quotient
|
||||
Ivy_SopDivideInternal( cSop, nLits, vQuo, &cDiv, &vRem );
|
||||
|
||||
// check the trivial case
|
||||
if ( Ivy_SopIsCubeFree( cDiv ) )
|
||||
{
|
||||
eNodeDiv = Dec_Factor32_rec( pFForm, cDiv );
|
||||
eNodeQuo = Dec_Factor32_rec( pFForm, vQuo );
|
||||
Vec_IntFree( cDiv );
|
||||
Vec_IntFree( vQuo );
|
||||
eNodeAnd = Dec_GraphAddNodeAnd( pFForm, eNodeDiv, eNodeQuo );
|
||||
if ( Vec_IntSize(vRem) == 0 )
|
||||
{
|
||||
Vec_IntFree( vRem );
|
||||
return eNodeAnd;
|
||||
}
|
||||
else
|
||||
{
|
||||
eNodeRem = Dec_Factor32_rec( pFForm, vRem );
|
||||
Vec_IntFree( vRem );
|
||||
return Dec_GraphAddNodeOr( pFForm, eNodeAnd, eNodeRem );
|
||||
}
|
||||
}
|
||||
|
||||
// get the common cube
|
||||
vCom = Ivy_SopCommonCubeCover( cDiv );
|
||||
Vec_IntFree( cDiv );
|
||||
Vec_IntFree( vQuo );
|
||||
Vec_IntFree( vRem );
|
||||
|
||||
// solve the simple problem
|
||||
eNode = Dec_Factor32LF_rec( pFForm, cSop, nLits, vCom );
|
||||
Vec_IntFree( vCom );
|
||||
return eNode;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Internal recursive factoring procedure for the leaf case.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Dec_Edge_t Dec_Factor32LF_rec( Dec_Graph_t * pFForm, Vec_Int_t * cSop, int nLits, Vec_Int_t * vSimple )
|
||||
{
|
||||
Dec_Man_t * pManDec = Abc_FrameReadManDec();
|
||||
Vec_Int_t * vEdgeLits = pManDec->vLits;
|
||||
Vec_Int_t * cDiv, * vQuo, * vRem;
|
||||
Dec_Edge_t eNodeDiv, eNodeQuo, eNodeRem;
|
||||
Dec_Edge_t eNodeAnd;
|
||||
|
||||
// get the most often occurring literal
|
||||
cDiv = Ivy_SopBestLiteralCover( cSop, nLits, vSimple );
|
||||
// divide the cover by the literal
|
||||
Ivy_SopDivideByLiteral( cSop, nLits, cDiv, &vQuo, &vRem );
|
||||
// get the node pointer for the literal
|
||||
eNodeDiv = Dec_Factor32TrivialCube( pFForm, cDiv, Ivy_SopReadCubeHead(cDiv), vEdgeLits );
|
||||
Vec_IntFree( cDiv );
|
||||
// factor the quotient and remainder
|
||||
eNodeQuo = Dec_Factor32_rec( pFForm, vQuo );
|
||||
Vec_IntFree( vQuo );
|
||||
eNodeAnd = Dec_GraphAddNodeAnd( pFForm, eNodeDiv, eNodeQuo );
|
||||
if ( Vec_IntSize(vRem) == 0 )
|
||||
{
|
||||
Vec_IntFree( vRem );
|
||||
return eNodeAnd;
|
||||
}
|
||||
else
|
||||
{
|
||||
eNodeRem = Dec_Factor32_rec( pFForm, vRem );
|
||||
Vec_IntFree( vRem );
|
||||
return Dec_GraphAddNodeOr( pFForm, eNodeAnd, eNodeRem );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Factoring the cover, which has no algebraic divisors.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Dec_Edge_t Dec_Factor32Trivial( Dec_Graph_t * pFForm, Vec_Int_t * cSop, int nLits )
|
||||
{
|
||||
Dec_Man_t * pManDec = Abc_FrameReadManDec();
|
||||
Vec_Int_t * vEdgeCubes = pManDec->vCubes;
|
||||
Vec_Int_t * vEdgeLits = pManDec->vLits;
|
||||
Mvc_Manager_t * pMem = pManDec->pMvcMem;
|
||||
Dec_Edge_t eNode;
|
||||
unsigned uCube;
|
||||
int i;
|
||||
// create the factored form for each cube
|
||||
Vec_IntClear( vEdgeCubes );
|
||||
Ivy_SopForEachCube( cSop, uCube )
|
||||
{
|
||||
eNode = Dec_Factor32TrivialCube( pFForm, cSop, nLits, uCube, vEdgeLits );
|
||||
Vec_IntPush( vEdgeCubes, Dec_EdgeToInt_(eNode) );
|
||||
}
|
||||
// balance the factored forms
|
||||
return Dec_Factor32TrivialTree_rec( pFForm, (Dec_Edge_t *)vEdgeCubes->pArray, vEdgeCubes->nSize, 1 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Factoring the cube.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Dec_Edge_t Dec_Factor32TrivialCube( Dec_Graph_t * pFForm, Vec_Int_t * cSop, unsigned uCube, int nLits, Vec_Int_t * vEdgeLits )
|
||||
{
|
||||
Dec_Edge_t eNode;
|
||||
int iBit, Value;
|
||||
// create the factored form for each literal
|
||||
Vec_IntClear( vEdgeLits );
|
||||
Mvc_CubeForEachLit( cSop, uCube, iBit, Value )
|
||||
if ( Value )
|
||||
{
|
||||
eNode = Dec_EdgeCreate( iBit/2, iBit%2 ); // CST
|
||||
Vec_IntPush( vEdgeLits, Dec_EdgeToInt_(eNode) );
|
||||
}
|
||||
// balance the factored forms
|
||||
return Dec_Factor32TrivialTree_rec( pFForm, (Dec_Edge_t *)vEdgeLits->pArray, vEdgeLits->nSize, 0 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Create the well-balanced tree of nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Dec_Edge_t Dec_Factor32TrivialTree_rec( Dec_Graph_t * pFForm, Dec_Edge_t * peNodes, int nNodes, int fNodeOr )
|
||||
{
|
||||
Dec_Edge_t eNode1, eNode2;
|
||||
int nNodes1, nNodes2;
|
||||
|
||||
if ( nNodes == 1 )
|
||||
return peNodes[0];
|
||||
|
||||
// split the nodes into two parts
|
||||
nNodes1 = nNodes/2;
|
||||
nNodes2 = nNodes - nNodes1;
|
||||
// nNodes2 = nNodes/2;
|
||||
// nNodes1 = nNodes - nNodes2;
|
||||
|
||||
// recursively construct the tree for the parts
|
||||
eNode1 = Dec_Factor32TrivialTree_rec( pFForm, peNodes, nNodes1, fNodeOr );
|
||||
eNode2 = Dec_Factor32TrivialTree_rec( pFForm, peNodes + nNodes1, nNodes2, fNodeOr );
|
||||
|
||||
if ( fNodeOr )
|
||||
return Dec_GraphAddNodeOr( pFForm, eNode1, eNode2 );
|
||||
else
|
||||
return Dec_GraphAddNodeAnd( pFForm, eNode1, eNode2 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// verification using temporary BDD package
|
||||
#include "cuddInt.h"
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Verifies that the factoring is correct.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
DdNode * Ivy_SopCoverToBdd( DdManager * dd, Vec_Int_t * cSop, int nVars )
|
||||
{
|
||||
DdNode * bSum, * bCube, * bTemp, * bVar;
|
||||
unsigned uCube;
|
||||
int Value, v;
|
||||
assert( nVars < 16 );
|
||||
// start the cover
|
||||
bSum = Cudd_ReadLogicZero(dd); Cudd_Ref( bSum );
|
||||
// check the logic function of the node
|
||||
Vec_IntForEachEntry( cSop, uCube, i )
|
||||
{
|
||||
bCube = Cudd_ReadOne(dd); Cudd_Ref( bCube );
|
||||
for ( v = 0; v < nVars; v++ )
|
||||
{
|
||||
Value = ((uCube >> 2*v) & 3);
|
||||
if ( Value == 1 )
|
||||
bVar = Cudd_Not( Cudd_bddIthVar( dd, v ) );
|
||||
else if ( Value == 2 )
|
||||
bVar = Cudd_bddIthVar( dd, v );
|
||||
else
|
||||
continue;
|
||||
bCube = Cudd_bddAnd( dd, bTemp = bCube, bVar ); Cudd_Ref( bCube );
|
||||
Cudd_RecursiveDeref( dd, bTemp );
|
||||
}
|
||||
bSum = Cudd_bddOr( dd, bTemp = bSum, bCube );
|
||||
Cudd_Ref( bSum );
|
||||
Cudd_RecursiveDeref( dd, bTemp );
|
||||
Cudd_RecursiveDeref( dd, bCube );
|
||||
}
|
||||
// complement the result if necessary
|
||||
Cudd_Deref( bSum );
|
||||
return bSum;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Verifies that the factoring is correct.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Dec_Factor32Verify( Vec_Int_t * cSop, Dec_Graph_t * pFForm, int nVars )
|
||||
{
|
||||
static DdManager * dd = NULL;
|
||||
DdNode * bFunc1, * bFunc2;
|
||||
int RetValue;
|
||||
// get the manager
|
||||
if ( dd == NULL )
|
||||
dd = Cudd_Init( 16, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
|
||||
// get the functions
|
||||
bFunc1 = Ivy_SopCoverToBdd( dd, cSop, nVars ); Cudd_Ref( bFunc1 );
|
||||
bFunc2 = Dec_GraphDeriveBdd( dd, pFForm ); Cudd_Ref( bFunc2 );
|
||||
//Extra_bddPrint( dd, bFunc1 ); printf("\n");
|
||||
//Extra_bddPrint( dd, bFunc2 ); printf("\n");
|
||||
RetValue = (bFunc1 == bFunc2);
|
||||
if ( bFunc1 != bFunc2 )
|
||||
{
|
||||
int s;
|
||||
Extra_bddPrint( dd, bFunc1 ); printf("\n");
|
||||
Extra_bddPrint( dd, bFunc2 ); printf("\n");
|
||||
s = 0;
|
||||
}
|
||||
Cudd_RecursiveDeref( dd, bFunc1 );
|
||||
Cudd_RecursiveDeref( dd, bFunc2 );
|
||||
return RetValue;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -1,378 +0,0 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [ivyFpga.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [And-Inverter Graph package.]
|
||||
|
||||
Synopsis [Prepares the AIG package to work as an FPGA mapper.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 11, 2006.]
|
||||
|
||||
Revision [$Id: ivyFpga.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "ivy.h"
|
||||
#include "attr.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Ivy_FpgaMan_t_ Ivy_FpgaMan_t;
|
||||
typedef struct Ivy_FpgaObj_t_ Ivy_FpgaObj_t;
|
||||
typedef struct Ivy_FpgaCut_t_ Ivy_FpgaCut_t;
|
||||
|
||||
// manager
|
||||
struct Ivy_FpgaMan_t_
|
||||
{
|
||||
Ivy_Man_t * pManIvy; // the AIG manager
|
||||
Attr_Man_t * pManAttr; // the attribute manager
|
||||
int nLutSize; // the LUT size
|
||||
int nCutsMax; // the max number of cuts
|
||||
int nEntrySize; // the size of the entry
|
||||
int nEntryBase; // the size of the entry minus cut leaf arrays
|
||||
int fVerbose; // the verbosity flag
|
||||
// temporary cut storage
|
||||
Ivy_FpgaCut_t * pCutStore; // the temporary cuts
|
||||
};
|
||||
|
||||
// priority cut
|
||||
struct Ivy_FpgaCut_t_
|
||||
{
|
||||
float Delay; // the delay of the cut
|
||||
float AreaFlow; // the area flow of the cut
|
||||
float Area; // the area of the cut
|
||||
int nLeaves; // the number of leaves
|
||||
int * pLeaves; // the array of fanins
|
||||
};
|
||||
|
||||
// node extension
|
||||
struct Ivy_FpgaObj_t_
|
||||
{
|
||||
unsigned Type : 4; // type
|
||||
unsigned nCuts : 28; // the number of cuts
|
||||
int Id; // integer ID
|
||||
int nRefs; // the number of references
|
||||
Ivy_FpgaObj_t * pFanin0; // the first fanin
|
||||
Ivy_FpgaObj_t * pFanin1; // the second fanin
|
||||
float Required; // required time of the onde
|
||||
Ivy_FpgaCut_t * pCut; // the best cut
|
||||
Ivy_FpgaCut_t Cuts[0]; // the cuts of the node
|
||||
};
|
||||
|
||||
|
||||
static Ivy_FpgaMan_t * Ivy_ManFpgaPrepare( Ivy_Man_t * p, int nLutSize, int nCutsMax, int fVerbose );
|
||||
static void Ivy_ManFpgaUndo( Ivy_FpgaMan_t * pFpga );
|
||||
static void Ivy_ObjFpgaCreate( Ivy_FpgaMan_t * pFpga, int ObjId );
|
||||
static void Ivy_ManFpgaDelay( Ivy_FpgaMan_t * pFpga );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs FPGA mapping.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ManFpga( Ivy_Man_t * p, int nLutSize, int nCutsMax, int fVerbose )
|
||||
{
|
||||
Ivy_FpgaMan_t * pFpga;
|
||||
pFpga = Ivy_ManFpgaPrepare( p, nLutSize, nCutsMax, fVerbose );
|
||||
Ivy_ManFpgaDelay( pFpga );
|
||||
Ivy_ManFpgaUndo( pFpga );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prepares manager for FPGA mapping.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Ivy_FpgaMan_t * Ivy_ManFpgaPrepare( Ivy_Man_t * p, int nLutSize, int nCutsMax, int fVerbose )
|
||||
{
|
||||
Ivy_FpgaMan_t * pFpga;
|
||||
Ivy_Obj_t * pObj;
|
||||
int i;
|
||||
pFpga = ALLOC( Ivy_FpgaMan_t, 1 );
|
||||
memset( pFpga, 0, sizeof(Ivy_FpgaMan_t) );
|
||||
// compute the size of the node
|
||||
pFpga->pManIvy = p;
|
||||
pFpga->nLutSize = nLutSize;
|
||||
pFpga->nCutsMax = nCutsMax;
|
||||
pFpga->fVerbose = fVerbose;
|
||||
pFpga->nEntrySize = sizeof(Ivy_FpgaObj_t) + (nCutsMax + 1) * (sizeof(Ivy_FpgaCut_t) + sizeof(int) * nLutSize);
|
||||
pFpga->nEntryBase = sizeof(Ivy_FpgaObj_t) + (nCutsMax + 1) * (sizeof(Ivy_FpgaCut_t));
|
||||
pFpga->pManAttr = Attr_ManStartPtrMem( Ivy_ManObjIdMax(p) + 1, pFpga->nEntrySize );
|
||||
if ( fVerbose )
|
||||
printf( "Entry size = %d. Total memory = %5.2f Mb.\n", pFpga->nEntrySize,
|
||||
1.0 * pFpga->nEntrySize * (Ivy_ManObjIdMax(p) + 1) / (1<<20) );
|
||||
// connect memory for cuts
|
||||
Ivy_ManForEachObj( p, pObj, i )
|
||||
Ivy_ObjFpgaCreate( pFpga, pObj->Id );
|
||||
// create temporary cuts
|
||||
pFpga->pCutStore = (Ivy_FpgaCut_t *)ALLOC( char, pFpga->nEntrySize * (nCutsMax + 1) * (nCutsMax + 1) );
|
||||
memset( pFpga->pCutStore, 0, pFpga->nEntrySize * (nCutsMax + 1) * (nCutsMax + 1) );
|
||||
{
|
||||
int i, * pArrays;
|
||||
pArrays = (int *)((char *)pFpga->pCutStore + sizeof(Ivy_FpgaCut_t) * (nCutsMax + 1) * (nCutsMax + 1));
|
||||
for ( i = 0; i < (nCutsMax + 1) * (nCutsMax + 1); i++ )
|
||||
pFpga->pCutStore[i].pLeaves = pArrays + i * pFpga->nLutSize;
|
||||
}
|
||||
return pFpga;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Quits the manager for FPGA mapping.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ManFpgaUndo( Ivy_FpgaMan_t * pFpga )
|
||||
{
|
||||
Attr_ManStop( pFpga->pManAttr );
|
||||
free( pFpga );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prepares the object for FPGA mapping.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ObjFpgaCreate( Ivy_FpgaMan_t * pFpga, int ObjId )
|
||||
{
|
||||
Ivy_FpgaObj_t * pObjFpga;
|
||||
int i, * pArrays;
|
||||
pObjFpga = Attr_ManReadAttrPtr( pFpga->pManAttr, ObjId );
|
||||
pArrays = (int *)((char *)pObjFpga + pFpga->nEntryBase);
|
||||
for ( i = 0; i <= pFpga->nCutsMax; i++ )
|
||||
pObjFpga->Cuts[i].pLeaves = pArrays + i * pFpga->nLutSize;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prepares the object for FPGA mapping.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_ObjFpgaMerge( Ivy_FpgaCut_t * pC0, Ivy_FpgaCut_t * pC1, Ivy_FpgaCut_t * pC, int nLimit )
|
||||
{
|
||||
int i, k, c;
|
||||
assert( pC0->nLeaves >= pC1->nLeaves );
|
||||
// the case of the largest cut sizes
|
||||
if ( pC0->nLeaves == nLimit && pC1->nLeaves == nLimit )
|
||||
{
|
||||
for ( i = 0; i < pC0->nLeaves; i++ )
|
||||
if ( pC0->pLeaves[i] != pC1->pLeaves[i] )
|
||||
return 0;
|
||||
for ( i = 0; i < pC0->nLeaves; i++ )
|
||||
pC->pLeaves[i] = pC0->pLeaves[i];
|
||||
pC->nLeaves = pC0->nLeaves;
|
||||
pC->Delay = 1 + IVY_MAX( pC0->Delay, pC1->Delay );
|
||||
return 1;
|
||||
}
|
||||
// the case when one of the cuts is the largest
|
||||
if ( pC0->nLeaves == nLimit )
|
||||
{
|
||||
for ( i = 0; i < pC1->nLeaves; i++ )
|
||||
{
|
||||
for ( k = 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 < pC0->nLeaves; i++ )
|
||||
pC->pLeaves[i] = pC0->pLeaves[i];
|
||||
pC->nLeaves = pC0->nLeaves;
|
||||
pC->Delay = 1 + IVY_MAX( pC0->Delay, pC1->Delay );
|
||||
return 1;
|
||||
}
|
||||
|
||||
// compare two cuts with different numbers
|
||||
i = k = 0;
|
||||
for ( c = 0; c < nLimit; c++ )
|
||||
{
|
||||
if ( k == pC1->nLeaves )
|
||||
{
|
||||
if ( i == pC0->nLeaves )
|
||||
{
|
||||
pC->nLeaves = c;
|
||||
pC->Delay = 1 + IVY_MAX( pC0->Delay, pC1->Delay );
|
||||
return 1;
|
||||
}
|
||||
pC->pLeaves[c] = pC0->pLeaves[i++];
|
||||
continue;
|
||||
}
|
||||
if ( i == pC0->nLeaves )
|
||||
{
|
||||
if ( k == pC1->nLeaves )
|
||||
{
|
||||
pC->nLeaves = c;
|
||||
pC->Delay = 1 + IVY_MAX( pC0->Delay, pC1->Delay );
|
||||
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 < pC0->nLeaves || k < pC1->nLeaves )
|
||||
return 0;
|
||||
pC->nLeaves = c;
|
||||
pC->Delay = 1 + IVY_MAX( pC0->Delay, pC1->Delay );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prepares the object for FPGA mapping.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_FpgaCutCompare( Ivy_FpgaCut_t * pC0, Ivy_FpgaCut_t * pC1 )
|
||||
{
|
||||
if ( pC0->Delay < pC1->Delay )
|
||||
return -1;
|
||||
if ( pC0->Delay > pC1->Delay )
|
||||
return 1;
|
||||
if ( pC0->nLeaves < pC1->nLeaves )
|
||||
return -1;
|
||||
if ( pC0->nLeaves > pC1->nLeaves )
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prepares the object for FPGA mapping.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ObjFpgaDelay( Ivy_FpgaMan_t * pFpga, int ObjId, int Fan0Id, int Fan1Id )
|
||||
{
|
||||
Ivy_FpgaObj_t * pObjFpga, * pObjFpga0, * pObjFpga1;
|
||||
int nCuts, i, k;
|
||||
pObjFpga = Attr_ManReadAttrPtr( pFpga->pManAttr, ObjId );
|
||||
pObjFpga0 = Attr_ManReadAttrPtr( pFpga->pManAttr, Fan0Id );
|
||||
pObjFpga1 = Attr_ManReadAttrPtr( pFpga->pManAttr, Fan1Id );
|
||||
// create cross-product of the cuts
|
||||
nCuts = 0;
|
||||
for ( i = 0; pObjFpga0->Cuts[i].nLeaves > 0 && i < pFpga->nCutsMax; i++ )
|
||||
for ( k = 0; pObjFpga1->Cuts[k].nLeaves > 0 && k < pFpga->nCutsMax; k++ )
|
||||
if ( Ivy_ObjFpgaMerge( pObjFpga0->Cuts + i, pObjFpga1->Cuts + k, pFpga->pCutStore + nCuts, pFpga->nLutSize ) )
|
||||
nCuts++;
|
||||
// sort the cuts
|
||||
qsort( pFpga->pCutStore, nCuts, sizeof(Ivy_FpgaCut_t), (int (*)(const void *, const void *))Ivy_FpgaCutCompare );
|
||||
// take the first
|
||||
pObjFpga->Cuts[0].nLeaves = 1;
|
||||
pObjFpga->Cuts[0].pLeaves[0] = ObjId;
|
||||
pObjFpga->Cuts[0].Delay = pFpga->pCutStore[0].Delay;
|
||||
pObjFpga->Cuts[1] = pFpga->pCutStore[0];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Maps the nodes for delay.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Ivy_ManFpgaDelay( Ivy_FpgaMan_t * pFpga )
|
||||
{
|
||||
Ivy_FpgaObj_t * pObjFpga;
|
||||
Ivy_Obj_t * pObj;
|
||||
int i, DelayBest;
|
||||
int clk = clock();
|
||||
// set arrival times and trivial cuts at const 1 and PIs
|
||||
pObjFpga = Attr_ManReadAttrPtr( pFpga->pManAttr, 0 );
|
||||
pObjFpga->Cuts[0].nLeaves = 1;
|
||||
Ivy_ManForEachPi( pFpga->pManIvy, pObj, i )
|
||||
{
|
||||
pObjFpga = Attr_ManReadAttrPtr( pFpga->pManAttr, pObj->Id );
|
||||
pObjFpga->Cuts[0].nLeaves = 1;
|
||||
pObjFpga->Cuts[0].pLeaves[0] = pObj->Id;
|
||||
}
|
||||
// map the internal nodes
|
||||
Ivy_ManForEachNode( pFpga->pManIvy, pObj, i )
|
||||
{
|
||||
Ivy_ObjFpgaDelay( pFpga, pObj->Id, Ivy_ObjFaninId0(pObj), Ivy_ObjFaninId1(pObj) );
|
||||
}
|
||||
// get the best arrival time of the POs
|
||||
DelayBest = 0;
|
||||
Ivy_ManForEachPo( pFpga->pManIvy, pObj, i )
|
||||
{
|
||||
pObjFpga = Attr_ManReadAttrPtr( pFpga->pManAttr, Ivy_ObjFanin0(pObj)->Id );
|
||||
if ( DelayBest < (int)pObjFpga->Cuts[1].Delay )
|
||||
DelayBest = (int)pObjFpga->Cuts[1].Delay;
|
||||
}
|
||||
printf( "Best delay = %d. ", DelayBest );
|
||||
PRT( "Time", clock() - clk );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -9,7 +9,6 @@ SRC += src/aig/ivy/ivyBalance.c \
|
|||
src/aig/ivy/ivyFastMap.c \
|
||||
src/aig/ivy/ivyFraig.c \
|
||||
src/aig/ivy/ivyHaig.c \
|
||||
src/aig/ivy/ivyIsop.c \
|
||||
src/aig/ivy/ivyMan.c \
|
||||
src/aig/ivy/ivyMem.c \
|
||||
src/aig/ivy/ivyMulti.c \
|
||||
|
|
|
|||
|
|
@ -427,9 +427,9 @@ char * Abc_SopCreateFromIsop( Extra_MmFlex_t * pMan, int nVars, Vec_Int_t * vCov
|
|||
{
|
||||
Literal = 3 & (Entry >> (k << 1));
|
||||
if ( Literal == 1 )
|
||||
pCube[k] = '1';
|
||||
else if ( Literal == 2 )
|
||||
pCube[k] = '0';
|
||||
else if ( Literal == 2 )
|
||||
pCube[k] = '1';
|
||||
else if ( Literal != 0 )
|
||||
assert( 0 );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2034,25 +2034,28 @@ int Abc_CommandRenode( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
{
|
||||
FILE * pOut, * pErr;
|
||||
Abc_Ntk_t * pNtk, * pNtkRes;
|
||||
int nFaninMax, c;
|
||||
int nFaninMax, nCubeMax, c;
|
||||
int fUseBdds;
|
||||
int fUseSops;
|
||||
int fVerbose;
|
||||
extern Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nFaninMax, int fUseBdds, int fVerbose );
|
||||
extern Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nFaninMax, int nCubeMax, int fUseBdds, int fUseSops, int fVerbose );
|
||||
|
||||
pNtk = Abc_FrameReadNtk(pAbc);
|
||||
pOut = Abc_FrameReadOut(pAbc);
|
||||
pErr = Abc_FrameReadErr(pAbc);
|
||||
|
||||
// set defaults
|
||||
nFaninMax = 8;
|
||||
nFaninMax = 5;
|
||||
nCubeMax = 5;
|
||||
fUseBdds = 0;
|
||||
fUseSops = 0;
|
||||
fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "Fbvh" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "KCbsvh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'F':
|
||||
case 'K':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
fprintf( pErr, "Command line switch \"-F\" should be followed by an integer.\n" );
|
||||
|
|
@ -2063,9 +2066,23 @@ int Abc_CommandRenode( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
if ( nFaninMax < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'C':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
fprintf( pErr, "Command line switch \"-C\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
nCubeMax = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( nCubeMax < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'b':
|
||||
fUseBdds ^= 1;
|
||||
break;
|
||||
case 's':
|
||||
fUseSops ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
|
|
@ -2076,6 +2093,12 @@ int Abc_CommandRenode( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
}
|
||||
}
|
||||
|
||||
if ( fUseBdds && fUseSops )
|
||||
{
|
||||
fprintf( pErr, "Cannot optimize both BDDs and SOPs at the same time.\n" );
|
||||
goto usage;
|
||||
}
|
||||
|
||||
if ( pNtk == NULL )
|
||||
{
|
||||
fprintf( pErr, "Empty network.\n" );
|
||||
|
|
@ -2088,7 +2111,7 @@ int Abc_CommandRenode( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
}
|
||||
|
||||
// get the new network
|
||||
pNtkRes = Abc_NtkRenode( pNtk, nFaninMax, fUseBdds, fVerbose );
|
||||
pNtkRes = Abc_NtkRenode( pNtk, nFaninMax, nCubeMax, fUseBdds, fUseSops, fVerbose );
|
||||
if ( pNtkRes == NULL )
|
||||
{
|
||||
fprintf( pErr, "Renoding has failed.\n" );
|
||||
|
|
@ -2099,10 +2122,13 @@ int Abc_CommandRenode( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pErr, "usage: renode [-F num] [-bv]\n" );
|
||||
fprintf( pErr, "\t transforms an AIG into a logic network by creating larger nodes\n" );
|
||||
fprintf( pErr, "\t-F num : the maximum fanin size after renoding [default = %d]\n", nFaninMax );
|
||||
fprintf( pErr, "\t-b : toggles cost function (BDD nodes or FF literals) [default = %s]\n", fUseBdds? "BDD nodes": "FF literals" );
|
||||
fprintf( pErr, "usage: renode [-K num] [-C num] [-bsv]\n" );
|
||||
fprintf( pErr, "\t transforms the AIG into a logic network with larger nodes\n" );
|
||||
fprintf( pErr, "\t while minimizing the number of FF literals of the node SOPs\n" );
|
||||
fprintf( pErr, "\t-K num : the maximum fanin size after renoding [default = %d]\n", nFaninMax );
|
||||
fprintf( pErr, "\t-C num : the maximum number of cubes used at a node [default = %d]\n", nCubeMax );
|
||||
fprintf( pErr, "\t-b : toggles minimizing the number of BDD nodes [default = %s]\n", fUseBdds? "yes": "no" );
|
||||
fprintf( pErr, "\t-s : toggles minimizing the number of SOP cubes [default = %s]\n", fUseSops? "yes": "no" );
|
||||
fprintf( pErr, "\t-v : print verbose information [default = %s]\n", fVerbose? "yes": "no" );
|
||||
fprintf( pErr, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "abc.h"
|
||||
#include "if.h"
|
||||
#include "kit.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
|
|
@ -164,6 +165,8 @@ Abc_Ntk_t * Abc_NtkFromIf( If_Man_t * pIfMan, Abc_Ntk_t * pNtk )
|
|||
// create the new network
|
||||
if ( pIfMan->pPars->fUseBdds )
|
||||
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_BDD );
|
||||
else if ( pIfMan->pPars->fUseSops )
|
||||
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
|
||||
else
|
||||
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_AIG );
|
||||
// prepare the mapping manager
|
||||
|
|
@ -223,7 +226,6 @@ Abc_Obj_t * Abc_NodeFromIf_rec( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Obj_t
|
|||
If_CutForEachLeaf( pIfMan, pCutBest, pIfLeaf, i )
|
||||
Abc_ObjAddFanin( pNodeNew, Abc_NodeFromIf_rec(pNtkNew, pIfMan, pIfLeaf) );
|
||||
// derive the function of this node
|
||||
|
||||
if ( pIfMan->pPars->fTruth )
|
||||
{
|
||||
if ( pIfMan->pPars->fUseBdds )
|
||||
|
|
@ -235,20 +237,29 @@ Abc_Obj_t * Abc_NodeFromIf_rec( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Obj_t
|
|||
// reorder the fanins to minimize the BDD size
|
||||
Abc_NodeBddReorder( pIfMan->pPars->pReoMan, pNodeNew );
|
||||
}
|
||||
else
|
||||
else if ( pIfMan->pPars->fUseSops )
|
||||
{
|
||||
typedef int Kit_Graph_t;
|
||||
extern Kit_Graph_t * Kit_TruthToGraph( unsigned * pTruth, int nVars );
|
||||
extern Hop_Obj_t * Dec_GraphToNetworkAig( Hop_Man_t * pMan, Kit_Graph_t * pGraph );
|
||||
// transform truth table into the decomposition tree
|
||||
Kit_Graph_t * pGraph = Kit_TruthToGraph( If_CutTruth(pCutBest), pCutBest->nLimit );
|
||||
Vec_Int_t * vCover = Vec_IntAlloc( 1 << 16 );
|
||||
// transform truth table into the SOP
|
||||
int RetValue = Kit_TruthIsop( If_CutTruth(pCutBest), pCutBest->nLimit, vCover, 0 );
|
||||
assert( RetValue == 0 );
|
||||
// derive the AIG for that tree
|
||||
pNodeNew->pData = Dec_GraphToNetworkAig( pNtkNew->pManFunc, pGraph );
|
||||
pNodeNew->pData = Abc_SopCreateFromIsop( pNtkNew->pManFunc, pCutBest->nLimit, vCover );
|
||||
Vec_IntFree( vCover );
|
||||
}
|
||||
else
|
||||
{
|
||||
extern Hop_Obj_t * Kit_GraphToHop( Hop_Man_t * pMan, Kit_Graph_t * pGraph );
|
||||
Vec_Int_t * vMemory = Vec_IntAlloc( 1 << 16 );
|
||||
// transform truth table into the decomposition tree
|
||||
Kit_Graph_t * pGraph = Kit_TruthToGraph( If_CutTruth(pCutBest), pCutBest->nLimit, vMemory );
|
||||
// derive the AIG for the decomposition tree
|
||||
pNodeNew->pData = Kit_GraphToHop( pNtkNew->pManFunc, pGraph );
|
||||
Kit_GraphFree( pGraph );
|
||||
Vec_IntFree( vMemory );
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
pNodeNew->pData = Abc_NodeIfToHop( pNtkNew->pManFunc, pIfMan, pIfObj );
|
||||
If_ObjSetCopy( pIfObj, pNodeNew );
|
||||
return pNodeNew;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include "abc.h"
|
||||
#include "reo.h"
|
||||
#include "if.h"
|
||||
#include "kit.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
|
|
@ -28,13 +29,11 @@
|
|||
|
||||
static int Abc_NtkRenodeEvalBdd( unsigned * pTruth, int nVars );
|
||||
static int Abc_NtkRenodeEvalSop( unsigned * pTruth, int nVars );
|
||||
static int Abc_NtkRenodeEvalAig( unsigned * pTruth, int nVars );
|
||||
|
||||
static reo_man * s_pReo = NULL;
|
||||
static DdManager * s_pDd = NULL;
|
||||
|
||||
typedef int Kit_Graph_t;
|
||||
extern DdNode * Kit_TruthToBdd( DdManager * dd, unsigned * pTruth, int nVars );
|
||||
extern Kit_Graph_t * Kit_TruthToGraph( unsigned * pTruth, int nVars );
|
||||
static reo_man * s_pReo = NULL;
|
||||
static DdManager * s_pDd = NULL;
|
||||
static Vec_Int_t * s_vMemory = NULL;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
|
|
@ -51,7 +50,7 @@ extern Kit_Graph_t * Kit_TruthToGraph( unsigned * pTruth, int nVars );
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nFaninMax, int fUseBdds, int fVerbose )
|
||||
Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nFaninMax, int nCubeMax, int fUseBdds, int fUseSops, int fVerbose )
|
||||
{
|
||||
extern Abc_Ntk_t * Abc_NtkIf( Abc_Ntk_t * pNtk, If_Par_t * pPars );
|
||||
If_Par_t Pars, * pPars = &Pars;
|
||||
|
|
@ -77,7 +76,14 @@ Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nFaninMax, int fUseBdds, int fV
|
|||
pPars->pLutLib = NULL; // Abc_FrameReadLibLut();
|
||||
pPars->pTimesArr = NULL;
|
||||
pPars->pTimesArr = NULL;
|
||||
pPars->pFuncCost = fUseBdds? Abc_NtkRenodeEvalBdd : Abc_NtkRenodeEvalSop;
|
||||
pPars->fUseBdds = fUseBdds;
|
||||
pPars->fUseSops = fUseSops;
|
||||
if ( fUseBdds )
|
||||
pPars->pFuncCost = Abc_NtkRenodeEvalBdd;
|
||||
else if ( fUseSops )
|
||||
pPars->pFuncCost = Abc_NtkRenodeEvalSop;
|
||||
else
|
||||
pPars->pFuncCost = Abc_NtkRenodeEvalAig;
|
||||
|
||||
// start the manager
|
||||
if ( fUseBdds )
|
||||
|
|
@ -85,9 +91,13 @@ Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nFaninMax, int fUseBdds, int fV
|
|||
assert( s_pReo == NULL );
|
||||
s_pDd = Cudd_Init( nFaninMax, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
|
||||
s_pReo = Extra_ReorderInit( nFaninMax, 100 );
|
||||
pPars->fUseBdds = 1;
|
||||
pPars->pReoMan = s_pReo;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( s_vMemory == NULL );
|
||||
s_vMemory = Vec_IntAlloc( 1 << 16 );
|
||||
}
|
||||
|
||||
// perform mapping/renoding
|
||||
pNtkNew = Abc_NtkIf( pNtk, pPars );
|
||||
|
|
@ -98,14 +108,20 @@ Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nFaninMax, int fUseBdds, int fV
|
|||
Extra_StopManager( s_pDd );
|
||||
Extra_ReorderQuit( s_pReo );
|
||||
s_pReo = NULL;
|
||||
s_pDd = NULL;
|
||||
s_pDd = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
Vec_IntFree( s_vMemory );
|
||||
s_vMemory = NULL;
|
||||
}
|
||||
|
||||
return pNtkNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives the BDD after reordering.]
|
||||
Synopsis [Computes the cost based on the BDD size after reordering.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -120,7 +136,8 @@ int Abc_NtkRenodeEvalBdd( unsigned * pTruth, int nVars )
|
|||
int nNodes, nSupport;
|
||||
bFunc = Kit_TruthToBdd( s_pDd, pTruth, nVars ); Cudd_Ref( bFunc );
|
||||
bFuncNew = Extra_Reorder( s_pReo, s_pDd, bFunc, NULL ); Cudd_Ref( bFuncNew );
|
||||
nSupport = Cudd_SupportSize( s_pDd, bFuncNew );
|
||||
// nSupport = Cudd_SupportSize( s_pDd, bFuncNew );
|
||||
nSupport = 1;
|
||||
nNodes = Cudd_DagSize( bFuncNew );
|
||||
Cudd_RecursiveDeref( s_pDd, bFuncNew );
|
||||
Cudd_RecursiveDeref( s_pDd, bFunc );
|
||||
|
|
@ -129,7 +146,7 @@ int Abc_NtkRenodeEvalBdd( unsigned * pTruth, int nVars )
|
|||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives the BDD after reordering.]
|
||||
Synopsis [Computes the cost based on ISOP.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -139,12 +156,33 @@ int Abc_NtkRenodeEvalBdd( unsigned * pTruth, int nVars )
|
|||
|
||||
***********************************************************************/
|
||||
int Abc_NtkRenodeEvalSop( unsigned * pTruth, int nVars )
|
||||
{
|
||||
int nCubes, RetValue;
|
||||
RetValue = Kit_TruthIsop( pTruth, nVars, s_vMemory, 0 );
|
||||
assert( RetValue == 0 );
|
||||
nCubes = Vec_IntSize( s_vMemory );
|
||||
return (1 << 16) | nCubes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the cost based on the factored form.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkRenodeEvalAig( unsigned * pTruth, int nVars )
|
||||
{
|
||||
Kit_Graph_t * pGraph;
|
||||
int nNodes, nDepth;
|
||||
pGraph = Kit_TruthToGraph( pTruth, nVars );
|
||||
pGraph = Kit_TruthToGraph( pTruth, nVars, s_vMemory );
|
||||
nNodes = Kit_GraphNodeNum( pGraph );
|
||||
nDepth = Kit_GraphLevelNum( pGraph );
|
||||
// nDepth = Kit_GraphLevelNum( pGraph );
|
||||
nDepth = 1;
|
||||
Kit_GraphFree( pGraph );
|
||||
return (nDepth << 16) | nNodes;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ struct If_Par_t_
|
|||
// internal parameters
|
||||
int fTruth; // truth table computation enabled
|
||||
int fUseBdds; // sets local BDDs at the nodes
|
||||
int fUseSops; // sets local SOPs at the nodes
|
||||
int nLatches; // the number of latches in seq mapping
|
||||
If_Lib_t * pLutLib; // the LUT library
|
||||
float * pTimesArr; // arrival times
|
||||
|
|
|
|||
|
|
@ -205,7 +205,7 @@ If_Obj_t * If_ManSetupObj( If_Man_t * p )
|
|||
{
|
||||
If_Cut_t * pCut;
|
||||
If_Obj_t * pObj;
|
||||
int i, * pArrays;
|
||||
int i, * pArrays, nTruthWords;
|
||||
// get memory for the object
|
||||
pObj = (If_Obj_t *)Mem_FixedEntryFetch( p->pMem );
|
||||
memset( pObj, 0, p->nEntryBase );
|
||||
|
|
@ -230,6 +230,13 @@ If_Obj_t * If_ManSetupObj( If_Man_t * p )
|
|||
pObj->nCuts = 1;
|
||||
// set the required times
|
||||
pObj->Required = IF_FLOAT_LARGE;
|
||||
// set up elementary truth table of the unit cut
|
||||
if ( p->pPars->fTruth )
|
||||
{
|
||||
nTruthWords = Extra_TruthWordNum( pCut->nLimit );
|
||||
for ( i = 0; i < nTruthWords; i++ )
|
||||
If_CutTruth(pCut)[i] = 0xAAAAAAAA;
|
||||
}
|
||||
return pObj;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,6 +69,8 @@ static inline unsigned Cut_TruthPhase( If_Cut_t * pCut, If_Cut_t * pCut1 )
|
|||
***********************************************************************/
|
||||
void If_CutComputeTruth( If_Man_t * p, If_Cut_t * pCut, If_Cut_t * pCut0, If_Cut_t * pCut1, int fCompl0, int fCompl1 )
|
||||
{
|
||||
extern void Kit_FactorTest( unsigned * pTruth, int nVars );
|
||||
|
||||
// permute the first table
|
||||
if ( fCompl0 )
|
||||
Extra_TruthNot( p->puTemp[0], If_CutTruth(pCut0), pCut->nLimit );
|
||||
|
|
@ -86,6 +88,9 @@ void If_CutComputeTruth( If_Man_t * p, If_Cut_t * pCut, If_Cut_t * pCut0, If_Cut
|
|||
Extra_TruthNand( If_CutTruth(pCut), p->puTemp[2], p->puTemp[3], pCut->nLimit );
|
||||
else
|
||||
Extra_TruthAnd( If_CutTruth(pCut), p->puTemp[2], p->puTemp[3], pCut->nLimit );
|
||||
|
||||
// perform
|
||||
// Kit_FactorTest( If_CutTruth(pCut), pCut->nLimit );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -511,7 +511,6 @@ static inline void Extra_TruthNand( unsigned * pOut, unsigned * pIn0, unsigned *
|
|||
extern void Extra_TruthSwapAdjacentVars( unsigned * pOut, unsigned * pIn, int nVars, int Start );
|
||||
extern void Extra_TruthStretch( unsigned * pOut, unsigned * pIn, int nVars, int nVarsAll, unsigned Phase );
|
||||
extern void Extra_TruthShrink( unsigned * pOut, unsigned * pIn, int nVars, int nVarsAll, unsigned Phase );
|
||||
extern DdNode * Extra_TruthToBdd( DdManager * dd, unsigned * pTruth, int nVars );
|
||||
extern int Extra_TruthVarInSupport( unsigned * pTruth, int nVars, int iVar );
|
||||
extern int Extra_TruthSupportSize( unsigned * pTruth, int nVars );
|
||||
extern int Extra_TruthSupport( unsigned * pTruth, int nVars );
|
||||
|
|
|
|||
|
|
@ -248,64 +248,6 @@ void Extra_TruthShrink( unsigned * pOut, unsigned * pIn, int nVars, int nVarsAll
|
|||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs truth table computation.]
|
||||
|
||||
Description [Note the caching makes no sense for this procedure.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
DdNode * Extra_TruthToBdd_rec( DdManager * dd, unsigned * pTruth, int iBit, int nVars, int nVarsTotal )
|
||||
{
|
||||
DdNode * bF0, * bF1, * bF;
|
||||
if ( nVars == 0 )
|
||||
{
|
||||
if ( pTruth[iBit>>5] & (1 << iBit&31) )
|
||||
return b1;
|
||||
return b0;
|
||||
}
|
||||
if ( nVars == 5 )
|
||||
{
|
||||
if ( pTruth[iBit>>5] == 0xFFFFFFFF )
|
||||
return b1;
|
||||
if ( pTruth[iBit>>5] == 0 )
|
||||
return b0;
|
||||
}
|
||||
// other special cases can be added
|
||||
bF0 = Extra_TruthToBdd_rec( dd, pTruth, iBit, nVars-1, nVarsTotal ); Cudd_Ref( bF0 );
|
||||
bF1 = Extra_TruthToBdd_rec( dd, pTruth, iBit+(1<<(nVars-1)), nVars-1, nVarsTotal ); Cudd_Ref( bF1 );
|
||||
bF = Cudd_bddIte( dd, dd->vars[nVarsTotal-nVars], bF1, bF0 ); Cudd_Ref( bF );
|
||||
Cudd_RecursiveDeref( dd, bF0 );
|
||||
Cudd_RecursiveDeref( dd, bF1 );
|
||||
Cudd_Deref( bF );
|
||||
return bF;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Compute BDD corresponding to the truth table.]
|
||||
|
||||
Description [If truth table has N vars, the BDD depends on N topmost
|
||||
variables of the BDD manager. The most significant variable of the table
|
||||
is encoded by the topmost variable of the manager. BDD construction is
|
||||
very efficient in this case because BDD is constructed one node at a time,
|
||||
by simply adding BDD nodes on top of existent BDD nodes.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
DdNode * Extra_TruthToBdd( DdManager * dd, unsigned * pTruth, int nVars )
|
||||
{
|
||||
return Extra_TruthToBdd_rec( dd, pTruth, 0, nVars, nVars );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if TT depends on the given variable.]
|
||||
|
|
|
|||
|
|
@ -598,6 +598,9 @@ static inline int Vec_IntPushUnique( Vec_Int_t * p, int Entry )
|
|||
***********************************************************************/
|
||||
static inline unsigned * Vec_IntFetch( Vec_Int_t * p, int nWords )
|
||||
{
|
||||
if ( nWords == 0 )
|
||||
return NULL;
|
||||
assert( nWords > 0 );
|
||||
p->nSize += nWords;
|
||||
if ( p->nSize > p->nCap )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,334 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [kit.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Computation kit.]
|
||||
|
||||
Synopsis [External declarations.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - Dec 6, 2006.]
|
||||
|
||||
Revision [$Id: kit.h,v 1.00 2006/12/06 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __KIT_H__
|
||||
#define __KIT_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 Kit_Sop_t_ Kit_Sop_t;
|
||||
struct Kit_Sop_t_
|
||||
{
|
||||
int nCubes; // the number of cubes
|
||||
unsigned * pCubes; // the storage for cubes
|
||||
};
|
||||
|
||||
typedef struct Kit_Edge_t_ Kit_Edge_t;
|
||||
struct Kit_Edge_t_
|
||||
{
|
||||
unsigned fCompl : 1; // the complemented bit
|
||||
unsigned Node : 30; // the decomposition node pointed by the edge
|
||||
};
|
||||
|
||||
typedef struct Kit_Node_t_ Kit_Node_t;
|
||||
struct Kit_Node_t_
|
||||
{
|
||||
Kit_Edge_t eEdge0; // the left child of the node
|
||||
Kit_Edge_t eEdge1; // the right child of the node
|
||||
// other info
|
||||
void * pFunc; // the function of the node (BDD or AIG)
|
||||
unsigned Level : 14; // the level of this node in the global AIG
|
||||
// printing info
|
||||
unsigned fNodeOr : 1; // marks the original OR node
|
||||
unsigned fCompl0 : 1; // marks the original complemented edge
|
||||
unsigned fCompl1 : 1; // marks the original complemented edge
|
||||
// latch info
|
||||
unsigned nLat0 : 5; // the number of latches on the first edge
|
||||
unsigned nLat1 : 5; // the number of latches on the second edge
|
||||
unsigned nLat2 : 5; // the number of latches on the output edge
|
||||
};
|
||||
|
||||
typedef struct Kit_Graph_t_ Kit_Graph_t;
|
||||
struct Kit_Graph_t_
|
||||
{
|
||||
int fConst; // marks the constant 1 graph
|
||||
int nLeaves; // the number of leaves
|
||||
int nSize; // the number of nodes (including the leaves)
|
||||
int nCap; // the number of allocated nodes
|
||||
Kit_Node_t * pNodes; // the array of leaves and internal nodes
|
||||
Kit_Edge_t eRoot; // the pointer to the topmost node
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef ALLOC
|
||||
#define ALLOC(type, num) ((type *) malloc(sizeof(type) * (num)))
|
||||
#endif
|
||||
|
||||
#ifndef FREE
|
||||
#define FREE(obj) ((obj) ? (free((char *) (obj)), (obj) = 0) : 0)
|
||||
#endif
|
||||
|
||||
#ifndef REALLOC
|
||||
#define REALLOC(type, obj, num) \
|
||||
((obj) ? ((type *) realloc((char *)(obj), sizeof(type) * (num))) : \
|
||||
((type *) malloc(sizeof(type) * (num))))
|
||||
#endif
|
||||
|
||||
static inline int Kit_CubeHasLit( unsigned uCube, int i ) { return(uCube & (unsigned)(1<<i)) > 0; }
|
||||
static inline unsigned Kit_CubeSetLit( unsigned uCube, int i ) { return uCube | (unsigned)(1<<i); }
|
||||
static inline unsigned Kit_CubeXorLit( unsigned uCube, int i ) { return uCube ^ (unsigned)(1<<i); }
|
||||
static inline unsigned Kit_CubeRemLit( unsigned uCube, int i ) { return uCube & ~(unsigned)(1<<i); }
|
||||
|
||||
static inline int Kit_CubeContains( unsigned uLarge, unsigned uSmall ) { return (uLarge & uSmall) == uSmall; }
|
||||
static inline unsigned Kit_CubeSharp( unsigned uCube, unsigned uMask ) { return uCube & ~uMask; }
|
||||
static inline unsigned Kit_CubeMask( int nVar ) { return (~(unsigned)0) >> (32-nVar); }
|
||||
|
||||
static inline int Kit_CubeIsMarked( unsigned uCube ) { return Kit_CubeHasLit( uCube, 31 ); }
|
||||
static inline unsigned Kit_CubeMark( unsigned uCube ) { return Kit_CubeSetLit( uCube, 31 ); }
|
||||
static inline unsigned Kit_CubeUnmark( unsigned uCube ) { return Kit_CubeRemLit( uCube, 31 ); }
|
||||
|
||||
static inline int Kit_SopCubeNum( Kit_Sop_t * cSop ) { return cSop->nCubes; }
|
||||
static inline unsigned Kit_SopCube( Kit_Sop_t * cSop, int i ) { return cSop->pCubes[i]; }
|
||||
static inline void Kit_SopShrink( Kit_Sop_t * cSop, int nCubesNew ) { cSop->nCubes = nCubesNew; }
|
||||
static inline void Kit_SopPushCube( Kit_Sop_t * cSop, unsigned uCube ) { cSop->pCubes[cSop->nCubes++] = uCube; }
|
||||
static inline void Kit_SopWriteCube( Kit_Sop_t * cSop, unsigned uCube, int i ) { cSop->pCubes[i] = uCube; }
|
||||
|
||||
static inline Kit_Edge_t Kit_EdgeCreate( int Node, int fCompl ) { Kit_Edge_t eEdge = { fCompl, Node }; return eEdge; }
|
||||
static inline unsigned Kit_EdgeToInt( Kit_Edge_t eEdge ) { return (eEdge.Node << 1) | eEdge.fCompl; }
|
||||
static inline Kit_Edge_t Kit_IntToEdge( unsigned Edge ) { return Kit_EdgeCreate( Edge >> 1, Edge & 1 ); }
|
||||
static inline unsigned Kit_EdgeToInt_( Kit_Edge_t eEdge ) { return *(unsigned *)&eEdge; }
|
||||
static inline Kit_Edge_t Kit_IntToEdge_( unsigned Edge ) { return *(Kit_Edge_t *)&Edge; }
|
||||
|
||||
static inline int Kit_GraphIsConst( Kit_Graph_t * pGraph ) { return pGraph->fConst; }
|
||||
static inline int Kit_GraphIsConst0( Kit_Graph_t * pGraph ) { return pGraph->fConst && pGraph->eRoot.fCompl; }
|
||||
static inline int Kit_GraphIsConst1( Kit_Graph_t * pGraph ) { return pGraph->fConst && !pGraph->eRoot.fCompl; }
|
||||
static inline int Kit_GraphIsComplement( Kit_Graph_t * pGraph ) { return pGraph->eRoot.fCompl; }
|
||||
static inline int Kit_GraphIsVar( Kit_Graph_t * pGraph ) { return pGraph->eRoot.Node < (unsigned)pGraph->nLeaves; }
|
||||
static inline void Kit_GraphComplement( Kit_Graph_t * pGraph ) { pGraph->eRoot.fCompl ^= 1; }
|
||||
static inline void Kit_GraphSetRoot( Kit_Graph_t * pGraph, Kit_Edge_t eRoot ) { pGraph->eRoot = eRoot; }
|
||||
static inline int Kit_GraphLeaveNum( Kit_Graph_t * pGraph ) { return pGraph->nLeaves; }
|
||||
static inline int Kit_GraphNodeNum( Kit_Graph_t * pGraph ) { return pGraph->nSize - pGraph->nLeaves; }
|
||||
static inline Kit_Node_t * Kit_GraphNode( Kit_Graph_t * pGraph, int i ) { return pGraph->pNodes + i; }
|
||||
static inline Kit_Node_t * Kit_GraphNodeLast( Kit_Graph_t * pGraph ) { return pGraph->pNodes + pGraph->nSize - 1; }
|
||||
static inline int Kit_GraphNodeInt( Kit_Graph_t * pGraph, Kit_Node_t * pNode ) { return pNode - pGraph->pNodes; }
|
||||
static inline int Kit_GraphNodeIsVar( Kit_Graph_t * pGraph, Kit_Node_t * pNode ) { return Kit_GraphNodeInt(pGraph,pNode) < pGraph->nLeaves; }
|
||||
static inline Kit_Node_t * Kit_GraphVar( Kit_Graph_t * pGraph ) { assert( Kit_GraphIsVar( pGraph ) ); return Kit_GraphNode( pGraph, pGraph->eRoot.Node ); }
|
||||
static inline int Kit_GraphVarInt( Kit_Graph_t * pGraph ) { assert( Kit_GraphIsVar( pGraph ) ); return Kit_GraphNodeInt( pGraph, Kit_GraphVar(pGraph) );}
|
||||
|
||||
static inline int Kit_Float2Int( float Val ) { return *((int *)&Val); }
|
||||
static inline float Kit_Int2Float( int Num ) { return *((float *)&Num); }
|
||||
static inline int Kit_BitWordNum( int nBits ) { return nBits/(8*sizeof(unsigned)) + ((nBits%(8*sizeof(unsigned))) > 0); }
|
||||
static inline int Kit_TruthWordNum( int nVars ) { return nVars <= 5 ? 1 : (1 << (nVars - 5)); }
|
||||
|
||||
static inline void Kit_TruthSetBit( unsigned * p, int Bit ) { p[Bit>>5] |= (1<<(Bit & 31)); }
|
||||
static inline void Kit_TruthXorBit( unsigned * p, int Bit ) { p[Bit>>5] ^= (1<<(Bit & 31)); }
|
||||
static inline int Kit_TruthHasBit( unsigned * p, int Bit ) { return (p[Bit>>5] & (1<<(Bit & 31))) > 0; }
|
||||
|
||||
static inline int Kit_WordCountOnes( unsigned uWord )
|
||||
{
|
||||
uWord = (uWord & 0x55555555) + ((uWord>>1) & 0x55555555);
|
||||
uWord = (uWord & 0x33333333) + ((uWord>>2) & 0x33333333);
|
||||
uWord = (uWord & 0x0F0F0F0F) + ((uWord>>4) & 0x0F0F0F0F);
|
||||
uWord = (uWord & 0x00FF00FF) + ((uWord>>8) & 0x00FF00FF);
|
||||
return (uWord & 0x0000FFFF) + (uWord>>16);
|
||||
}
|
||||
static inline int Kit_TruthCountOnes( unsigned * pIn, int nVars )
|
||||
{
|
||||
int w, Counter = 0;
|
||||
for ( w = Kit_TruthWordNum(nVars)-1; w >= 0; w-- )
|
||||
Counter += Kit_WordCountOnes(pIn[w]);
|
||||
return Counter;
|
||||
}
|
||||
static inline int Kit_TruthIsEqual( unsigned * pIn0, unsigned * pIn1, int nVars )
|
||||
{
|
||||
int w;
|
||||
for ( w = Kit_TruthWordNum(nVars)-1; w >= 0; w-- )
|
||||
if ( pIn0[w] != pIn1[w] )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
static inline int Kit_TruthIsConst0( unsigned * pIn, int nVars )
|
||||
{
|
||||
int w;
|
||||
for ( w = Kit_TruthWordNum(nVars)-1; w >= 0; w-- )
|
||||
if ( pIn[w] )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
static inline int Kit_TruthIsConst1( unsigned * pIn, int nVars )
|
||||
{
|
||||
int w;
|
||||
for ( w = Kit_TruthWordNum(nVars)-1; w >= 0; w-- )
|
||||
if ( pIn[w] != ~(unsigned)0 )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
static inline int Kit_TruthIsImply( unsigned * pIn1, unsigned * pIn2, int nVars )
|
||||
{
|
||||
int w;
|
||||
for ( w = Kit_TruthWordNum(nVars)-1; w >= 0; w-- )
|
||||
if ( pIn1[w] & ~pIn2[w] )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
static inline void Kit_TruthCopy( unsigned * pOut, unsigned * pIn, int nVars )
|
||||
{
|
||||
int w;
|
||||
for ( w = Kit_TruthWordNum(nVars)-1; w >= 0; w-- )
|
||||
pOut[w] = pIn[w];
|
||||
}
|
||||
static inline void Kit_TruthClear( unsigned * pOut, int nVars )
|
||||
{
|
||||
int w;
|
||||
for ( w = Kit_TruthWordNum(nVars)-1; w >= 0; w-- )
|
||||
pOut[w] = 0;
|
||||
}
|
||||
static inline void Kit_TruthFill( unsigned * pOut, int nVars )
|
||||
{
|
||||
int w;
|
||||
for ( w = Kit_TruthWordNum(nVars)-1; w >= 0; w-- )
|
||||
pOut[w] = ~(unsigned)0;
|
||||
}
|
||||
static inline void Kit_TruthNot( unsigned * pOut, unsigned * pIn, int nVars )
|
||||
{
|
||||
int w;
|
||||
for ( w = Kit_TruthWordNum(nVars)-1; w >= 0; w-- )
|
||||
pOut[w] = ~pIn[w];
|
||||
}
|
||||
static inline void Kit_TruthAnd( unsigned * pOut, unsigned * pIn0, unsigned * pIn1, int nVars )
|
||||
{
|
||||
int w;
|
||||
for ( w = Kit_TruthWordNum(nVars)-1; w >= 0; w-- )
|
||||
pOut[w] = pIn0[w] & pIn1[w];
|
||||
}
|
||||
static inline void Kit_TruthOr( unsigned * pOut, unsigned * pIn0, unsigned * pIn1, int nVars )
|
||||
{
|
||||
int w;
|
||||
for ( w = Kit_TruthWordNum(nVars)-1; w >= 0; w-- )
|
||||
pOut[w] = pIn0[w] | pIn1[w];
|
||||
}
|
||||
static inline void Kit_TruthSharp( unsigned * pOut, unsigned * pIn0, unsigned * pIn1, int nVars )
|
||||
{
|
||||
int w;
|
||||
for ( w = Kit_TruthWordNum(nVars)-1; w >= 0; w-- )
|
||||
pOut[w] = pIn0[w] & ~pIn1[w];
|
||||
}
|
||||
static inline void Kit_TruthNand( unsigned * pOut, unsigned * pIn0, unsigned * pIn1, int nVars )
|
||||
{
|
||||
int w;
|
||||
for ( w = Kit_TruthWordNum(nVars)-1; w >= 0; w-- )
|
||||
pOut[w] = ~(pIn0[w] & pIn1[w]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// ITERATORS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define Kit_SopForEachCube( cSop, uCube, i ) \
|
||||
for ( i = 0; (i < Kit_SopCubeNum(cSop)) && ((uCube) = Kit_SopCube(cSop, i)); i++ )
|
||||
#define Kit_CubeForEachLiteral( uCube, Lit, nLits, i ) \
|
||||
for ( i = 0; (i < (nLits)) && ((Lit) = Kit_CubeHasLit(uCube, i)); i++ )
|
||||
|
||||
#define Kit_GraphForEachLeaf( pGraph, pLeaf, i ) \
|
||||
for ( i = 0; (i < (pGraph)->nLeaves) && (((pLeaf) = Kit_GraphNode(pGraph, i)), 1); i++ )
|
||||
#define Kit_GraphForEachNode( pGraph, pAnd, i ) \
|
||||
for ( i = (pGraph)->nLeaves; (i < (pGraph)->nSize) && (((pAnd) = Kit_GraphNode(pGraph, i)), 1); i++ )
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*=== kitBdd.c ==========================================================*/
|
||||
extern DdNode * Kit_SopToBdd( DdManager * dd, Kit_Sop_t * cSop, int nVars );
|
||||
extern DdNode * Kit_GraphToBdd( DdManager * dd, Kit_Graph_t * pGraph );
|
||||
extern DdNode * Kit_TruthToBdd( DdManager * dd, unsigned * pTruth, int nVars );
|
||||
/*=== kitFactor.c ==========================================================*/
|
||||
extern Kit_Graph_t * Kit_SopFactor( Vec_Int_t * vCover, int fCompl, int nVars, Vec_Int_t * vMemory );
|
||||
/*=== kitGraph.c ==========================================================*/
|
||||
extern Kit_Graph_t * Kit_GraphCreate( int nLeaves );
|
||||
extern Kit_Graph_t * Kit_GraphCreateConst0();
|
||||
extern Kit_Graph_t * Kit_GraphCreateConst1();
|
||||
extern Kit_Graph_t * Kit_GraphCreateLeaf( int iLeaf, int nLeaves, int fCompl );
|
||||
extern void Kit_GraphFree( Kit_Graph_t * pGraph );
|
||||
extern Kit_Node_t * Kit_GraphAppendNode( Kit_Graph_t * pGraph );
|
||||
extern Kit_Edge_t Kit_GraphAddNodeAnd( Kit_Graph_t * pGraph, Kit_Edge_t eEdge0, Kit_Edge_t eEdge1 );
|
||||
extern Kit_Edge_t Kit_GraphAddNodeOr( Kit_Graph_t * pGraph, Kit_Edge_t eEdge0, Kit_Edge_t eEdge1 );
|
||||
extern Kit_Edge_t Kit_GraphAddNodeXor( Kit_Graph_t * pGraph, Kit_Edge_t eEdge0, Kit_Edge_t eEdge1, int Type );
|
||||
extern Kit_Edge_t Kit_GraphAddNodeMux( Kit_Graph_t * pGraph, Kit_Edge_t eEdgeC, Kit_Edge_t eEdgeT, Kit_Edge_t eEdgeE, int Type );
|
||||
extern unsigned Kit_GraphToTruth( Kit_Graph_t * pGraph );
|
||||
extern Kit_Graph_t * Kit_TruthToGraph( unsigned * pTruth, int nVars, Vec_Int_t * vMemory );
|
||||
/*=== kitHop.c ==========================================================*/
|
||||
/*=== kitIsop.c ==========================================================*/
|
||||
extern int Kit_TruthIsop( unsigned * puTruth, int nVars, Vec_Int_t * vMemory, int fTryBoth );
|
||||
/*=== kitSop.c ==========================================================*/
|
||||
extern void Kit_SopCreate( Kit_Sop_t * cResult, Vec_Int_t * vInput, int nVars, Vec_Int_t * vMemory );
|
||||
extern void Kit_SopCreateInverse( Kit_Sop_t * cResult, Vec_Int_t * vInput, int nVars, Vec_Int_t * vMemory );
|
||||
extern void Kit_SopDup( Kit_Sop_t * cResult, Kit_Sop_t * cSop, Vec_Int_t * vMemory );
|
||||
extern void Kit_SopDivideByLiteralQuo( Kit_Sop_t * cSop, int iLit );
|
||||
extern void Kit_SopDivideByCube( Kit_Sop_t * cSop, Kit_Sop_t * cDiv, Kit_Sop_t * vQuo, Kit_Sop_t * vRem, Vec_Int_t * vMemory );
|
||||
extern void Kit_SopDivideInternal( Kit_Sop_t * cSop, Kit_Sop_t * cDiv, Kit_Sop_t * vQuo, Kit_Sop_t * vRem, Vec_Int_t * vMemory );
|
||||
extern void Kit_SopMakeCubeFree( Kit_Sop_t * cSop );
|
||||
extern int Kit_SopIsCubeFree( Kit_Sop_t * cSop );
|
||||
extern void Kit_SopCommonCubeCover( Kit_Sop_t * cResult, Kit_Sop_t * cSop, Vec_Int_t * vMemory );
|
||||
extern int Kit_SopAnyLiteral( Kit_Sop_t * cSop, int nLits );
|
||||
extern int Kit_SopDivisor( Kit_Sop_t * cResult, Kit_Sop_t * cSop, int nLits, Vec_Int_t * vMemory );
|
||||
extern void Kit_SopBestLiteralCover( Kit_Sop_t * cResult, Kit_Sop_t * cSop, unsigned uCube, int nLits, Vec_Int_t * vMemory );
|
||||
/*=== kitTruth.c ==========================================================*/
|
||||
extern void Kit_TruthSwapAdjacentVars( unsigned * pOut, unsigned * pIn, int nVars, int Start );
|
||||
extern void Kit_TruthStretch( unsigned * pOut, unsigned * pIn, int nVars, int nVarsAll, unsigned Phase );
|
||||
extern void Kit_TruthShrink( unsigned * pOut, unsigned * pIn, int nVars, int nVarsAll, unsigned Phase );
|
||||
extern int Kit_TruthVarInSupport( unsigned * pTruth, int nVars, int iVar );
|
||||
extern int Kit_TruthSupportSize( unsigned * pTruth, int nVars );
|
||||
extern int Kit_TruthSupport( unsigned * pTruth, int nVars );
|
||||
extern void Kit_TruthCofactor0( unsigned * pTruth, int nVars, int iVar );
|
||||
extern void Kit_TruthCofactor1( unsigned * pTruth, int nVars, int iVar );
|
||||
extern void Kit_TruthExist( unsigned * pTruth, int nVars, int iVar );
|
||||
extern void Kit_TruthForall( 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 );
|
||||
extern void Kit_TruthCountOnesInCofs( unsigned * pTruth, int nVars, short * pStore );
|
||||
extern unsigned Kit_TruthHash( unsigned * pIn, int nWords );
|
||||
extern unsigned Kit_TruthSemiCanonicize( unsigned * pInOut, unsigned * pAux, int nVars, char * pCanonPerm, short * pStore );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -0,0 +1,231 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [kitBdd.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Computation kit.]
|
||||
|
||||
Synopsis [Procedures involving BDDs.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - Dec 6, 2006.]
|
||||
|
||||
Revision [$Id: kitBdd.c,v 1.00 2006/12/06 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "kit.h"
|
||||
#include "extra.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives the BDD for the given SOP.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
DdNode * Kit_SopToBdd( DdManager * dd, Kit_Sop_t * cSop, int nVars )
|
||||
{
|
||||
DdNode * bSum, * bCube, * bTemp, * bVar;
|
||||
unsigned uCube;
|
||||
int Value, i, v;
|
||||
assert( nVars < 16 );
|
||||
// start the cover
|
||||
bSum = Cudd_ReadLogicZero(dd); Cudd_Ref( bSum );
|
||||
// check the logic function of the node
|
||||
Kit_SopForEachCube( cSop, uCube, i )
|
||||
{
|
||||
bCube = Cudd_ReadOne(dd); Cudd_Ref( bCube );
|
||||
for ( v = 0; v < nVars; v++ )
|
||||
{
|
||||
Value = ((uCube >> 2*v) & 3);
|
||||
if ( Value == 1 )
|
||||
bVar = Cudd_Not( Cudd_bddIthVar( dd, v ) );
|
||||
else if ( Value == 2 )
|
||||
bVar = Cudd_bddIthVar( dd, v );
|
||||
else
|
||||
continue;
|
||||
bCube = Cudd_bddAnd( dd, bTemp = bCube, bVar ); Cudd_Ref( bCube );
|
||||
Cudd_RecursiveDeref( dd, bTemp );
|
||||
}
|
||||
bSum = Cudd_bddOr( dd, bTemp = bSum, bCube );
|
||||
Cudd_Ref( bSum );
|
||||
Cudd_RecursiveDeref( dd, bTemp );
|
||||
Cudd_RecursiveDeref( dd, bCube );
|
||||
}
|
||||
// complement the result if necessary
|
||||
Cudd_Deref( bSum );
|
||||
return bSum;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Converts graph to BDD.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
DdNode * Kit_GraphToBdd( DdManager * dd, Kit_Graph_t * pGraph )
|
||||
{
|
||||
DdNode * bFunc, * bFunc0, * bFunc1;
|
||||
Kit_Node_t * pNode;
|
||||
int i;
|
||||
|
||||
// sanity checks
|
||||
assert( Kit_GraphLeaveNum(pGraph) >= 0 );
|
||||
assert( Kit_GraphLeaveNum(pGraph) <= pGraph->nSize );
|
||||
|
||||
// check for constant function
|
||||
if ( Kit_GraphIsConst(pGraph) )
|
||||
return Cudd_NotCond( b1, Kit_GraphIsComplement(pGraph) );
|
||||
// check for a literal
|
||||
if ( Kit_GraphIsVar(pGraph) )
|
||||
return Cudd_NotCond( Cudd_bddIthVar(dd, Kit_GraphVarInt(pGraph)), Kit_GraphIsComplement(pGraph) );
|
||||
|
||||
// assign the elementary variables
|
||||
Kit_GraphForEachLeaf( pGraph, pNode, i )
|
||||
pNode->pFunc = Cudd_bddIthVar( dd, i );
|
||||
|
||||
// compute the function for each internal node
|
||||
Kit_GraphForEachNode( pGraph, pNode, i )
|
||||
{
|
||||
bFunc0 = Cudd_NotCond( Kit_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl );
|
||||
bFunc1 = Cudd_NotCond( Kit_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl );
|
||||
pNode->pFunc = Cudd_bddAnd( dd, bFunc0, bFunc1 ); Cudd_Ref( pNode->pFunc );
|
||||
}
|
||||
|
||||
// deref the intermediate results
|
||||
bFunc = pNode->pFunc; Cudd_Ref( bFunc );
|
||||
Kit_GraphForEachNode( pGraph, pNode, i )
|
||||
Cudd_RecursiveDeref( dd, pNode->pFunc );
|
||||
Cudd_Deref( bFunc );
|
||||
|
||||
// complement the result if necessary
|
||||
return Cudd_NotCond( bFunc, Kit_GraphIsComplement(pGraph) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
DdNode * Kit_TruthToBdd_rec( DdManager * dd, unsigned * pTruth, int iBit, int nVars, int nVarsTotal )
|
||||
{
|
||||
DdNode * bF0, * bF1, * bF;
|
||||
if ( nVars == 0 )
|
||||
{
|
||||
if ( pTruth[iBit>>5] & (1 << iBit&31) )
|
||||
return b1;
|
||||
return b0;
|
||||
}
|
||||
if ( nVars == 5 )
|
||||
{
|
||||
if ( pTruth[iBit>>5] == 0xFFFFFFFF )
|
||||
return b1;
|
||||
if ( pTruth[iBit>>5] == 0 )
|
||||
return b0;
|
||||
}
|
||||
// other special cases can be added
|
||||
bF0 = Kit_TruthToBdd_rec( dd, pTruth, iBit, nVars-1, nVarsTotal ); Cudd_Ref( bF0 );
|
||||
bF1 = Kit_TruthToBdd_rec( dd, pTruth, iBit+(1<<(nVars-1)), nVars-1, nVarsTotal ); Cudd_Ref( bF1 );
|
||||
bF = Cudd_bddIte( dd, dd->vars[nVarsTotal-nVars], bF1, bF0 ); Cudd_Ref( bF );
|
||||
Cudd_RecursiveDeref( dd, bF0 );
|
||||
Cudd_RecursiveDeref( dd, bF1 );
|
||||
Cudd_Deref( bF );
|
||||
return bF;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Compute BDD corresponding to the truth table.]
|
||||
|
||||
Description [If truth table has N vars, the BDD depends on N topmost
|
||||
variables of the BDD manager. The most significant variable of the table
|
||||
is encoded by the topmost variable of the manager. BDD construction is
|
||||
efficient in this case because BDD is constructed one node at a time,
|
||||
by simply adding BDD nodes on top of existent BDD nodes.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
DdNode * Kit_TruthToBdd( DdManager * dd, unsigned * pTruth, int nVars )
|
||||
{
|
||||
return Kit_TruthToBdd_rec( dd, pTruth, 0, nVars, nVars );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Verifies that the factoring is correct.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Kit_SopFactorVerify( Vec_Int_t * vCover, Kit_Graph_t * pFForm, int nVars )
|
||||
{
|
||||
static DdManager * dd = NULL;
|
||||
Kit_Sop_t Sop, * cSop = &Sop;
|
||||
DdNode * bFunc1, * bFunc2;
|
||||
Vec_Int_t * vMemory;
|
||||
int RetValue;
|
||||
// get the manager
|
||||
if ( dd == NULL )
|
||||
dd = Cudd_Init( 16, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
|
||||
// derive SOP
|
||||
vMemory = Vec_IntAlloc( Vec_IntSize(vCover) );
|
||||
Kit_SopCreate( cSop, vCover, nVars, vMemory );
|
||||
// get the functions
|
||||
bFunc1 = Kit_SopToBdd( dd, cSop, nVars ); Cudd_Ref( bFunc1 );
|
||||
bFunc2 = Kit_GraphToBdd( dd, pFForm ); Cudd_Ref( bFunc2 );
|
||||
//Extra_bddPrint( dd, bFunc1 ); printf("\n");
|
||||
//Extra_bddPrint( dd, bFunc2 ); printf("\n");
|
||||
RetValue = (bFunc1 == bFunc2);
|
||||
if ( bFunc1 != bFunc2 )
|
||||
{
|
||||
int s;
|
||||
Extra_bddPrint( dd, bFunc1 ); printf("\n");
|
||||
Extra_bddPrint( dd, bFunc2 ); printf("\n");
|
||||
s = 0;
|
||||
}
|
||||
Cudd_RecursiveDeref( dd, bFunc1 );
|
||||
Cudd_RecursiveDeref( dd, bFunc2 );
|
||||
Vec_IntFree( vMemory );
|
||||
return RetValue;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,337 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [kitFactor.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Computation kit.]
|
||||
|
||||
Synopsis [Algebraic factoring.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - Dec 6, 2006.]
|
||||
|
||||
Revision [$Id: kitFactor.c,v 1.00 2006/12/06 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "kit.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// factoring fails if intermediate memory usage exceed this limit
|
||||
#define KIT_FACTOR_MEM_LIMIT (1<<16)
|
||||
|
||||
static Kit_Edge_t Kit_SopFactor_rec( Kit_Graph_t * pFForm, Kit_Sop_t * cSop, int nLits, Vec_Int_t * vMemory );
|
||||
static Kit_Edge_t Kit_SopFactorLF_rec( Kit_Graph_t * pFForm, Kit_Sop_t * cSop, Kit_Sop_t * cSimple, int nLits, Vec_Int_t * vMemory );
|
||||
static Kit_Edge_t Kit_SopFactorTrivial( Kit_Graph_t * pFForm, Kit_Sop_t * cSop, int nLits );
|
||||
static Kit_Edge_t Kit_SopFactorTrivialCube( Kit_Graph_t * pFForm, unsigned uCube, int nLits );
|
||||
|
||||
extern int Kit_SopFactorVerify( Vec_Int_t * cSop, Kit_Graph_t * pFForm, int nVars );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Factors the cover.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Kit_Graph_t * Kit_SopFactor( Vec_Int_t * vCover, int fCompl, int nVars, Vec_Int_t * vMemory )
|
||||
{
|
||||
Kit_Sop_t Sop, Res;
|
||||
Kit_Sop_t * cSop = &Sop, * cRes = &Res;
|
||||
Kit_Graph_t * pFForm;
|
||||
Kit_Edge_t eRoot;
|
||||
int nCubes = Vec_IntSize(vCover);
|
||||
|
||||
// works for up to 15 variables because divisin procedure
|
||||
// used the last bit for marking the cubes going to the remainder
|
||||
assert( nVars < 16 );
|
||||
|
||||
// check for trivial functions
|
||||
if ( Vec_IntSize(vCover) == 0 )
|
||||
return Kit_GraphCreateConst0();
|
||||
if ( Vec_IntSize(vCover) == 1 && Vec_IntEntry(vCover, 0) == (int)Kit_CubeMask(nVars) )
|
||||
return Kit_GraphCreateConst1();
|
||||
|
||||
// prepare memory manager
|
||||
// Vec_IntClear( vMemory );
|
||||
Vec_IntGrow( vMemory, KIT_FACTOR_MEM_LIMIT );
|
||||
|
||||
// perform CST
|
||||
Kit_SopCreateInverse( cSop, vCover, 2 * nVars, vMemory ); // CST
|
||||
|
||||
// start the factored form
|
||||
pFForm = Kit_GraphCreate( nVars );
|
||||
// factor the cover
|
||||
eRoot = Kit_SopFactor_rec( pFForm, cSop, 2 * nVars, vMemory );
|
||||
// finalize the factored form
|
||||
Kit_GraphSetRoot( pFForm, eRoot );
|
||||
if ( fCompl )
|
||||
Kit_GraphComplement( pFForm );
|
||||
|
||||
// verify the factored form
|
||||
// Vec_IntShrink( vCover, nCubes );
|
||||
// if ( !Kit_SopFactorVerify( vCover, pFForm, nVars ) )
|
||||
// printf( "Verification has failed.\n" );
|
||||
return pFForm;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recursive factoring procedure.]
|
||||
|
||||
Description [For the pseudo-code, see Hachtel/Somenzi,
|
||||
Logic synthesis and verification algorithms, Kluwer, 1996, p. 432.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Kit_Edge_t Kit_SopFactor_rec( Kit_Graph_t * pFForm, Kit_Sop_t * cSop, int nLits, Vec_Int_t * vMemory )
|
||||
{
|
||||
Kit_Sop_t Div, Quo, Rem, Com;
|
||||
Kit_Sop_t * cDiv = &Div, * cQuo = &Quo, * cRem = &Rem, * cCom = &Com;
|
||||
Kit_Edge_t eNodeDiv, eNodeQuo, eNodeRem, eNodeAnd;
|
||||
|
||||
// make sure the cover contains some cubes
|
||||
assert( Kit_SopCubeNum(cSop) > 0 );
|
||||
|
||||
// get the divisor
|
||||
if ( !Kit_SopDivisor(cDiv, cSop, nLits, vMemory) )
|
||||
return Kit_SopFactorTrivial( pFForm, cSop, nLits );
|
||||
|
||||
// divide the cover by the divisor
|
||||
Kit_SopDivideInternal( cSop, cDiv, cQuo, cRem, vMemory );
|
||||
|
||||
// check the trivial case
|
||||
assert( Kit_SopCubeNum(cQuo) > 0 );
|
||||
if ( Kit_SopCubeNum(cQuo) == 1 )
|
||||
return Kit_SopFactorLF_rec( pFForm, cSop, cQuo, nLits, vMemory );
|
||||
|
||||
// make the quotient cube free
|
||||
Kit_SopMakeCubeFree( cQuo );
|
||||
|
||||
// divide the cover by the quotient
|
||||
Kit_SopDivideInternal( cSop, cQuo, cDiv, cRem, vMemory );
|
||||
|
||||
// check the trivial case
|
||||
if ( Kit_SopIsCubeFree( cDiv ) )
|
||||
{
|
||||
eNodeDiv = Kit_SopFactor_rec( pFForm, cDiv, nLits, vMemory );
|
||||
eNodeQuo = Kit_SopFactor_rec( pFForm, cQuo, nLits, vMemory );
|
||||
eNodeAnd = Kit_GraphAddNodeAnd( pFForm, eNodeDiv, eNodeQuo );
|
||||
if ( Kit_SopCubeNum(cRem) == 0 )
|
||||
return eNodeAnd;
|
||||
eNodeRem = Kit_SopFactor_rec( pFForm, cRem, nLits, vMemory );
|
||||
return Kit_GraphAddNodeOr( pFForm, eNodeAnd, eNodeRem );
|
||||
}
|
||||
|
||||
// get the common cube
|
||||
Kit_SopCommonCubeCover( cCom, cDiv, vMemory );
|
||||
|
||||
// solve the simple problem
|
||||
return Kit_SopFactorLF_rec( pFForm, cSop, cCom, nLits, vMemory );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Internal recursive factoring procedure for the leaf case.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Kit_Edge_t Kit_SopFactorLF_rec( Kit_Graph_t * pFForm, Kit_Sop_t * cSop, Kit_Sop_t * cSimple, int nLits, Vec_Int_t * vMemory )
|
||||
{
|
||||
Kit_Sop_t Div, Quo, Rem;
|
||||
Kit_Sop_t * cDiv = &Div, * cQuo = &Quo, * cRem = &Rem;
|
||||
Kit_Edge_t eNodeDiv, eNodeQuo, eNodeRem, eNodeAnd;
|
||||
assert( Kit_SopCubeNum(cSimple) == 1 );
|
||||
// get the most often occurring literal
|
||||
Kit_SopBestLiteralCover( cDiv, cSop, Kit_SopCube(cSimple, 0), nLits, vMemory );
|
||||
// divide the cover by the literal
|
||||
Kit_SopDivideByCube( cSop, cDiv, cQuo, cRem, vMemory );
|
||||
// get the node pointer for the literal
|
||||
eNodeDiv = Kit_SopFactorTrivialCube( pFForm, Kit_SopCube(cDiv, 0), nLits );
|
||||
// factor the quotient and remainder
|
||||
eNodeQuo = Kit_SopFactor_rec( pFForm, cQuo, nLits, vMemory );
|
||||
eNodeAnd = Kit_GraphAddNodeAnd( pFForm, eNodeDiv, eNodeQuo );
|
||||
if ( Kit_SopCubeNum(cRem) == 0 )
|
||||
return eNodeAnd;
|
||||
eNodeRem = Kit_SopFactor_rec( pFForm, cRem, nLits, vMemory );
|
||||
return Kit_GraphAddNodeOr( pFForm, eNodeAnd, eNodeRem );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Factoring cube.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Kit_Edge_t Kit_SopFactorTrivialCube_rec( Kit_Graph_t * pFForm, unsigned uCube, int nStart, int nFinish )
|
||||
{
|
||||
Kit_Edge_t eNode1, eNode2;
|
||||
int i, iLit, nLits, nLits1, nLits2;
|
||||
// count the number of literals in this interval
|
||||
nLits = 0;
|
||||
for ( i = nStart; i < nFinish; i++ )
|
||||
if ( Kit_CubeHasLit(uCube, i) )
|
||||
{
|
||||
iLit = i;
|
||||
nLits++;
|
||||
}
|
||||
// quit if there is only one literal
|
||||
if ( nLits == 1 )
|
||||
return Kit_EdgeCreate( iLit/2, iLit%2 ); // CST
|
||||
// split the literals into two parts
|
||||
nLits1 = nLits/2;
|
||||
nLits2 = nLits - nLits1;
|
||||
// nLits2 = nLits/2;
|
||||
// nLits1 = nLits - nLits2;
|
||||
// find the splitting point
|
||||
nLits = 0;
|
||||
for ( i = nStart; i < nFinish; i++ )
|
||||
if ( Kit_CubeHasLit(uCube, i) )
|
||||
{
|
||||
if ( nLits == nLits1 )
|
||||
break;
|
||||
nLits++;
|
||||
}
|
||||
// recursively construct the tree for the parts
|
||||
eNode1 = Kit_SopFactorTrivialCube_rec( pFForm, uCube, nStart, i );
|
||||
eNode2 = Kit_SopFactorTrivialCube_rec( pFForm, uCube, i, nFinish );
|
||||
return Kit_GraphAddNodeAnd( pFForm, eNode1, eNode2 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Factoring cube.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Kit_Edge_t Kit_SopFactorTrivialCube( Kit_Graph_t * pFForm, unsigned uCube, int nLits )
|
||||
{
|
||||
return Kit_SopFactorTrivialCube_rec( pFForm, uCube, 0, nLits );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Factoring SOP.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Kit_Edge_t Kit_SopFactorTrivial_rec( Kit_Graph_t * pFForm, unsigned * pCubes, int nCubes, int nLits )
|
||||
{
|
||||
Kit_Edge_t eNode1, eNode2;
|
||||
int nCubes1, nCubes2;
|
||||
if ( nCubes == 1 )
|
||||
return Kit_SopFactorTrivialCube_rec( pFForm, pCubes[0], 0, nLits );
|
||||
// split the cubes into two parts
|
||||
nCubes1 = nCubes/2;
|
||||
nCubes2 = nCubes - nCubes1;
|
||||
// nCubes2 = nCubes/2;
|
||||
// nCubes1 = nCubes - nCubes2;
|
||||
// recursively construct the tree for the parts
|
||||
eNode1 = Kit_SopFactorTrivial_rec( pFForm, pCubes, nCubes1, nLits );
|
||||
eNode2 = Kit_SopFactorTrivial_rec( pFForm, pCubes + nCubes1, nCubes2, nLits );
|
||||
return Kit_GraphAddNodeOr( pFForm, eNode1, eNode2 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Factoring the cover, which has no algebraic divisors.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Kit_Edge_t Kit_SopFactorTrivial( Kit_Graph_t * pFForm, Kit_Sop_t * cSop, int nLits )
|
||||
{
|
||||
return Kit_SopFactorTrivial_rec( pFForm, cSop->pCubes, cSop->nCubes, nLits );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Testing procedure for the factoring code.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Kit_FactorTest( unsigned * pTruth, int nVars )
|
||||
{
|
||||
Vec_Int_t * vCover, * vMemory;
|
||||
Kit_Graph_t * pGraph;
|
||||
// unsigned uTruthRes;
|
||||
int RetValue;
|
||||
|
||||
// derive SOP
|
||||
vCover = Vec_IntAlloc( 0 );
|
||||
RetValue = Kit_TruthIsop( pTruth, nVars, vCover, 0 );
|
||||
assert( RetValue == 0 );
|
||||
|
||||
// derive factored form
|
||||
vMemory = Vec_IntAlloc( 0 );
|
||||
pGraph = Kit_SopFactor( vCover, 0, nVars, vMemory );
|
||||
/*
|
||||
// derive truth table
|
||||
assert( nVars <= 5 );
|
||||
uTruthRes = Kit_GraphToTruth( pGraph );
|
||||
if ( uTruthRes != pTruth[0] )
|
||||
printf( "Verification failed!" );
|
||||
*/
|
||||
printf( "Vars = %2d. Cubes = %3d. FFNodes = %3d. FF_memory = %3d.\n",
|
||||
nVars, Vec_IntSize(vCover), Kit_GraphNodeNum(pGraph), Vec_IntSize(vMemory) );
|
||||
|
||||
Vec_IntFree( vMemory );
|
||||
Vec_IntFree( vCover );
|
||||
Kit_GraphFree( pGraph );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,367 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [kitGraph.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Computation kit.]
|
||||
|
||||
Synopsis [Decomposition graph representation.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - Dec 6, 2006.]
|
||||
|
||||
Revision [$Id: kitGraph.c,v 1.00 2006/12/06 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "kit.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates a graph with the given number of leaves.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Kit_Graph_t * Kit_GraphCreate( int nLeaves )
|
||||
{
|
||||
Kit_Graph_t * pGraph;
|
||||
pGraph = ALLOC( Kit_Graph_t, 1 );
|
||||
memset( pGraph, 0, sizeof(Kit_Graph_t) );
|
||||
pGraph->nLeaves = nLeaves;
|
||||
pGraph->nSize = nLeaves;
|
||||
pGraph->nCap = 2 * nLeaves + 50;
|
||||
pGraph->pNodes = ALLOC( Kit_Node_t, pGraph->nCap );
|
||||
memset( pGraph->pNodes, 0, sizeof(Kit_Node_t) * pGraph->nSize );
|
||||
return pGraph;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates constant 0 graph.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Kit_Graph_t * Kit_GraphCreateConst0()
|
||||
{
|
||||
Kit_Graph_t * pGraph;
|
||||
pGraph = ALLOC( Kit_Graph_t, 1 );
|
||||
memset( pGraph, 0, sizeof(Kit_Graph_t) );
|
||||
pGraph->fConst = 1;
|
||||
pGraph->eRoot.fCompl = 1;
|
||||
return pGraph;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates constant 1 graph.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Kit_Graph_t * Kit_GraphCreateConst1()
|
||||
{
|
||||
Kit_Graph_t * pGraph;
|
||||
pGraph = ALLOC( Kit_Graph_t, 1 );
|
||||
memset( pGraph, 0, sizeof(Kit_Graph_t) );
|
||||
pGraph->fConst = 1;
|
||||
return pGraph;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the literal graph.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Kit_Graph_t * Kit_GraphCreateLeaf( int iLeaf, int nLeaves, int fCompl )
|
||||
{
|
||||
Kit_Graph_t * pGraph;
|
||||
assert( 0 <= iLeaf && iLeaf < nLeaves );
|
||||
pGraph = Kit_GraphCreate( nLeaves );
|
||||
pGraph->eRoot.Node = iLeaf;
|
||||
pGraph->eRoot.fCompl = fCompl;
|
||||
return pGraph;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates a graph with the given number of leaves.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Kit_GraphFree( Kit_Graph_t * pGraph )
|
||||
{
|
||||
FREE( pGraph->pNodes );
|
||||
free( pGraph );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Appends a new node to the graph.]
|
||||
|
||||
Description [This procedure is meant for internal use.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Kit_Node_t * Kit_GraphAppendNode( Kit_Graph_t * pGraph )
|
||||
{
|
||||
Kit_Node_t * pNode;
|
||||
if ( pGraph->nSize == pGraph->nCap )
|
||||
{
|
||||
pGraph->pNodes = REALLOC( Kit_Node_t, pGraph->pNodes, 2 * pGraph->nCap );
|
||||
pGraph->nCap = 2 * pGraph->nCap;
|
||||
}
|
||||
pNode = pGraph->pNodes + pGraph->nSize++;
|
||||
memset( pNode, 0, sizeof(Kit_Node_t) );
|
||||
return pNode;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates an AND node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Kit_Edge_t Kit_GraphAddNodeAnd( Kit_Graph_t * pGraph, Kit_Edge_t eEdge0, Kit_Edge_t eEdge1 )
|
||||
{
|
||||
Kit_Node_t * pNode;
|
||||
// get the new node
|
||||
pNode = Kit_GraphAppendNode( pGraph );
|
||||
// set the inputs and other info
|
||||
pNode->eEdge0 = eEdge0;
|
||||
pNode->eEdge1 = eEdge1;
|
||||
pNode->fCompl0 = eEdge0.fCompl;
|
||||
pNode->fCompl1 = eEdge1.fCompl;
|
||||
return Kit_EdgeCreate( pGraph->nSize - 1, 0 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates an OR node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Kit_Edge_t Kit_GraphAddNodeOr( Kit_Graph_t * pGraph, Kit_Edge_t eEdge0, Kit_Edge_t eEdge1 )
|
||||
{
|
||||
Kit_Node_t * pNode;
|
||||
// get the new node
|
||||
pNode = Kit_GraphAppendNode( pGraph );
|
||||
// set the inputs and other info
|
||||
pNode->eEdge0 = eEdge0;
|
||||
pNode->eEdge1 = eEdge1;
|
||||
pNode->fCompl0 = eEdge0.fCompl;
|
||||
pNode->fCompl1 = eEdge1.fCompl;
|
||||
// make adjustments for the OR gate
|
||||
pNode->fNodeOr = 1;
|
||||
pNode->eEdge0.fCompl = !pNode->eEdge0.fCompl;
|
||||
pNode->eEdge1.fCompl = !pNode->eEdge1.fCompl;
|
||||
return Kit_EdgeCreate( pGraph->nSize - 1, 1 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates an XOR node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Kit_Edge_t Kit_GraphAddNodeXor( Kit_Graph_t * pGraph, Kit_Edge_t eEdge0, Kit_Edge_t eEdge1, int Type )
|
||||
{
|
||||
Kit_Edge_t eNode0, eNode1, eNode;
|
||||
if ( Type == 0 )
|
||||
{
|
||||
// derive the first AND
|
||||
eEdge0.fCompl ^= 1;
|
||||
eNode0 = Kit_GraphAddNodeAnd( pGraph, eEdge0, eEdge1 );
|
||||
eEdge0.fCompl ^= 1;
|
||||
// derive the second AND
|
||||
eEdge1.fCompl ^= 1;
|
||||
eNode1 = Kit_GraphAddNodeAnd( pGraph, eEdge0, eEdge1 );
|
||||
// derive the final OR
|
||||
eNode = Kit_GraphAddNodeOr( pGraph, eNode0, eNode1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// derive the first AND
|
||||
eNode0 = Kit_GraphAddNodeAnd( pGraph, eEdge0, eEdge1 );
|
||||
// derive the second AND
|
||||
eEdge0.fCompl ^= 1;
|
||||
eEdge1.fCompl ^= 1;
|
||||
eNode1 = Kit_GraphAddNodeAnd( pGraph, eEdge0, eEdge1 );
|
||||
// derive the final OR
|
||||
eNode = Kit_GraphAddNodeOr( pGraph, eNode0, eNode1 );
|
||||
eNode.fCompl ^= 1;
|
||||
}
|
||||
return eNode;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates an XOR node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Kit_Edge_t Kit_GraphAddNodeMux( Kit_Graph_t * pGraph, Kit_Edge_t eEdgeC, Kit_Edge_t eEdgeT, Kit_Edge_t eEdgeE, int Type )
|
||||
{
|
||||
Kit_Edge_t eNode0, eNode1, eNode;
|
||||
if ( Type == 0 )
|
||||
{
|
||||
// derive the first AND
|
||||
eNode0 = Kit_GraphAddNodeAnd( pGraph, eEdgeC, eEdgeT );
|
||||
// derive the second AND
|
||||
eEdgeC.fCompl ^= 1;
|
||||
eNode1 = Kit_GraphAddNodeAnd( pGraph, eEdgeC, eEdgeE );
|
||||
// derive the final OR
|
||||
eNode = Kit_GraphAddNodeOr( pGraph, eNode0, eNode1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// complement the arguments
|
||||
eEdgeT.fCompl ^= 1;
|
||||
eEdgeE.fCompl ^= 1;
|
||||
// derive the first AND
|
||||
eNode0 = Kit_GraphAddNodeAnd( pGraph, eEdgeC, eEdgeT );
|
||||
// derive the second AND
|
||||
eEdgeC.fCompl ^= 1;
|
||||
eNode1 = Kit_GraphAddNodeAnd( pGraph, eEdgeC, eEdgeE );
|
||||
// derive the final OR
|
||||
eNode = Kit_GraphAddNodeOr( pGraph, eNode0, eNode1 );
|
||||
eNode.fCompl ^= 1;
|
||||
}
|
||||
return eNode;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives the truth table.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
unsigned Kit_GraphToTruth( Kit_Graph_t * pGraph )
|
||||
{
|
||||
unsigned uTruths[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 };
|
||||
unsigned uTruth, uTruth0, uTruth1;
|
||||
Kit_Node_t * pNode;
|
||||
int i;
|
||||
|
||||
// sanity checks
|
||||
assert( Kit_GraphLeaveNum(pGraph) >= 0 );
|
||||
assert( Kit_GraphLeaveNum(pGraph) <= pGraph->nSize );
|
||||
assert( Kit_GraphLeaveNum(pGraph) <= 5 );
|
||||
|
||||
// check for constant function
|
||||
if ( Kit_GraphIsConst(pGraph) )
|
||||
return Kit_GraphIsComplement(pGraph)? 0 : ~((unsigned)0);
|
||||
// check for a literal
|
||||
if ( Kit_GraphIsVar(pGraph) )
|
||||
return Kit_GraphIsComplement(pGraph)? ~uTruths[Kit_GraphVarInt(pGraph)] : uTruths[Kit_GraphVarInt(pGraph)];
|
||||
|
||||
// assign the elementary variables
|
||||
Kit_GraphForEachLeaf( pGraph, pNode, i )
|
||||
pNode->pFunc = (void *)uTruths[i];
|
||||
|
||||
// compute the function for each internal node
|
||||
Kit_GraphForEachNode( pGraph, pNode, i )
|
||||
{
|
||||
uTruth0 = (unsigned)Kit_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc;
|
||||
uTruth1 = (unsigned)Kit_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc;
|
||||
uTruth0 = pNode->eEdge0.fCompl? ~uTruth0 : uTruth0;
|
||||
uTruth1 = pNode->eEdge1.fCompl? ~uTruth1 : uTruth1;
|
||||
uTruth = uTruth0 & uTruth1;
|
||||
pNode->pFunc = (void *)uTruth;
|
||||
}
|
||||
|
||||
// complement the result if necessary
|
||||
return Kit_GraphIsComplement(pGraph)? ~uTruth : uTruth;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives the factored form from the truth table.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Kit_Graph_t * Kit_TruthToGraph( unsigned * pTruth, int nVars, Vec_Int_t * vMemory )
|
||||
{
|
||||
Kit_Graph_t * pGraph;
|
||||
int RetValue;
|
||||
// derive SOP
|
||||
RetValue = Kit_TruthIsop( pTruth, nVars, vMemory, 0 );
|
||||
assert( RetValue == 0 );
|
||||
// derive factored form
|
||||
pGraph = Kit_SopFactor( vMemory, 0, nVars, vMemory );
|
||||
return pGraph;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [kitHop.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Computation kit.]
|
||||
|
||||
Synopsis [Procedures involving AIGs.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - Dec 6, 2006.]
|
||||
|
||||
Revision [$Id: kitHop.c,v 1.00 2006/12/06 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "kit.h"
|
||||
#include "hop.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Transforms the decomposition graph into the AIG.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Hop_Obj_t * Kit_GraphToHopInternal( Hop_Man_t * pMan, Kit_Graph_t * pGraph )
|
||||
{
|
||||
Kit_Node_t * pNode;
|
||||
Hop_Obj_t * pAnd0, * pAnd1;
|
||||
int i;
|
||||
// check for constant function
|
||||
if ( Kit_GraphIsConst(pGraph) )
|
||||
return Hop_NotCond( Hop_ManConst1(pMan), Kit_GraphIsComplement(pGraph) );
|
||||
// check for a literal
|
||||
if ( Kit_GraphIsVar(pGraph) )
|
||||
return Hop_NotCond( Kit_GraphVar(pGraph)->pFunc, Kit_GraphIsComplement(pGraph) );
|
||||
// build the AIG nodes corresponding to the AND gates of the graph
|
||||
Kit_GraphForEachNode( pGraph, pNode, i )
|
||||
{
|
||||
pAnd0 = Hop_NotCond( Kit_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl );
|
||||
pAnd1 = Hop_NotCond( Kit_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl );
|
||||
pNode->pFunc = Hop_And( pMan, pAnd0, pAnd1 );
|
||||
}
|
||||
// complement the result if necessary
|
||||
return Hop_NotCond( pNode->pFunc, Kit_GraphIsComplement(pGraph) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Strashes one logic node using its SOP.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Hop_Obj_t * Kit_GraphToHop( Hop_Man_t * pMan, Kit_Graph_t * pGraph )
|
||||
{
|
||||
Kit_Node_t * pNode;
|
||||
int i;
|
||||
// collect the fanins
|
||||
Kit_GraphForEachLeaf( pGraph, pNode, i )
|
||||
pNode->pFunc = Hop_IthVar( pMan, i );
|
||||
// perform strashing
|
||||
return Kit_GraphToHopInternal( pMan, pGraph );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Strashes one logic node using its SOP.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Hop_Obj_t * Kit_CoverToHop( Hop_Man_t * pMan, Vec_Int_t * vCover, int nVars, Vec_Int_t * vMemory )
|
||||
{
|
||||
Kit_Graph_t * pGraph;
|
||||
Hop_Obj_t * pFunc;
|
||||
// perform factoring
|
||||
pGraph = Kit_SopFactor( vCover, 0, nVars, vMemory );
|
||||
// convert graph to the AIG
|
||||
pFunc = Kit_GraphToHop( pMan, pGraph );
|
||||
Kit_GraphFree( pGraph );
|
||||
return pFunc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -1,43 +1,35 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [ivyIsop.c]
|
||||
FileName [kitIsop.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [And-Inverter Graph package.]
|
||||
PackageName [Computation kit.]
|
||||
|
||||
Synopsis [Computing irredundant SOP using truth table.]
|
||||
Synopsis [ISOP computation based on Morreale's algorithm.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 11, 2006.]
|
||||
Date [Ver. 1.0. Started - Dec 6, 2006.]
|
||||
|
||||
Revision [$Id: ivyIsop.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
|
||||
Revision [$Id: kitIsop.c,v 1.00 2006/12/06 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "ivy.h"
|
||||
#include "kit.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ISOP computation fails if intermediate memory usage exceed this limit
|
||||
#define IVY_ISOP_MEM_LIMIT 16*4096
|
||||
|
||||
// intermediate ISOP representation
|
||||
typedef struct Ivy_Sop_t_ Ivy_Sop_t;
|
||||
struct Ivy_Sop_t_
|
||||
{
|
||||
unsigned * pCubes;
|
||||
int nCubes;
|
||||
};
|
||||
#define KIT_ISOP_MEM_LIMIT (1<<16)
|
||||
|
||||
// static procedures to compute ISOP
|
||||
static unsigned * Ivy_TruthIsop_rec( unsigned * puOn, unsigned * puOnDc, int nVars, Ivy_Sop_t * pcRes, Vec_Int_t * vStore );
|
||||
static unsigned Ivy_TruthIsop5_rec( unsigned uOn, unsigned uOnDc, int nVars, Ivy_Sop_t * pcRes, Vec_Int_t * vStore );
|
||||
static unsigned * Kit_TruthIsop_rec( unsigned * puOn, unsigned * puOnDc, int nVars, Kit_Sop_t * pcRes, Vec_Int_t * vStore );
|
||||
static unsigned Kit_TruthIsop5_rec( unsigned uOn, unsigned uOnDc, int nVars, Kit_Sop_t * pcRes, Vec_Int_t * vStore );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
|
|
@ -47,9 +39,9 @@ static unsigned Ivy_TruthIsop5_rec( unsigned uOn, unsigned uOnDc, int nVars, I
|
|||
|
||||
Synopsis [Computes ISOP from TT.]
|
||||
|
||||
Description [Returns the cover in vCover. Uses the rest of array in vCover
|
||||
Description [Returns the cover in vMemory. Uses the rest of array in vMemory
|
||||
as an intermediate memory storage. Returns the cover with -1 cubes, if the
|
||||
the computation exceeded the memory limit (IVY_ISOP_MEM_LIMIT words of
|
||||
the computation exceeded the memory limit (KIT_ISOP_MEM_LIMIT words of
|
||||
intermediate data).]
|
||||
|
||||
SideEffects []
|
||||
|
|
@ -57,10 +49,10 @@ static unsigned Ivy_TruthIsop5_rec( unsigned uOn, unsigned uOnDc, int nVars, I
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ivy_TruthIsop( unsigned * puTruth, int nVars, Vec_Int_t * vCover, int fTryBoth )
|
||||
int Kit_TruthIsop( unsigned * puTruth, int nVars, Vec_Int_t * vMemory, int fTryBoth )
|
||||
{
|
||||
Ivy_Sop_t cRes, * pcRes = &cRes;
|
||||
Ivy_Sop_t cRes2, * pcRes2 = &cRes2;
|
||||
Kit_Sop_t cRes, * pcRes = &cRes;
|
||||
Kit_Sop_t cRes2, * pcRes2 = &cRes2;
|
||||
unsigned * pResult;
|
||||
int RetValue = 0;
|
||||
assert( nVars >= 0 && nVars < 16 );
|
||||
|
|
@ -68,13 +60,13 @@ int Ivy_TruthIsop( unsigned * puTruth, int nVars, Vec_Int_t * vCover, int fTryBo
|
|||
// for ( i = nVars; i < 5; i++ )
|
||||
// assert( !Extra_TruthVarInSupport(puTruth, 5, i) );
|
||||
// prepare memory manager
|
||||
Vec_IntClear( vCover );
|
||||
Vec_IntGrow( vCover, IVY_ISOP_MEM_LIMIT );
|
||||
Vec_IntClear( vMemory );
|
||||
Vec_IntGrow( vMemory, KIT_ISOP_MEM_LIMIT );
|
||||
// compute ISOP for the direct polarity
|
||||
pResult = Ivy_TruthIsop_rec( puTruth, puTruth, nVars, pcRes, vCover );
|
||||
pResult = Kit_TruthIsop_rec( puTruth, puTruth, nVars, pcRes, vMemory );
|
||||
if ( pcRes->nCubes == -1 )
|
||||
{
|
||||
vCover->nSize = -1;
|
||||
vMemory->nSize = -1;
|
||||
return 0;
|
||||
}
|
||||
assert( Extra_TruthIsEqual( puTruth, pResult, nVars ) );
|
||||
|
|
@ -82,7 +74,7 @@ int Ivy_TruthIsop( unsigned * puTruth, int nVars, Vec_Int_t * vCover, int fTryBo
|
|||
{
|
||||
// compute ISOP for the complemented polarity
|
||||
Extra_TruthNot( puTruth, puTruth, nVars );
|
||||
pResult = Ivy_TruthIsop_rec( puTruth, puTruth, nVars, pcRes2, vCover );
|
||||
pResult = Kit_TruthIsop_rec( puTruth, puTruth, nVars, pcRes2, vMemory );
|
||||
if ( pcRes2->nCubes >= 0 )
|
||||
{
|
||||
assert( Extra_TruthIsEqual( puTruth, pResult, nVars ) );
|
||||
|
|
@ -94,10 +86,10 @@ int Ivy_TruthIsop( unsigned * puTruth, int nVars, Vec_Int_t * vCover, int fTryBo
|
|||
}
|
||||
Extra_TruthNot( puTruth, puTruth, nVars );
|
||||
}
|
||||
// printf( "%d ", vCover->nSize );
|
||||
// printf( "%d ", vMemory->nSize );
|
||||
// move the cover representation to the beginning of the memory buffer
|
||||
memmove( vCover->pArray, pcRes->pCubes, pcRes->nCubes * sizeof(unsigned) );
|
||||
Vec_IntShrink( vCover, pcRes->nCubes );
|
||||
memmove( vMemory->pArray, pcRes->pCubes, pcRes->nCubes * sizeof(unsigned) );
|
||||
Vec_IntShrink( vMemory, pcRes->nCubes );
|
||||
return RetValue;
|
||||
}
|
||||
|
||||
|
|
@ -112,10 +104,10 @@ int Ivy_TruthIsop( unsigned * puTruth, int nVars, Vec_Int_t * vCover, int fTryBo
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
unsigned * Ivy_TruthIsop_rec( unsigned * puOn, unsigned * puOnDc, int nVars, Ivy_Sop_t * pcRes, Vec_Int_t * vStore )
|
||||
unsigned * Kit_TruthIsop_rec( unsigned * puOn, unsigned * puOnDc, int nVars, Kit_Sop_t * pcRes, Vec_Int_t * vStore )
|
||||
{
|
||||
Ivy_Sop_t cRes0, cRes1, cRes2;
|
||||
Ivy_Sop_t * pcRes0 = &cRes0, * pcRes1 = &cRes1, * pcRes2 = &cRes2;
|
||||
Kit_Sop_t cRes0, cRes1, cRes2;
|
||||
Kit_Sop_t * pcRes0 = &cRes0, * pcRes1 = &cRes1, * pcRes2 = &cRes2;
|
||||
unsigned * puRes0, * puRes1, * puRes2;
|
||||
unsigned * puOn0, * puOn1, * puOnDc0, * puOnDc1, * pTemp, * pTemp0, * pTemp1;
|
||||
int i, k, Var, nWords, nWordsAll;
|
||||
|
|
@ -159,7 +151,7 @@ unsigned * Ivy_TruthIsop_rec( unsigned * puOn, unsigned * puOnDc, int nVars, Ivy
|
|||
// consider a simple case when one-word computation can be used
|
||||
if ( Var < 5 )
|
||||
{
|
||||
unsigned uRes = Ivy_TruthIsop5_rec( puOn[0], puOnDc[0], Var+1, pcRes, vStore );
|
||||
unsigned uRes = Kit_TruthIsop5_rec( puOn[0], puOnDc[0], Var+1, pcRes, vStore );
|
||||
for ( i = 0; i < nWordsAll; i++ )
|
||||
pTemp[i] = uRes;
|
||||
return pTemp;
|
||||
|
|
@ -172,14 +164,14 @@ unsigned * Ivy_TruthIsop_rec( unsigned * puOn, unsigned * puOnDc, int nVars, Ivy
|
|||
pTemp0 = pTemp; pTemp1 = pTemp + nWords;
|
||||
// solve for cofactors
|
||||
Extra_TruthSharp( pTemp0, puOn0, puOnDc1, Var );
|
||||
puRes0 = Ivy_TruthIsop_rec( pTemp0, puOnDc0, Var, pcRes0, vStore );
|
||||
puRes0 = Kit_TruthIsop_rec( pTemp0, puOnDc0, Var, pcRes0, vStore );
|
||||
if ( pcRes0->nCubes == -1 )
|
||||
{
|
||||
pcRes->nCubes = -1;
|
||||
return NULL;
|
||||
}
|
||||
Extra_TruthSharp( pTemp1, puOn1, puOnDc0, Var );
|
||||
puRes1 = Ivy_TruthIsop_rec( pTemp1, puOnDc1, Var, pcRes1, vStore );
|
||||
puRes1 = Kit_TruthIsop_rec( pTemp1, puOnDc1, Var, pcRes1, vStore );
|
||||
if ( pcRes1->nCubes == -1 )
|
||||
{
|
||||
pcRes->nCubes = -1;
|
||||
|
|
@ -189,7 +181,7 @@ unsigned * Ivy_TruthIsop_rec( unsigned * puOn, unsigned * puOnDc, int nVars, Ivy
|
|||
Extra_TruthSharp( pTemp1, puOn1, puRes1, Var );
|
||||
Extra_TruthOr( pTemp0, pTemp0, pTemp1, Var );
|
||||
Extra_TruthAnd( pTemp1, puOnDc0, puOnDc1, Var );
|
||||
puRes2 = Ivy_TruthIsop_rec( pTemp0, pTemp1, Var, pcRes2, vStore );
|
||||
puRes2 = Kit_TruthIsop_rec( pTemp0, pTemp1, Var, pcRes2, vStore );
|
||||
if ( pcRes2->nCubes == -1 )
|
||||
{
|
||||
pcRes->nCubes = -1;
|
||||
|
|
@ -205,9 +197,9 @@ unsigned * Ivy_TruthIsop_rec( unsigned * puOn, unsigned * puOnDc, int nVars, Ivy
|
|||
}
|
||||
k = 0;
|
||||
for ( i = 0; i < pcRes0->nCubes; i++ )
|
||||
pcRes->pCubes[k++] = pcRes0->pCubes[i] | (1 << ((Var<<1)+1));
|
||||
pcRes->pCubes[k++] = pcRes0->pCubes[i] | (1 << ((Var<<1)+0));
|
||||
for ( i = 0; i < pcRes1->nCubes; i++ )
|
||||
pcRes->pCubes[k++] = pcRes1->pCubes[i] | (1 << ((Var<<1)+0));
|
||||
pcRes->pCubes[k++] = pcRes1->pCubes[i] | (1 << ((Var<<1)+1));
|
||||
for ( i = 0; i < pcRes2->nCubes; i++ )
|
||||
pcRes->pCubes[k++] = pcRes2->pCubes[i];
|
||||
assert( k == pcRes->nCubes );
|
||||
|
|
@ -236,11 +228,11 @@ unsigned * Ivy_TruthIsop_rec( unsigned * puOn, unsigned * puOnDc, int nVars, Ivy
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
unsigned Ivy_TruthIsop5_rec( unsigned uOn, unsigned uOnDc, int nVars, Ivy_Sop_t * pcRes, Vec_Int_t * vStore )
|
||||
unsigned Kit_TruthIsop5_rec( unsigned uOn, unsigned uOnDc, int nVars, Kit_Sop_t * pcRes, Vec_Int_t * vStore )
|
||||
{
|
||||
unsigned uMasks[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 };
|
||||
Ivy_Sop_t cRes0, cRes1, cRes2;
|
||||
Ivy_Sop_t * pcRes0 = &cRes0, * pcRes1 = &cRes1, * pcRes2 = &cRes2;
|
||||
Kit_Sop_t cRes0, cRes1, cRes2;
|
||||
Kit_Sop_t * pcRes0 = &cRes0, * pcRes1 = &cRes1, * pcRes2 = &cRes2;
|
||||
unsigned uOn0, uOn1, uOnDc0, uOnDc1, uRes0, uRes1, uRes2;
|
||||
int i, k, Var;
|
||||
assert( nVars <= 5 );
|
||||
|
|
@ -278,19 +270,19 @@ unsigned Ivy_TruthIsop5_rec( unsigned uOn, unsigned uOnDc, int nVars, Ivy_Sop_t
|
|||
Extra_TruthCofactor0( &uOnDc0, Var + 1, Var );
|
||||
Extra_TruthCofactor1( &uOnDc1, Var + 1, Var );
|
||||
// solve for cofactors
|
||||
uRes0 = Ivy_TruthIsop5_rec( uOn0 & ~uOnDc1, uOnDc0, Var, pcRes0, vStore );
|
||||
uRes0 = Kit_TruthIsop5_rec( uOn0 & ~uOnDc1, uOnDc0, Var, pcRes0, vStore );
|
||||
if ( pcRes0->nCubes == -1 )
|
||||
{
|
||||
pcRes->nCubes = -1;
|
||||
return 0;
|
||||
}
|
||||
uRes1 = Ivy_TruthIsop5_rec( uOn1 & ~uOnDc0, uOnDc1, Var, pcRes1, vStore );
|
||||
uRes1 = Kit_TruthIsop5_rec( uOn1 & ~uOnDc0, uOnDc1, Var, pcRes1, vStore );
|
||||
if ( pcRes1->nCubes == -1 )
|
||||
{
|
||||
pcRes->nCubes = -1;
|
||||
return 0;
|
||||
}
|
||||
uRes2 = Ivy_TruthIsop5_rec( (uOn0 & ~uRes0) | (uOn1 & ~uRes1), uOnDc0 & uOnDc1, Var, pcRes2, vStore );
|
||||
uRes2 = Kit_TruthIsop5_rec( (uOn0 & ~uRes0) | (uOn1 & ~uRes1), uOnDc0 & uOnDc1, Var, pcRes2, vStore );
|
||||
if ( pcRes2->nCubes == -1 )
|
||||
{
|
||||
pcRes->nCubes = -1;
|
||||
|
|
@ -306,9 +298,9 @@ unsigned Ivy_TruthIsop5_rec( unsigned uOn, unsigned uOnDc, int nVars, Ivy_Sop_t
|
|||
}
|
||||
k = 0;
|
||||
for ( i = 0; i < pcRes0->nCubes; i++ )
|
||||
pcRes->pCubes[k++] = pcRes0->pCubes[i] | (1 << ((Var<<1)+1));
|
||||
pcRes->pCubes[k++] = pcRes0->pCubes[i] | (1 << ((Var<<1)+0));
|
||||
for ( i = 0; i < pcRes1->nCubes; i++ )
|
||||
pcRes->pCubes[k++] = pcRes1->pCubes[i] | (1 << ((Var<<1)+0));
|
||||
pcRes->pCubes[k++] = pcRes1->pCubes[i] | (1 << ((Var<<1)+1));
|
||||
for ( i = 0; i < pcRes2->nCubes; i++ )
|
||||
pcRes->pCubes[k++] = pcRes2->pCubes[i];
|
||||
assert( k == pcRes->nCubes );
|
||||
|
|
@ -0,0 +1,570 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [kitSop.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Computation kit.]
|
||||
|
||||
Synopsis [Procedures involving SOPs.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - Dec 6, 2006.]
|
||||
|
||||
Revision [$Id: kitSop.c,v 1.00 2006/12/06 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "kit.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates SOP from the cube array.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Kit_SopCreate( Kit_Sop_t * cResult, Vec_Int_t * vInput, int nVars, Vec_Int_t * vMemory )
|
||||
{
|
||||
unsigned uCube;
|
||||
int i;
|
||||
// start the cover
|
||||
cResult->nCubes = 0;
|
||||
cResult->pCubes = Vec_IntFetch( vMemory, Vec_IntSize(vInput) );
|
||||
// add the cubes
|
||||
Vec_IntForEachEntry( vInput, uCube, i )
|
||||
Kit_SopPushCube( cResult, uCube );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates SOP from the cube array.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Kit_SopCreateInverse( Kit_Sop_t * cResult, Vec_Int_t * vInput, int nLits, Vec_Int_t * vMemory )
|
||||
{
|
||||
unsigned uCube, uMask = 0;
|
||||
int i, nCubes = Vec_IntSize(vInput);
|
||||
// start the cover
|
||||
cResult->nCubes = 0;
|
||||
cResult->pCubes = Vec_IntFetch( vMemory, nCubes );
|
||||
// add the cubes
|
||||
// Vec_IntForEachEntry( vInput, uCube, i )
|
||||
for ( i = 0; i < nCubes; i++ )
|
||||
{
|
||||
uCube = Vec_IntEntry( vInput, i );
|
||||
uMask = ((uCube | (uCube >> 1)) & 0x55555555);
|
||||
uMask |= (uMask << 1);
|
||||
Kit_SopPushCube( cResult, uCube ^ uMask );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Duplicates SOP.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Kit_SopDup( Kit_Sop_t * cResult, Kit_Sop_t * cSop, Vec_Int_t * vMemory )
|
||||
{
|
||||
unsigned uCube;
|
||||
int i;
|
||||
// start the cover
|
||||
cResult->nCubes = 0;
|
||||
cResult->pCubes = Vec_IntFetch( vMemory, Kit_SopCubeNum(cSop) );
|
||||
// add the cubes
|
||||
Kit_SopForEachCube( cSop, uCube, i )
|
||||
Kit_SopPushCube( cResult, uCube );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives the quotient of division by literal.]
|
||||
|
||||
Description [Reduces the cover to be equal to the result of
|
||||
division of the given cover by the literal.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Kit_SopDivideByLiteralQuo( Kit_Sop_t * cSop, int iLit )
|
||||
{
|
||||
unsigned uCube;
|
||||
int i, k = 0;
|
||||
Kit_SopForEachCube( cSop, uCube, i )
|
||||
{
|
||||
if ( Kit_CubeHasLit(uCube, iLit) )
|
||||
Kit_SopWriteCube( cSop, Kit_CubeRemLit(uCube, iLit), k++ );
|
||||
}
|
||||
Kit_SopShrink( cSop, k );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Divides cover by one cube.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Kit_SopDivideByCube( Kit_Sop_t * cSop, Kit_Sop_t * cDiv, Kit_Sop_t * vQuo, Kit_Sop_t * vRem, Vec_Int_t * vMemory )
|
||||
{
|
||||
unsigned uCube, uDiv;
|
||||
int i;
|
||||
// get the only cube
|
||||
assert( Kit_SopCubeNum(cDiv) == 1 );
|
||||
uDiv = Kit_SopCube(cDiv, 0);
|
||||
// allocate covers
|
||||
vQuo->nCubes = 0;
|
||||
vQuo->pCubes = Vec_IntFetch( vMemory, Kit_SopCubeNum(cSop) );
|
||||
vRem->nCubes = 0;
|
||||
vRem->pCubes = Vec_IntFetch( vMemory, Kit_SopCubeNum(cSop) );
|
||||
// sort the cubes
|
||||
Kit_SopForEachCube( cSop, uCube, i )
|
||||
{
|
||||
if ( Kit_CubeContains( uCube, uDiv ) )
|
||||
Kit_SopPushCube( vQuo, Kit_CubeSharp(uCube, uDiv) );
|
||||
else
|
||||
Kit_SopPushCube( vRem, uCube );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Divides cover by one cube.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Kit_SopDivideInternal( Kit_Sop_t * cSop, Kit_Sop_t * cDiv, Kit_Sop_t * vQuo, Kit_Sop_t * vRem, Vec_Int_t * vMemory )
|
||||
{
|
||||
unsigned uCube, uDiv, uCube2, uDiv2, uQuo;
|
||||
int i, i2, k, k2, nCubesRem;
|
||||
assert( Kit_SopCubeNum(cSop) >= Kit_SopCubeNum(cDiv) );
|
||||
// consider special case
|
||||
if ( Kit_SopCubeNum(cDiv) == 1 )
|
||||
{
|
||||
Kit_SopDivideByCube( cSop, cDiv, vQuo, vRem, vMemory );
|
||||
return;
|
||||
}
|
||||
// allocate quotient
|
||||
vQuo->nCubes = 0;
|
||||
vQuo->pCubes = Vec_IntFetch( vMemory, Kit_SopCubeNum(cSop) / Kit_SopCubeNum(cDiv) );
|
||||
// for each cube of the cover
|
||||
// it either belongs to the quotient or to the remainder
|
||||
Kit_SopForEachCube( cSop, uCube, i )
|
||||
{
|
||||
// skip taken cubes
|
||||
if ( Kit_CubeIsMarked(uCube) )
|
||||
continue;
|
||||
// find a matching cube in the divisor
|
||||
Kit_SopForEachCube( cDiv, uDiv, k )
|
||||
if ( Kit_CubeContains( uCube, uDiv ) )
|
||||
break;
|
||||
// the cube is not found
|
||||
if ( k == Kit_SopCubeNum(cDiv) )
|
||||
continue;
|
||||
// the quotient cube exists
|
||||
uQuo = Kit_CubeSharp( uCube, uDiv );
|
||||
// find corresponding cubes for other cubes of the divisor
|
||||
Kit_SopForEachCube( cDiv, uDiv2, k2 )
|
||||
{
|
||||
if ( k2 == k )
|
||||
continue;
|
||||
// find a matching cube
|
||||
Kit_SopForEachCube( cSop, uCube2, i2 )
|
||||
{
|
||||
// skip taken cubes
|
||||
if ( Kit_CubeIsMarked(uCube2) )
|
||||
continue;
|
||||
// check if the cube can be used
|
||||
if ( Kit_CubeContains( uCube2, uDiv2 ) && uQuo == Kit_CubeSharp( uCube2, uDiv2 ) )
|
||||
break;
|
||||
}
|
||||
// the case when the cube is not found
|
||||
if ( i2 == Kit_SopCubeNum(cSop) )
|
||||
break;
|
||||
}
|
||||
// we did not find some cubes - continue looking at other cubes
|
||||
if ( k2 != Kit_SopCubeNum(cDiv) )
|
||||
continue;
|
||||
// we found all cubes - add the quotient cube
|
||||
Kit_SopPushCube( vQuo, uQuo );
|
||||
|
||||
// mark the first cube
|
||||
Kit_SopWriteCube( cSop, Kit_CubeMark(uCube), i );
|
||||
// mark other cubes that have this quotient
|
||||
Kit_SopForEachCube( cDiv, uDiv2, k2 )
|
||||
{
|
||||
if ( k2 == k )
|
||||
continue;
|
||||
// find a matching cube
|
||||
Kit_SopForEachCube( cSop, uCube2, i2 )
|
||||
{
|
||||
// skip taken cubes
|
||||
if ( Kit_CubeIsMarked(uCube2) )
|
||||
continue;
|
||||
// check if the cube can be used
|
||||
if ( Kit_CubeContains( uCube2, uDiv2 ) && uQuo == Kit_CubeSharp( uCube2, uDiv2 ) )
|
||||
break;
|
||||
}
|
||||
assert( i2 < Kit_SopCubeNum(cSop) );
|
||||
// the cube is found, mark it
|
||||
// (later we will add all unmarked cubes to the remainder)
|
||||
Kit_SopWriteCube( cSop, Kit_CubeMark(uCube2), i2 );
|
||||
}
|
||||
}
|
||||
// determine the number of cubes in the remainder
|
||||
nCubesRem = Kit_SopCubeNum(cSop) - Kit_SopCubeNum(vQuo) * Kit_SopCubeNum(cDiv);
|
||||
// allocate remainder
|
||||
vRem->nCubes = 0;
|
||||
vRem->pCubes = Vec_IntFetch( vMemory, nCubesRem );
|
||||
// finally add the remaining unmarked cubes to the remainder
|
||||
// and clean the marked cubes in the cover
|
||||
Kit_SopForEachCube( cSop, uCube, i )
|
||||
{
|
||||
if ( !Kit_CubeIsMarked(uCube) )
|
||||
{
|
||||
Kit_SopPushCube( vRem, uCube );
|
||||
continue;
|
||||
}
|
||||
Kit_SopWriteCube( cSop, Kit_CubeUnmark(uCube), i );
|
||||
}
|
||||
assert( nCubesRem == Kit_SopCubeNum(vRem) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the common cube.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline unsigned Kit_SopCommonCube( Kit_Sop_t * cSop )
|
||||
{
|
||||
unsigned uMask, uCube;
|
||||
int i;
|
||||
uMask = ~(unsigned)0;
|
||||
Kit_SopForEachCube( cSop, uCube, i )
|
||||
uMask &= uCube;
|
||||
return uMask;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Makes the cover cube-free.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Kit_SopMakeCubeFree( Kit_Sop_t * cSop )
|
||||
{
|
||||
unsigned uMask, uCube;
|
||||
int i;
|
||||
uMask = Kit_SopCommonCube( cSop );
|
||||
if ( uMask == 0 )
|
||||
return;
|
||||
// remove the common cube
|
||||
Kit_SopForEachCube( cSop, uCube, i )
|
||||
Kit_SopWriteCube( cSop, Kit_CubeSharp(uCube, uMask), i );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks if the cover is cube-free.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Kit_SopIsCubeFree( Kit_Sop_t * cSop )
|
||||
{
|
||||
return Kit_SopCommonCube( cSop ) == 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates SOP composes of the common cube of the given SOP.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Kit_SopCommonCubeCover( Kit_Sop_t * cResult, Kit_Sop_t * cSop, Vec_Int_t * vMemory )
|
||||
{
|
||||
assert( Kit_SopCubeNum(cSop) > 0 );
|
||||
cResult->nCubes = 0;
|
||||
cResult->pCubes = Vec_IntFetch( vMemory, 1 );
|
||||
Kit_SopPushCube( cResult, Kit_SopCommonCube(cSop) );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find any literal that occurs more than once.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Kit_SopAnyLiteral( Kit_Sop_t * cSop, int nLits )
|
||||
{
|
||||
unsigned uCube;
|
||||
int i, k, nLitsCur;
|
||||
// go through each literal
|
||||
for ( i = 0; i < nLits; i++ )
|
||||
{
|
||||
// go through all the cubes
|
||||
nLitsCur = 0;
|
||||
Kit_SopForEachCube( cSop, uCube, k )
|
||||
if ( Kit_CubeHasLit(uCube, i) )
|
||||
nLitsCur++;
|
||||
if ( nLitsCur > 1 )
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find the least often occurring literal.]
|
||||
|
||||
Description [Find the least often occurring literal among those
|
||||
that occur more than once.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Kit_SopWorstLiteral( Kit_Sop_t * cSop, int nLits )
|
||||
{
|
||||
unsigned uCube;
|
||||
int i, k, iMin, nLitsMin, nLitsCur;
|
||||
int fUseFirst = 1;
|
||||
|
||||
// go through each literal
|
||||
iMin = -1;
|
||||
nLitsMin = 1000000;
|
||||
for ( i = 0; i < nLits; i++ )
|
||||
{
|
||||
// go through all the cubes
|
||||
nLitsCur = 0;
|
||||
Kit_SopForEachCube( cSop, uCube, k )
|
||||
if ( Kit_CubeHasLit(uCube, i) )
|
||||
nLitsCur++;
|
||||
// skip the literal that does not occur or occurs once
|
||||
if ( nLitsCur < 2 )
|
||||
continue;
|
||||
// check if this is the best literal
|
||||
if ( fUseFirst )
|
||||
{
|
||||
if ( nLitsMin > nLitsCur )
|
||||
{
|
||||
nLitsMin = nLitsCur;
|
||||
iMin = i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( nLitsMin >= nLitsCur )
|
||||
{
|
||||
nLitsMin = nLitsCur;
|
||||
iMin = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( nLitsMin < 1000000 )
|
||||
return iMin;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find the least often occurring literal.]
|
||||
|
||||
Description [Find the least often occurring literal among those
|
||||
that occur more than once.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Kit_SopBestLiteral( Kit_Sop_t * cSop, int nLits, unsigned uMask )
|
||||
{
|
||||
unsigned uCube;
|
||||
int i, k, iMax, nLitsMax, nLitsCur;
|
||||
int fUseFirst = 1;
|
||||
|
||||
// go through each literal
|
||||
iMax = -1;
|
||||
nLitsMax = -1;
|
||||
for ( i = 0; i < nLits; i++ )
|
||||
{
|
||||
if ( !Kit_CubeHasLit(uMask, i) )
|
||||
continue;
|
||||
// go through all the cubes
|
||||
nLitsCur = 0;
|
||||
Kit_SopForEachCube( cSop, uCube, k )
|
||||
if ( Kit_CubeHasLit(uCube, i) )
|
||||
nLitsCur++;
|
||||
// skip the literal that does not occur or occurs once
|
||||
if ( nLitsCur < 2 )
|
||||
continue;
|
||||
// check if this is the best literal
|
||||
if ( fUseFirst )
|
||||
{
|
||||
if ( nLitsMax < nLitsCur )
|
||||
{
|
||||
nLitsMax = nLitsCur;
|
||||
iMax = i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( nLitsMax <= nLitsCur )
|
||||
{
|
||||
nLitsMax = nLitsCur;
|
||||
iMax = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( nLitsMax >= 0 )
|
||||
return iMax;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes a level-zero kernel.]
|
||||
|
||||
Description [Modifies the cover to contain one level-zero kernel.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Kit_SopDivisorZeroKernel_rec( Kit_Sop_t * cSop, int nLits )
|
||||
{
|
||||
int iLit;
|
||||
// find any literal that occurs at least two times
|
||||
iLit = Kit_SopWorstLiteral( cSop, nLits );
|
||||
if ( iLit == -1 )
|
||||
return;
|
||||
// derive the cube-free quotient
|
||||
Kit_SopDivideByLiteralQuo( cSop, iLit ); // the same cover
|
||||
Kit_SopMakeCubeFree( cSop ); // the same cover
|
||||
// call recursively
|
||||
Kit_SopDivisorZeroKernel_rec( cSop, nLits ); // the same cover
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the quick divisor of the cover.]
|
||||
|
||||
Description [Returns 0, if there is no divisor other than trivial.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Kit_SopDivisor( Kit_Sop_t * cResult, Kit_Sop_t * cSop, int nLits, Vec_Int_t * vMemory )
|
||||
{
|
||||
if ( Kit_SopCubeNum(cSop) <= 1 )
|
||||
return 0;
|
||||
if ( Kit_SopAnyLiteral( cSop, nLits ) == -1 )
|
||||
return 0;
|
||||
// duplicate the cover
|
||||
Kit_SopDup( cResult, cSop, vMemory );
|
||||
// perform the kerneling
|
||||
Kit_SopDivisorZeroKernel_rec( cResult, nLits );
|
||||
assert( Kit_SopCubeNum(cResult) > 0 );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Create the one-literal cover with the best literal from cSop.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Kit_SopBestLiteralCover( Kit_Sop_t * cResult, Kit_Sop_t * cSop, unsigned uCube, int nLits, Vec_Int_t * vMemory )
|
||||
{
|
||||
int iLitBest;
|
||||
// get the best literal
|
||||
iLitBest = Kit_SopBestLiteral( cSop, nLits, uCube );
|
||||
// start the cover
|
||||
cResult->nCubes = 0;
|
||||
cResult->pCubes = Vec_IntFetch( vMemory, 1 );
|
||||
// set the cube
|
||||
Kit_SopPushCube( cResult, Kit_CubeSetLit(0, iLitBest) );
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,48 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [kit_.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Computation kit.]
|
||||
|
||||
Synopsis []
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - Dec 6, 2006.]
|
||||
|
||||
Revision [$Id: kit_.c,v 1.00 2006/12/06 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "kit.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
SRC += src/opt/kit/kitBdd.c \
|
||||
src/opt/kit/kitFactor.c \
|
||||
src/opt/kit/kitGraph.c \
|
||||
src/opt/kit/kitHop.c \
|
||||
src/opt/kit/kitIsop.c \
|
||||
src/opt/kit/kitSop.c \
|
||||
src/opt/kit/kitTruth.c
|
||||
|
|
@ -801,14 +801,14 @@ void sat_solver_reducedb(sat_solver* s)
|
|||
vecp_resize(&s->learnts,j);
|
||||
}
|
||||
|
||||
static lbool sat_solver_search(sat_solver* s, int nof_conflicts, int nof_learnts)
|
||||
static lbool sat_solver_search(sat_solver* s, sint64 nof_conflicts, sint64 nof_learnts)
|
||||
{
|
||||
int* levels = s->levels;
|
||||
double var_decay = 0.95;
|
||||
double clause_decay = 0.999;
|
||||
double random_var_freq = 0.02;
|
||||
|
||||
int conflictC = 0;
|
||||
sint64 conflictC = 0;
|
||||
veci learnt_clause;
|
||||
int i;
|
||||
|
||||
|
|
@ -1118,8 +1118,8 @@ bool sat_solver_simplify(sat_solver* s)
|
|||
|
||||
int sat_solver_solve(sat_solver* s, lit* begin, lit* end, sint64 nConfLimit, sint64 nInsLimit, sint64 nConfLimitGlobal, sint64 nInsLimitGlobal)
|
||||
{
|
||||
double nof_conflicts = 100;
|
||||
double nof_learnts = sat_solver_nclauses(s) / 3;
|
||||
sint64 nof_conflicts = 100;
|
||||
sint64 nof_learnts = sat_solver_nclauses(s) / 3;
|
||||
lbool status = l_Undef;
|
||||
lbool* values = s->assigns;
|
||||
lit* i;
|
||||
|
|
@ -1178,9 +1178,9 @@ int sat_solver_solve(sat_solver* s, lit* begin, lit* end, sint64 nConfLimit, sin
|
|||
s->progress_estimate*100);
|
||||
fflush(stdout);
|
||||
}
|
||||
status = sat_solver_search(s,(int)nof_conflicts, (int)nof_learnts);
|
||||
nof_conflicts *= 1.5;
|
||||
nof_learnts *= 1.1;
|
||||
status = sat_solver_search(s, nof_conflicts, nof_learnts);
|
||||
nof_conflicts = nof_conflicts * 3 / 2; //*= 1.5;
|
||||
nof_learnts = nof_learnts * 11 / 10; //*= 1.1;
|
||||
|
||||
// quit the loop if reached an external limit
|
||||
if ( s->nConfLimit && s->stats.conflicts > s->nConfLimit )
|
||||
|
|
|
|||
Loading…
Reference in New Issue