mirror of https://github.com/YosysHQ/abc.git
Version abc50806
This commit is contained in:
parent
888e5bed5d
commit
d0e834d1a6
68
abc.dsp
68
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\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\sop\mvc" /I "src\sop\ft" /I "src\sat\asat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\fxa" /I "src\map\fpga" /I "src\map\mapper" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\util" /I "src\misc\vec" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D "HAVE_ASSERT_H" /FR /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /O2 /I "src\base\abc" /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\mvc" /I "src\sop\ft" /I "src\sat\asat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\fxa" /I "src\opt\fxu" /I "src\map\fpga" /I "src\map\mapper" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\util" /I "src\misc\vec" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D "HAVE_ASSERT_H" /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\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\sop\mvc" /I "src\sop\ft" /I "src\sat\asat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\fxa" /I "src\map\fpga" /I "src\map\mapper" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\util" /I "src\misc\vec" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D "HAVE_ASSERT_H" /FR /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "src\base\abc" /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\mvc" /I "src\sop\ft" /I "src\sat\asat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\fxa" /I "src\opt\fxu" /I "src\map\fpga" /I "src\map\mapper" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\util" /I "src\misc\vec" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D "HAVE_ASSERT_H" /FR /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
|
|
@ -145,6 +145,10 @@ SOURCE=.\src\base\abc\abcFunc.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\base\abc\abcFxu.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\base\abc\abcInt.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
@ -964,6 +968,66 @@ SOURCE=.\src\sat\fraig\fraigVec.c
|
|||
|
||||
# PROP Default_Filter ""
|
||||
# End Group
|
||||
# Begin Group "fxu"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\fxu\fxu.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\fxu\fxu.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\fxu\fxuCreate.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\fxu\fxuHeapD.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\fxu\fxuHeapS.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\fxu\fxuInt.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\fxu\fxuList.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\fxu\fxuMatrix.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\fxu\fxuPair.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\fxu\fxuPrint.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\fxu\fxuReduce.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\fxu\fxuSelect.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\fxu\fxuSingle.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\fxu\fxuUpdate.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Group
|
||||
# Begin Group "map"
|
||||
|
||||
|
|
|
|||
2
abc.rc
2
abc.rc
|
|
@ -11,7 +11,7 @@ alias r read
|
|||
alias rl read_blif
|
||||
alias rb read_bench
|
||||
alias rv read_verilog
|
||||
alias rsup read_super
|
||||
alias rsup read_super mcnc5_old.super
|
||||
alias rlib read_library
|
||||
alias sa set autoexec ps
|
||||
alias so source -x
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include "mainInt.h"
|
||||
#include "ft.h"
|
||||
#include "fraig.h"
|
||||
#include "fxu.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
|
|
@ -37,6 +38,7 @@ static int Ntk_CommandStrash ( Abc_Frame_t * pAbc, int argc, char ** argv
|
|||
static int Ntk_CommandBalance ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Ntk_CommandRenode ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Ntk_CommandCleanup ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Ntk_CommandFx ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
|
||||
static int Ntk_CommandLogic ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Ntk_CommandMiter ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
|
|
@ -55,6 +57,7 @@ static int Ntk_CommandFraigSweep ( Abc_Frame_t * pAbc, int argc, char ** argv
|
|||
static int Ntk_CommandMap ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Ntk_CommandUnmap ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Ntk_CommandAttach ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Ntk_CommandSuperChoice ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
|
||||
static int Ntk_CommandFpga ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
|
||||
|
|
@ -88,6 +91,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
|
|||
Cmd_CommandAdd( pAbc, "Synthesis", "balance", Ntk_CommandBalance, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Synthesis", "renode", Ntk_CommandRenode, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Synthesis", "cleanup", Ntk_CommandCleanup, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Synthesis", "fx", Ntk_CommandFx, 1 );
|
||||
|
||||
Cmd_CommandAdd( pAbc, "Various", "logic", Ntk_CommandLogic, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Various", "miter", Ntk_CommandMiter, 1 );
|
||||
|
|
@ -106,6 +110,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
|
|||
Cmd_CommandAdd( pAbc, "SC mapping", "map", Ntk_CommandMap, 1 );
|
||||
Cmd_CommandAdd( pAbc, "SC mapping", "unmap", Ntk_CommandUnmap, 1 );
|
||||
Cmd_CommandAdd( pAbc, "SC mapping", "attach", Ntk_CommandAttach, 1 );
|
||||
Cmd_CommandAdd( pAbc, "SC mapping", "sc", Ntk_CommandSuperChoice, 1 );
|
||||
|
||||
Cmd_CommandAdd( pAbc, "FPGA mapping", "fpga", Ntk_CommandFpga, 1 );
|
||||
|
||||
|
|
@ -750,6 +755,127 @@ usage:
|
|||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ntk_CommandFx( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
Abc_Ntk_t * pNtk;
|
||||
FILE * pOut, * pErr;
|
||||
Fxu_Data_t * p = NULL;
|
||||
int c;
|
||||
extern bool Abc_NtkFastExtract( Abc_Ntk_t * pNtk, Fxu_Data_t * p );
|
||||
extern void Abc_NtkFxuFreeInfo( Fxu_Data_t * p );
|
||||
|
||||
pNtk = Abc_FrameReadNet(pAbc);
|
||||
pOut = Abc_FrameReadOut(pAbc);
|
||||
pErr = Abc_FrameReadErr(pAbc);
|
||||
|
||||
// allocate the structure
|
||||
p = ALLOC( Fxu_Data_t, 1 );
|
||||
memset( p, 0, sizeof(Fxu_Data_t) );
|
||||
// set the defaults
|
||||
p->nPairsMax = 30000;
|
||||
p->nNodesExt = 10000;
|
||||
p->fOnlyS = 0;
|
||||
p->fOnlyD = 0;
|
||||
p->fUse0 = 0;
|
||||
p->fUseCompl = 1;
|
||||
p->fVerbose = 0;
|
||||
util_getopt_reset();
|
||||
while ( (c = util_getopt(argc, argv, "lnsdzcvh")) != EOF )
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'l':
|
||||
if ( util_optind >= argc )
|
||||
{
|
||||
fprintf( pErr, "Command line switch \"-l\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
p->nPairsMax = atoi(argv[util_optind]);
|
||||
util_optind++;
|
||||
if ( p->nPairsMax < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'n':
|
||||
if ( util_optind >= argc )
|
||||
{
|
||||
fprintf( pErr, "Command line switch \"-n\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
p->nNodesExt = atoi(argv[util_optind]);
|
||||
util_optind++;
|
||||
if ( p->nNodesExt < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 's':
|
||||
p->fOnlyS ^= 1;
|
||||
break;
|
||||
case 'd':
|
||||
p->fOnlyD ^= 1;
|
||||
break;
|
||||
case 'z':
|
||||
p->fUse0 ^= 1;
|
||||
break;
|
||||
case 'c':
|
||||
p->fUseCompl ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
p->fVerbose ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
break;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
|
||||
if ( pNtk == NULL )
|
||||
{
|
||||
fprintf( pErr, "Empty network.\n" );
|
||||
Abc_NtkFxuFreeInfo( p );
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( Abc_NtkNodeNum(pNtk) == 0 )
|
||||
{
|
||||
fprintf( pErr, "The network does not have internal nodes.\n" );
|
||||
Abc_NtkFxuFreeInfo( p );
|
||||
return 1;
|
||||
}
|
||||
|
||||
// the nodes to be merged are linked into the special linked list
|
||||
Abc_NtkFastExtract( pNtk, p );
|
||||
Abc_NtkFxuFreeInfo( p );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pErr, "usage: fx [-n num] [-l num] [-sdzcvh]\n");
|
||||
fprintf( pErr, "\t performs unate fast extract on the current network\n");
|
||||
fprintf( pErr, "\t-n num : the maximum number of divisors to extract [default = %d]\n", p->nNodesExt );
|
||||
fprintf( pErr, "\t-l num : the maximum number of cube pairs to consider [default = %d]\n", p->nPairsMax );
|
||||
fprintf( pErr, "\t-s : use only single-cube divisors [default = %s]\n", p->fOnlyS? "yes": "no" );
|
||||
fprintf( pErr, "\t-d : use only double-cube divisors [default = %s]\n", p->fOnlyD? "yes": "no" );
|
||||
fprintf( pErr, "\t-z : use zero-weight divisors [default = %s]\n", p->fUse0? "yes": "no" );
|
||||
fprintf( pErr, "\t-c : use complement in the binary case [default = %s]\n", p->fUseCompl? "yes": "no" );
|
||||
fprintf( pErr, "\t-v : print verbose information [default = %s]\n", p->fVerbose? "yes": "no" );
|
||||
fprintf( pErr, "\t-h : print the command usage\n");
|
||||
Abc_NtkFxuFreeInfo( p );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -1189,6 +1315,7 @@ int Ntk_CommandFraig( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
Fraig_Params_t Params;
|
||||
FILE * pOut, * pErr;
|
||||
Abc_Ntk_t * pNtk, * pNtkRes;
|
||||
int fAllNodes;
|
||||
int c;
|
||||
|
||||
pNtk = Abc_FrameReadNet(pAbc);
|
||||
|
|
@ -1196,6 +1323,7 @@ int Ntk_CommandFraig( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
pErr = Abc_FrameReadErr(pAbc);
|
||||
|
||||
// set defaults
|
||||
fAllNodes = 0;
|
||||
Params.nPatsRand = 2048; // the number of words of random simulation info
|
||||
Params.nPatsDyna = 2048; // the number of words of dynamic simulation info
|
||||
Params.nBTLimit = 99; // the max number of backtracks to perform
|
||||
|
|
@ -1208,7 +1336,7 @@ int Ntk_CommandFraig( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
Params.fVerbose = 0; // the verbosiness flag
|
||||
Params.fVerboseP = 0; // the verbosiness flag
|
||||
util_getopt_reset();
|
||||
while ( ( c = util_getopt( argc, argv, "RDBrscpvh" ) ) != EOF )
|
||||
while ( ( c = util_getopt( argc, argv, "RDBrscpvah" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
|
|
@ -1262,7 +1390,9 @@ int Ntk_CommandFraig( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
case 'v':
|
||||
Params.fVerbose ^= 1;
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
fAllNodes ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
|
|
@ -1286,11 +1416,11 @@ int Ntk_CommandFraig( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
|
||||
// get the new network
|
||||
if ( Abc_NtkIsAig(pNtk) )
|
||||
pNtkRes = Abc_NtkFraig( pNtk, &Params, 0 );
|
||||
pNtkRes = Abc_NtkFraig( pNtk, &Params, fAllNodes );
|
||||
else
|
||||
{
|
||||
pNtk = Abc_NtkStrash( pNtk );
|
||||
pNtkRes = Abc_NtkFraig( pNtk, &Params, 0 );
|
||||
pNtkRes = Abc_NtkFraig( pNtk, &Params, fAllNodes );
|
||||
Abc_NtkDelete( pNtk );
|
||||
}
|
||||
if ( pNtkRes == NULL )
|
||||
|
|
@ -1308,7 +1438,7 @@ int Ntk_CommandFraig( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
|
||||
usage:
|
||||
sprintf( Buffer, "%d", Params.nBTLimit );
|
||||
fprintf( pErr, "usage: fraig [-R num] [-D num] [-B num] [-rscpvh]\n" );
|
||||
fprintf( pErr, "usage: fraig [-R num] [-D num] [-B num] [-rscpvah]\n" );
|
||||
fprintf( pErr, "\t transforms a logic network into a functionally reduced AIG\n" );
|
||||
fprintf( pErr, "\t-R num : number of random patterns (127 < num < 32769) [default = %d]\n", Params.nPatsRand );
|
||||
fprintf( pErr, "\t-D num : number of systematic patterns (127 < num < 32769) [default = %d]\n", Params.nPatsDyna );
|
||||
|
|
@ -1318,6 +1448,7 @@ usage:
|
|||
fprintf( pErr, "\t-c : toggle accumulation of choices [default = %s]\n", Params.fChoicing? "yes": "no" );
|
||||
fprintf( pErr, "\t-p : toggle proving the final miter [default = %s]\n", Params.fTryProve? "yes": "no" );
|
||||
fprintf( pErr, "\t-v : toggle verbose output [default = %s]\n", Params.fVerbose? "yes": "no" );
|
||||
fprintf( pErr, "\t-a : toggle between all nodes and DFS nodes [default = %s]\n", fAllNodes? "all": "dfs" );
|
||||
fprintf( pErr, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -1890,6 +2021,72 @@ usage:
|
|||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Ntk_CommandSuperChoice( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
FILE * pOut, * pErr;
|
||||
Abc_Ntk_t * pNtk, * pNtkRes;
|
||||
int c;
|
||||
extern Abc_Ntk_t * Abc_NtkSuperChoice( Abc_Ntk_t * pNtk );
|
||||
|
||||
pNtk = Abc_FrameReadNet(pAbc);
|
||||
pOut = Abc_FrameReadOut(pAbc);
|
||||
pErr = Abc_FrameReadErr(pAbc);
|
||||
|
||||
// set defaults
|
||||
util_getopt_reset();
|
||||
while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
|
||||
if ( pNtk == NULL )
|
||||
{
|
||||
fprintf( pErr, "Empty network.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( !Abc_NtkIsAig(pNtk) )
|
||||
{
|
||||
fprintf( pErr, "Works only for the AIG representation.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
// get the new network
|
||||
pNtkRes = Abc_NtkSuperChoice( pNtk );
|
||||
if ( pNtkRes == NULL )
|
||||
{
|
||||
fprintf( pErr, "Superchoicing has failed.\n" );
|
||||
return 1;
|
||||
}
|
||||
// replace the current network
|
||||
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pErr, "usage: sc [-h]\n" );
|
||||
fprintf( pErr, "\t performs superchoicing\n" );
|
||||
fprintf( pErr, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
|
|||
|
|
@ -480,6 +480,7 @@ extern bool Abc_NtkMiterSat( Abc_Ntk_t * pNtk, int fVerbose );
|
|||
extern solver * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk );
|
||||
/*=== abcSop.c ==========================================================*/
|
||||
extern char * Abc_SopRegister( Extra_MmFlex_t * pMan, char * pName );
|
||||
extern char * Abc_SopStart( Extra_MmFlex_t * pMan, int nCubes, int nVars );
|
||||
extern int Abc_SopGetCubeNum( char * pSop );
|
||||
extern int Abc_SopGetLitNum( char * pSop );
|
||||
extern int Abc_SopGetVarNum( char * pSop );
|
||||
|
|
|
|||
|
|
@ -267,6 +267,8 @@ void Abc_AttachComputeTruth( char * pSop, unsigned uTruthsIn[][2], unsigned * uT
|
|||
}
|
||||
uTruthRes[0] |= uSignCube[0];
|
||||
}
|
||||
if ( Abc_SopGetPhase(pSop) == 0 )
|
||||
uTruthRes[0] = ~uTruthRes[0];
|
||||
if ( nInputs < 5 )
|
||||
uTruthRes[0] &= ATTACH_MASK(1<<nInputs);
|
||||
}
|
||||
|
|
@ -295,6 +297,13 @@ void Abc_AttachComputeTruth( char * pSop, unsigned uTruthsIn[][2], unsigned * uT
|
|||
uTruthRes[0] |= uSignCube[0];
|
||||
uTruthRes[1] |= uSignCube[1];
|
||||
}
|
||||
|
||||
// complement if the SOP is complemented
|
||||
if ( Abc_SopGetPhase(pSop) == 0 )
|
||||
{
|
||||
uTruthRes[0] = ~uTruthRes[0];
|
||||
uTruthRes[1] = ~uTruthRes[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -223,9 +223,12 @@ int Abc_NtkGetLevelNum( Abc_Ntk_t * pNtk )
|
|||
}
|
||||
else
|
||||
{
|
||||
Abc_NtkForEachCo( pNtk, pNode, i )
|
||||
// Abc_NtkForEachCo( pNtk, pNode, i )
|
||||
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||
{
|
||||
pDriver = Abc_ObjFanin0( pNode );
|
||||
// pDriver = Abc_ObjFanin0( pNode );
|
||||
pDriver = pNode;
|
||||
|
||||
Abc_NtkGetLevelNum_rec( pDriver );
|
||||
if ( LevelsMax < pDriver->Level )
|
||||
LevelsMax = pDriver->Level;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,262 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [abcFxu.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Network and node package.]
|
||||
|
||||
Synopsis [Interface with the fast extract package.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: abcFxu.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "abc.h"
|
||||
#include "fxu.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool Abc_NtkFxuCheck( Abc_Ntk_t * pNtk );
|
||||
static void Abc_NtkFxuCollectInfo( Abc_Ntk_t * pNtk, Fxu_Data_t * p );
|
||||
static void Abc_NtkFxuReconstruct( Abc_Ntk_t * pNtk, Fxu_Data_t * p );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs fast_extract on the current network.]
|
||||
|
||||
Description [Takes the network and the maximum number of nodes to extract.
|
||||
Uses the concurrent double-cube and single cube divisor extraction procedure.
|
||||
Modifies the network in the end, after extracting all nodes. Note that
|
||||
Ntk_NetworkSweep() may increase the performance of this procedure because
|
||||
the single-literal nodes will not be created in the sparse matrix. Returns 1
|
||||
if the network has been changed.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
bool Abc_NtkFastExtract( Abc_Ntk_t * pNtk, Fxu_Data_t * p )
|
||||
{
|
||||
assert( Abc_NtkIsLogicBdd(pNtk) || Abc_NtkIsLogicSop(pNtk) );
|
||||
// convert nodes to SOPs
|
||||
if ( Abc_NtkIsLogicBdd(pNtk) )
|
||||
Abc_NtkBddToSop(pNtk);
|
||||
else
|
||||
{ // to make sure the SOPs are SCC-free
|
||||
// Abc_NtkSopToBdd(pNtk);
|
||||
// Abc_NtkBddToSop(pNtk);
|
||||
}
|
||||
// check if the network meets the requirements
|
||||
if ( !Abc_NtkFxuCheck(pNtk) )
|
||||
{
|
||||
printf( "Abc_NtkFastExtract: Nodes have duplicated or complemented fanins. FXU is not performed.\n" );
|
||||
return 0;
|
||||
}
|
||||
// sweep removes useless nodes
|
||||
Abc_NtkCleanup( pNtk, 0 );
|
||||
// collect information about the covers
|
||||
// make sure all covers are SCC free
|
||||
// allocate literal array for each cover
|
||||
Abc_NtkFxuCollectInfo( pNtk, p );
|
||||
// call the fast extract procedure
|
||||
// returns the number of divisor extracted
|
||||
if ( Fxu_FastExtract(p) > 0 )
|
||||
{
|
||||
// update the network
|
||||
Abc_NtkFxuReconstruct( pNtk, p );
|
||||
// make sure everything is okay
|
||||
if ( !Abc_NtkCheck( pNtk ) )
|
||||
printf( "Abc_NtkFastExtract: The network check has failed.\n" );
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Makes sure the nodes do not have complemented and duplicated fanins.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
bool Abc_NtkFxuCheck( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Obj_t * pNode, * pFanin1, * pFanin2;
|
||||
int n, i, k;
|
||||
Abc_NtkForEachNode( pNtk, pNode, n )
|
||||
{
|
||||
Abc_ObjForEachFanin( pNode, pFanin1, i )
|
||||
{
|
||||
if ( Abc_ObjFaninC(pNode, i) )
|
||||
return 0;
|
||||
Abc_ObjForEachFanin( pNode, pFanin2, k )
|
||||
{
|
||||
if ( i == k )
|
||||
continue;
|
||||
if ( pFanin1 == pFanin2 )
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collect information about the network for fast_extract.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkFxuCollectInfo( Abc_Ntk_t * pNtk, Fxu_Data_t * p )
|
||||
{
|
||||
Abc_Obj_t * pNode;
|
||||
int i;
|
||||
// add information to the manager
|
||||
p->pManSop = pNtk->pManFunc;
|
||||
p->vSops = Vec_PtrAlloc(0);
|
||||
p->vFanins = Vec_PtrAlloc(0);
|
||||
p->vSopsNew = Vec_PtrAlloc(0);
|
||||
p->vFaninsNew = Vec_PtrAlloc(0);
|
||||
Vec_PtrFill( p->vSops, pNtk->vObjs->nSize, NULL );
|
||||
Vec_PtrFill( p->vFanins, pNtk->vObjs->nSize, NULL );
|
||||
Vec_PtrFill( p->vSopsNew, pNtk->vObjs->nSize + p->nNodesExt, NULL );
|
||||
Vec_PtrFill( p->vFaninsNew, pNtk->vObjs->nSize + p->nNodesExt, NULL );
|
||||
// add SOPs and fanin array
|
||||
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||
{
|
||||
if ( Abc_SopGetVarNum(pNode->pData) < 2 )
|
||||
continue;
|
||||
if ( Abc_SopGetCubeNum(pNode->pData) < 1 )
|
||||
continue;
|
||||
p->vSops->pArray[i] = pNode->pData;
|
||||
p->vFanins->pArray[i] = &pNode->vFanins;
|
||||
}
|
||||
p->nNodesOld = pNtk->vObjs->nSize;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkFxuFreeInfo( Fxu_Data_t * p )
|
||||
{
|
||||
int i;
|
||||
// free the arrays of new fanins
|
||||
if ( p->vFaninsNew )
|
||||
for ( i = 0; i < p->vFaninsNew->nSize; i++ )
|
||||
if ( p->vFaninsNew->pArray[i] )
|
||||
Vec_IntFree( p->vFaninsNew->pArray[i] );
|
||||
// free the arrays
|
||||
if ( p->vSops ) Vec_PtrFree( p->vSops );
|
||||
if ( p->vSopsNew ) Vec_PtrFree( p->vSopsNew );
|
||||
if ( p->vFanins ) Vec_PtrFree( p->vFanins );
|
||||
if ( p->vFaninsNew ) Vec_PtrFree( p->vFaninsNew );
|
||||
FREE( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recostructs the network after FX.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkFxuReconstruct( Abc_Ntk_t * pNtk, Fxu_Data_t * p )
|
||||
{
|
||||
Vec_Fan_t * vFaninsOld;
|
||||
Vec_Int_t * vFanins;
|
||||
Abc_Obj_t * pNode, * pFanin;
|
||||
int i, k;
|
||||
|
||||
assert( p->vFanins->nSize < p->vFaninsNew->nSize );
|
||||
// create the new nodes
|
||||
for ( i = p->vFanins->nSize; i < p->vFanins->nSize + p->nNodesNew; i++ )
|
||||
{
|
||||
// start the node
|
||||
pNode = Abc_NtkCreateNode( pNtk );
|
||||
assert( i == (int)pNode->Id );
|
||||
}
|
||||
// update the old nodes
|
||||
for ( i = 0; i < p->vFanins->nSize; i++ )
|
||||
{
|
||||
// the new array of fanins
|
||||
vFanins = p->vFaninsNew->pArray[i];
|
||||
if ( vFanins == NULL )
|
||||
continue;
|
||||
// remove old fanins
|
||||
pNode = Abc_NtkObj( pNtk, i );
|
||||
vFaninsOld = &pNode->vFanins;
|
||||
for ( k = vFaninsOld->nSize - 1; k >= 0; k-- )
|
||||
{
|
||||
pFanin = Abc_NtkObj( pNtk, vFaninsOld->pArray[k].iFan );
|
||||
Abc_ObjDeleteFanin( pNode, pFanin );
|
||||
}
|
||||
// add new fanins
|
||||
vFanins = p->vFaninsNew->pArray[i];
|
||||
for ( k = 0; k < vFanins->nSize; k++ )
|
||||
{
|
||||
pFanin = Abc_NtkObj( pNtk, vFanins->pArray[k] );
|
||||
Abc_ObjAddFanin( pNode, pFanin );
|
||||
}
|
||||
pNode->pData = p->vSopsNew->pArray[i];
|
||||
assert( pNode->pData != NULL );
|
||||
}
|
||||
// set up the new nodes
|
||||
for ( i = p->vFanins->nSize; i < p->vFanins->nSize + p->nNodesNew; i++ )
|
||||
{
|
||||
// get the new node
|
||||
pNode = Abc_NtkObj( pNtk, i );
|
||||
// add the fanins
|
||||
vFanins = p->vFaninsNew->pArray[i];
|
||||
for ( k = 0; k < vFanins->nSize; k++ )
|
||||
{
|
||||
pFanin = Abc_NtkObj( pNtk, vFanins->pArray[k] );
|
||||
Abc_ObjAddFanin( pNode, pFanin );
|
||||
}
|
||||
pNode->pData = p->vSopsNew->pArray[i];
|
||||
assert( pNode->pData != NULL );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -33,6 +33,12 @@ static Abc_Obj_t * Abc_NodeFromMap_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNode
|
|||
static Abc_Obj_t * Abc_NodeFromMapPhase_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase );
|
||||
static Abc_Obj_t * Abc_NodeFromMapSuper_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, Map_Super_t * pSuper, Abc_Obj_t * pNodePis[], int nNodePis );
|
||||
static Abc_Obj_t * Abc_NtkFixCiDriver( Abc_Obj_t * pNode );
|
||||
|
||||
static Abc_Ntk_t * Abc_NtkFromMapSuperChoice( Map_Man_t * pMan, Abc_Ntk_t * pNtk );
|
||||
static void Abc_NodeSuperChoice( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode );
|
||||
static void Abc_NodeFromMapCutPhase( Abc_Ntk_t * pNtkNew, Map_Cut_t * pCut, int fPhase );
|
||||
static Abc_Obj_t * Abc_NodeFromMapSuperChoice_rec( Abc_Ntk_t * pNtkNew, Map_Super_t * pSuper, Abc_Obj_t * pNodePis[], int nNodePis );
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFITIONS ///
|
||||
|
|
@ -53,8 +59,8 @@ Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, int
|
|||
{
|
||||
int fCheck = 1;
|
||||
Abc_Ntk_t * pNtkNew;
|
||||
|
||||
Map_Man_t * pMan;
|
||||
int clk;
|
||||
|
||||
assert( Abc_NtkIsAig(pNtk) );
|
||||
|
||||
|
|
@ -81,11 +87,13 @@ Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, int
|
|||
pMan = Abc_NtkToMap( pNtk, DelayTarget, fRecovery, fVerbose );
|
||||
if ( pMan == NULL )
|
||||
return NULL;
|
||||
clk = clock();
|
||||
if ( !Map_Mapping( pMan ) )
|
||||
{
|
||||
Map_ManFree( pMan );
|
||||
return NULL;
|
||||
}
|
||||
Map_ManPrintStatsToFile( pNtk->pSpec, Map_ManReadAreaFinal(pMan), Map_ManReadRequiredGlo(pMan), clock()-clk );
|
||||
|
||||
// reconstruct the network after mapping
|
||||
pNtkNew = Abc_NtkFromMap( pMan, pNtk );
|
||||
|
|
@ -432,6 +440,265 @@ Abc_Obj_t * Abc_NtkFixCiDriver( Abc_Obj_t * pNode )
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Interface with the mapping package.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Abc_NtkSuperChoice( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
int fCheck = 1;
|
||||
Abc_Ntk_t * pNtkNew;
|
||||
|
||||
Map_Man_t * pMan;
|
||||
|
||||
assert( Abc_NtkIsAig(pNtk) );
|
||||
|
||||
// check that the library is available
|
||||
if ( Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) == NULL )
|
||||
{
|
||||
printf( "The current library is not available.\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// derive the supergate library
|
||||
if ( Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame()) == NULL && Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) )
|
||||
{
|
||||
printf( "A simple supergate library is derived from gate library \"%s\".\n",
|
||||
Mio_LibraryReadName(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame())) );
|
||||
Map_SuperLibDeriveFromGenlib( Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) );
|
||||
}
|
||||
|
||||
// print a warning about choice nodes
|
||||
if ( Abc_NtkCountChoiceNodes( pNtk ) )
|
||||
printf( "Performing mapping with choices.\n" );
|
||||
|
||||
// perform the mapping
|
||||
pMan = Abc_NtkToMap( pNtk, -1, 1, 0 );
|
||||
if ( pMan == NULL )
|
||||
return NULL;
|
||||
if ( !Map_Mapping( pMan ) )
|
||||
{
|
||||
Map_ManFree( pMan );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// reconstruct the network after mapping
|
||||
pNtkNew = Abc_NtkFromMapSuperChoice( pMan, pNtk );
|
||||
if ( pNtkNew == NULL )
|
||||
return NULL;
|
||||
Map_ManFree( pMan );
|
||||
|
||||
// make sure that everything is okay
|
||||
if ( fCheck && !Abc_NtkCheck( pNtkNew ) )
|
||||
{
|
||||
printf( "Abc_NtkMap: The network check has failed.\n" );
|
||||
Abc_NtkDelete( pNtkNew );
|
||||
return NULL;
|
||||
}
|
||||
return pNtkNew;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the mapped network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Abc_NtkFromMapSuperChoice( Map_Man_t * pMan, Abc_Ntk_t * pNtk )
|
||||
{
|
||||
ProgressBar * pProgress;
|
||||
Abc_Ntk_t * pNtkNew, * pNtkNew2;
|
||||
Abc_Obj_t * pNode;
|
||||
int i;
|
||||
|
||||
// save the pointer to the mapped nodes
|
||||
Abc_NtkForEachCi( pNtk, pNode, i )
|
||||
pNode->pNext = pNode->pCopy;
|
||||
Abc_NtkForEachPo( pNtk, pNode, i )
|
||||
pNode->pNext = pNode->pCopy;
|
||||
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||
pNode->pNext = pNode->pCopy;
|
||||
|
||||
// duplicate the network
|
||||
pNtkNew2 = Abc_NtkDup( pNtk );
|
||||
pNtkNew = Abc_NtkRenode( pNtkNew2, 0, 20, 0, 0, 1 );
|
||||
Abc_NtkBddToSop( pNtkNew );
|
||||
|
||||
// set the old network to point to the new network
|
||||
Abc_NtkForEachCi( pNtk, pNode, i )
|
||||
pNode->pCopy = pNode->pCopy->pCopy;
|
||||
Abc_NtkForEachPo( pNtk, pNode, i )
|
||||
pNode->pCopy = pNode->pCopy->pCopy;
|
||||
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||
pNode->pCopy = pNode->pCopy->pCopy;
|
||||
Abc_NtkDelete( pNtkNew2 );
|
||||
|
||||
// set the pointers from the mapper to the new nodes
|
||||
Abc_NtkForEachCi( pNtk, pNode, i )
|
||||
{
|
||||
Map_NodeSetData( Map_ManReadInputs(pMan)[i], 0, (char *)Abc_NodeCreateInv(pNtkNew,pNode->pCopy) );
|
||||
Map_NodeSetData( Map_ManReadInputs(pMan)[i], 1, (char *)pNode->pCopy );
|
||||
}
|
||||
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||
{
|
||||
if ( Abc_NodeIsConst(pNode) )
|
||||
continue;
|
||||
Map_NodeSetData( (Map_Node_t *)pNode->pNext, 0, (char *)Abc_NodeCreateInv(pNtkNew,pNode->pCopy) );
|
||||
Map_NodeSetData( (Map_Node_t *)pNode->pNext, 1, (char *)pNode->pCopy );
|
||||
}
|
||||
|
||||
// assign the mapping of the required phase to the POs
|
||||
pProgress = Extra_ProgressBarStart( stdout, Abc_NtkNodeNum(pNtk) );
|
||||
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||
{
|
||||
Extra_ProgressBarUpdate( pProgress, i, NULL );
|
||||
if ( Abc_NodeIsConst(pNode) )
|
||||
continue;
|
||||
Abc_NodeSuperChoice( pNtkNew, pNode );
|
||||
}
|
||||
Extra_ProgressBarStop( pProgress );
|
||||
return pNtkNew;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the mapped network.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NodeSuperChoice( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode )
|
||||
{
|
||||
Map_Node_t * pMapNode = (Map_Node_t *)pNode->pNext;
|
||||
Map_Cut_t * pCuts, * pTemp;
|
||||
|
||||
pCuts = Map_NodeReadCuts(pMapNode);
|
||||
for ( pTemp = Map_CutReadNext(pCuts); pTemp; pTemp = Map_CutReadNext(pTemp) )
|
||||
{
|
||||
Abc_NodeFromMapCutPhase( pNtkNew, pTemp, 0 );
|
||||
Abc_NodeFromMapCutPhase( pNtkNew, pTemp, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Constructs the nodes corrresponding to one node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NodeFromMapCutPhase( Abc_Ntk_t * pNtkNew, Map_Cut_t * pCut, int fPhase )
|
||||
{
|
||||
Abc_Obj_t * pNodePIs[10];
|
||||
Map_Node_t ** ppLeaves;
|
||||
Map_Super_t * pSuperBest;
|
||||
unsigned uPhaseBest;
|
||||
int i, fInvPin, nLeaves;
|
||||
|
||||
pSuperBest = Map_CutReadSuperBest( pCut, fPhase );
|
||||
if ( pSuperBest == NULL )
|
||||
return;
|
||||
|
||||
// get the information about the best cut
|
||||
uPhaseBest = Map_CutReadPhaseBest( pCut, fPhase );
|
||||
nLeaves = Map_CutReadLeavesNum( pCut );
|
||||
ppLeaves = Map_CutReadLeaves( pCut );
|
||||
|
||||
// collect the PI nodes
|
||||
for ( i = 0; i < nLeaves; i++ )
|
||||
{
|
||||
fInvPin = ((uPhaseBest & (1 << i)) > 0);
|
||||
pNodePIs[i] = (Abc_Obj_t *)Map_NodeReadData( ppLeaves[i], !fInvPin );
|
||||
assert( pNodePIs[i] != NULL );
|
||||
}
|
||||
|
||||
// implement the supergate
|
||||
Abc_NodeFromMapSuperChoice_rec( pNtkNew, pSuperBest, pNodePIs, nLeaves );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Constructs the nodes corrresponding to one supergate.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Obj_t * Abc_NodeFromMapSuperChoice_rec( Abc_Ntk_t * pNtkNew, Map_Super_t * pSuper, Abc_Obj_t * pNodePis[], int nNodePis )
|
||||
{
|
||||
Mio_Gate_t * pRoot;
|
||||
Map_Super_t ** ppFanins;
|
||||
Abc_Obj_t * pNodeNew, * pNodeFanin;
|
||||
int nFanins, Number, i;
|
||||
|
||||
// get the parameters of the supergate
|
||||
pRoot = Map_SuperReadRoot(pSuper);
|
||||
if ( pRoot == NULL )
|
||||
{
|
||||
Number = Map_SuperReadNum(pSuper);
|
||||
if ( Number < nNodePis )
|
||||
{
|
||||
return pNodePis[Number];
|
||||
}
|
||||
else
|
||||
{
|
||||
// assert( 0 );
|
||||
/* It might happen that a super gate with 5 inputs is constructed that
|
||||
* actually depends only on the first four variables; i.e the fifth is a
|
||||
* don't care -- in that case we connect constant node for the fifth
|
||||
* (since the cut only has 4 variables). An interesting question is what
|
||||
* if the first variable (and not the fifth one is the redundant one;
|
||||
* can that happen?) */
|
||||
return Abc_NodeCreateConst0(pNtkNew);
|
||||
}
|
||||
}
|
||||
|
||||
// get information about the fanins of the supergate
|
||||
nFanins = Map_SuperReadFaninNum( pSuper );
|
||||
ppFanins = Map_SuperReadFanins( pSuper );
|
||||
// create a new node with these fanins
|
||||
pNodeNew = Abc_NtkCreateNode( pNtkNew );
|
||||
for ( i = 0; i < nFanins; i++ )
|
||||
{
|
||||
pNodeFanin = Abc_NodeFromMapSuperChoice_rec( pNtkNew, ppFanins[i], pNodePis, nNodePis );
|
||||
Abc_ObjAddFanin( pNodeNew, pNodeFanin );
|
||||
}
|
||||
pNodeNew->pData = Abc_SopRegister( pNtkNew->pManFunc, Mio_GateReadSop(pRoot) );
|
||||
return pNodeNew;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -67,7 +67,12 @@ Abc_Ntk_t * Abc_NtkLogic( Abc_Ntk_t * pNtk )
|
|||
Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
|
||||
// create and connect the POs
|
||||
Abc_NtkForEachPo( pNtk, pObj, i )
|
||||
Abc_ObjAddFanin( Abc_NtkCreateTermPo(pNtkNew), Abc_ObjFanin0(pObj)->pCopy );
|
||||
{
|
||||
if ( Abc_ObjFaninNum(pObj) == 0 )
|
||||
Abc_ObjAddFanin( Abc_NtkCreateTermPo(pNtkNew), pObj->pCopy );
|
||||
else
|
||||
Abc_ObjAddFanin( Abc_NtkCreateTermPo(pNtkNew), Abc_ObjFanin0(pObj)->pCopy );
|
||||
}
|
||||
// connect the latches
|
||||
Abc_NtkForEachLatch( pNtk, pObj, i )
|
||||
Abc_ObjAddFanin( pObj->pCopy, Abc_ObjFanin0(pObj)->pCopy );
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk )
|
|||
if ( Abc_NtkIsLogicSop(pNtk) )
|
||||
{
|
||||
fprintf( pFile, " cube = %5d", Abc_NtkGetCubeNum(pNtk) );
|
||||
// fprintf( pFile, " lit(sop) = %5d", Abc_NtkGetLitNum(pNtk) );
|
||||
fprintf( pFile, " lit(sop) = %5d", Abc_NtkGetLitNum(pNtk) );
|
||||
fprintf( pFile, " lit(fac) = %5d", Abc_NtkGetLitFactNum(pNtk) );
|
||||
}
|
||||
else if ( Abc_NtkIsLogicBdd(pNtk) )
|
||||
|
|
|
|||
|
|
@ -130,6 +130,8 @@ void Abc_NtkRenodeInt( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
|
|||
Abc_NtkForEachCo( pNtk, pNode, i )
|
||||
{
|
||||
Extra_ProgressBarUpdate( pProgress, i, NULL );
|
||||
if ( Abc_ObjIsTerm(Abc_ObjFanin0(pNode)) )
|
||||
continue;
|
||||
Abc_NtkRenode_rec( pNtkNew, Abc_ObjFanin0(pNode) );
|
||||
}
|
||||
Extra_ProgressBarStop( pProgress );
|
||||
|
|
|
|||
|
|
@ -59,6 +59,37 @@ char * Abc_SopRegister( Extra_MmFlex_t * pMan, char * pName )
|
|||
return pRegName;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Starts the constant 1 cover with the given number of variables and cubes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
char * Abc_SopStart( Extra_MmFlex_t * pMan, int nCubes, int nVars )
|
||||
{
|
||||
char * pSopCover;
|
||||
char * pCube;
|
||||
int i, v;
|
||||
pSopCover = Extra_MmFlexEntryFetch( pMan, nCubes * (nVars + 3) + 1 );
|
||||
for ( i = 0; i < nCubes; i++ )
|
||||
{
|
||||
pCube = pSopCover + i * (nVars + 3);
|
||||
for ( v = 0; v < nVars; v++ )
|
||||
pCube[v] = '-';
|
||||
pCube[nVars + 0] = ' ';
|
||||
pCube[nVars + 1] = '1';
|
||||
pCube[nVars + 2] = '\n';
|
||||
}
|
||||
pSopCover[nCubes * (nVars + 3)] = 0;
|
||||
return pSopCover;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Reads the number of cubes in the cover.]
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@ void Abc_NtkStrashPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
|
|||
|
||||
// perform strashing
|
||||
vNodes = Abc_NtkDfs( pNtk );
|
||||
// vNodes = Abc_AigCollectAll( pNtk );
|
||||
pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize );
|
||||
for ( i = 0; i < vNodes->nSize; i++ )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -768,6 +768,11 @@ Vec_Ptr_t * Abc_AigCollectAll( Abc_Ntk_t * pNtk )
|
|||
vNodes = Vec_PtrAlloc( 100 );
|
||||
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||
Vec_PtrPush( vNodes, pNode );
|
||||
|
||||
// works only if the levels are set!!!
|
||||
if ( !Abc_NtkIsAig(pNtk) )
|
||||
Abc_NtkGetLevelNum(pNtk);
|
||||
|
||||
Vec_PtrSort( vNodes, Abc_NodeCompareLevelsIncrease );
|
||||
return vNodes;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [abc_.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Network and node package.]
|
||||
|
||||
Synopsis []
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: abc_.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "abc.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -127,12 +127,19 @@ int Fpga_MappingPostProcess( Fpga_Man_t * p )
|
|||
float aSwitchTotalPrev, aSwitchTotalCur;
|
||||
int Iter, clk;
|
||||
|
||||
|
||||
if ( p->fVerbose )
|
||||
{
|
||||
printf( "Iteration %dD : Area = %11.1f ", 0, Fpga_MappingArea( p ) );
|
||||
PRT( "Time", p->timeMatch );
|
||||
}
|
||||
|
||||
|
||||
// Fpga_MappingExplore( p );
|
||||
// p->fAreaGlo = Fpga_MappingArea( p );
|
||||
// return;
|
||||
|
||||
|
||||
// aAreaTotalCur = FPGA_FLOAT_LARGE;
|
||||
aAreaTotalCur = Fpga_MappingSetRefsAndArea( p );
|
||||
|
||||
|
|
@ -159,6 +166,11 @@ PRT( "Time", clock() - clk );
|
|||
} while ( aAreaTotalPrev > 1.02 * aAreaTotalCur );
|
||||
|
||||
|
||||
// Fpga_MappingExplore( p );
|
||||
// p->fAreaGlo = Fpga_MappingArea( p );
|
||||
// return;
|
||||
|
||||
|
||||
/*
|
||||
// compute the area of each cut
|
||||
aAreaTotalCur = Fpga_MappingSetRefsAndArea( p );
|
||||
|
|
|
|||
|
|
@ -334,6 +334,7 @@ extern float Fpga_TimeComputeArrivalMax( Fpga_Man_t * p );
|
|||
extern void Fpga_TimeComputeRequiredGlobal( Fpga_Man_t * p );
|
||||
extern void Fpga_TimeComputeRequired( Fpga_Man_t * p, float fRequired );
|
||||
extern void Fpga_TimePropagateRequired( Fpga_Man_t * p, Fpga_NodeVec_t * vNodes );
|
||||
extern void Fpga_TimePropagateArrival( Fpga_Man_t * p );
|
||||
/*=== fpgaTruth.c ===============================================================*/
|
||||
extern void Fpga_MappingTruths( Fpga_Man_t * pMan );
|
||||
/*=== fpgaVec.c =============================================================*/
|
||||
|
|
@ -368,6 +369,7 @@ extern float Fpga_MappingGetAreaFlow( Fpga_Man_t * p );
|
|||
extern float Fpga_MappingArea( Fpga_Man_t * pMan );
|
||||
extern float Fpga_MappingComputeCutAreas( Fpga_Man_t * pMan );
|
||||
extern float Fpga_MappingSetRefsAndArea( Fpga_Man_t * pMan );
|
||||
extern Fpga_NodeVec_t * Fpga_MappingCollectRefed( Fpga_Man_t * pMan );
|
||||
extern int Fpga_MappingCountLevels( Fpga_Man_t * pMan );
|
||||
extern void Fpga_MappingUnmark( Fpga_Man_t * pMan );
|
||||
extern void Fpga_MappingUnmark_rec( Fpga_Node_t * pNode );
|
||||
|
|
|
|||
|
|
@ -724,6 +724,112 @@ clk = clock();
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/**function*************************************************************
|
||||
|
||||
synopsis [Performs area minimization using a heuristic algorithm.]
|
||||
|
||||
description []
|
||||
|
||||
sideeffects []
|
||||
|
||||
seealso []
|
||||
|
||||
***********************************************************************/
|
||||
float Fpga_FindBestNode( Fpga_Man_t * p, Fpga_NodeVec_t * vNodes, Fpga_Node_t ** ppNode, Fpga_Cut_t ** ppCutBest )
|
||||
{
|
||||
Fpga_Node_t * pNode;
|
||||
Fpga_Cut_t * pCut;
|
||||
float Gain, CutArea1, CutArea2, CutArea3;
|
||||
int i;
|
||||
|
||||
Gain = 0;
|
||||
for ( i = 0; i < vNodes->nSize; i++ )
|
||||
{
|
||||
pNode = vNodes->pArray[i];
|
||||
// deref the current cut
|
||||
CutArea1 = Fpga_CutDeref( p, pNode, pNode->pCutBest, 0 );
|
||||
|
||||
// ref all the cuts
|
||||
for ( pCut = pNode->pCuts->pNext; pCut; pCut = pCut->pNext )
|
||||
{
|
||||
if ( pCut == pNode->pCutBest )
|
||||
continue;
|
||||
if ( pCut->tArrival > pNode->tRequired )
|
||||
continue;
|
||||
|
||||
CutArea2 = Fpga_CutGetAreaDerefed( p, pCut );
|
||||
if ( Gain < CutArea1 - CutArea2 )
|
||||
{
|
||||
*ppNode = pNode;
|
||||
*ppCutBest = pCut;
|
||||
Gain = CutArea1 - CutArea2;
|
||||
}
|
||||
}
|
||||
// ref the old cut
|
||||
CutArea3 = Fpga_CutRef( p, pNode, pNode->pCutBest, 0 );
|
||||
assert( CutArea1 == CutArea3 );
|
||||
}
|
||||
if ( Gain == 0 )
|
||||
printf( "Returning no gain.\n" );
|
||||
|
||||
return Gain;
|
||||
}
|
||||
|
||||
/**function*************************************************************
|
||||
|
||||
synopsis [Performs area minimization using a heuristic algorithm.]
|
||||
|
||||
description []
|
||||
|
||||
sideeffects []
|
||||
|
||||
seealso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fpga_MappingExplore( Fpga_Man_t * p )
|
||||
{
|
||||
Fpga_Cut_t * pCutBest;
|
||||
Fpga_Node_t * pNodeBest;
|
||||
Fpga_NodeVec_t * vNodes;
|
||||
float Area, Gain, CutArea1, CutArea2;
|
||||
int i;
|
||||
|
||||
// compute the arrival times
|
||||
Fpga_TimePropagateArrival( p );
|
||||
p->fRequiredGlo = Fpga_TimeComputeArrivalMax( p );
|
||||
Fpga_TimeComputeRequired( p, p->fRequiredGlo );
|
||||
|
||||
// assign the refs
|
||||
Area = Fpga_MappingSetRefsAndArea( p );
|
||||
// collect the nodes
|
||||
vNodes = Fpga_MappingCollectRefed( p );
|
||||
// find the best node to update
|
||||
for ( i = 0; Gain = Fpga_FindBestNode(p, vNodes, &pNodeBest, &pCutBest); i++ )
|
||||
{
|
||||
// update the node
|
||||
assert( pNodeBest->pCutBest != pCutBest );
|
||||
// deref the current cut
|
||||
CutArea1 = Fpga_CutDeref( p, pNodeBest, pNodeBest->pCutBest, 0 );
|
||||
// ref the new cut
|
||||
CutArea2 = Fpga_CutRef( p, pNodeBest, pCutBest, 0 );
|
||||
assert( CutArea1 - CutArea2 == Gain );
|
||||
printf( "Iteration %2d: Gain = %5.2f.\n", i, Gain );
|
||||
// update the node
|
||||
pNodeBest->pCutBest = pCutBest;
|
||||
// collect new nodes
|
||||
Fpga_NodeVecFree( vNodes );
|
||||
vNodes = Fpga_MappingCollectRefed( p );
|
||||
// compute the arrival and required times
|
||||
Fpga_TimePropagateArrival( p );
|
||||
Fpga_TimeComputeRequired( p, p->fRequiredGlo );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -182,6 +182,34 @@ void Fpga_TimePropagateRequired( Fpga_Man_t * p, Fpga_NodeVec_t * vNodes )
|
|||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the required times of all nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fpga_TimePropagateArrival( Fpga_Man_t * p )
|
||||
{
|
||||
Fpga_Node_t * pNode;
|
||||
Fpga_Cut_t * pCut;
|
||||
int i;
|
||||
|
||||
// clean the required times and the fanout counts for all nodes
|
||||
for ( i = 0; i < p->vAnds->nSize; i++ )
|
||||
{
|
||||
pNode = p->vAnds->pArray[i];
|
||||
for ( pCut = pNode->pCuts->pNext; pCut; pCut = pCut->pNext )
|
||||
pCut->tArrival = Fpga_TimeCutComputeArrival( p, pCut );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -491,6 +491,32 @@ float Fpga_MappingSetRefsAndArea_rec( Fpga_Man_t * pMan, Fpga_Node_t * pNode )
|
|||
return aArea;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collect the referenced nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Fpga_NodeVec_t * Fpga_MappingCollectRefed( Fpga_Man_t * pMan )
|
||||
{
|
||||
Fpga_NodeVec_t * vNodes;
|
||||
int i;
|
||||
vNodes = Fpga_NodeVecAlloc( 100 );
|
||||
for ( i = 0; i < pMan->vNodesAll->nSize; i++ )
|
||||
{
|
||||
if ( Fpga_NodeIsVar(pMan->vNodesAll->pArray[i]) )
|
||||
continue;
|
||||
if ( pMan->vNodesAll->pArray[i]->nRefs )
|
||||
Fpga_NodeVecPush( vNodes, pMan->vNodesAll->pArray[i] );
|
||||
}
|
||||
return vNodes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the number of logic levels not counting PIs/POs.]
|
||||
|
|
|
|||
|
|
@ -82,6 +82,8 @@ extern Map_Node_t * Map_ManReadConst1 ( Map_Man_t * p );
|
|||
extern Map_Time_t * Map_ManReadInputArrivals( Map_Man_t * p );
|
||||
extern Mio_Library_t * Map_ManReadGenLib ( Map_Man_t * p );
|
||||
extern bool Map_ManReadVerbose( Map_Man_t * p );
|
||||
extern float Map_ManReadAreaFinal( Map_Man_t * p );
|
||||
extern float Map_ManReadRequiredGlo( Map_Man_t * p );
|
||||
extern void Map_ManSetTimeToMap( Map_Man_t * p, int Time );
|
||||
extern void Map_ManSetTimeToNet( Map_Man_t * p, int Time );
|
||||
extern void Map_ManSetTimeSweep( Map_Man_t * p, int Time );
|
||||
|
|
@ -125,6 +127,7 @@ extern Map_Node_t ** Map_CutReadLeaves( Map_Cut_t * p );
|
|||
extern unsigned Map_CutReadPhaseBest( Map_Cut_t * p, int fPhase );
|
||||
extern unsigned Map_CutReadPhase0( Map_Cut_t * p );
|
||||
extern unsigned Map_CutReadPhase1( Map_Cut_t * p );
|
||||
extern Map_Cut_t * Map_CutReadNext( Map_Cut_t * p );
|
||||
|
||||
extern char * Map_SuperReadFormula( Map_Super_t * p );
|
||||
extern Mio_Gate_t * Map_SuperReadRoot( Map_Super_t * p );
|
||||
|
|
|
|||
|
|
@ -82,8 +82,8 @@ int Map_Mapping( Map_Man_t * p )
|
|||
p->AreaBase = Map_MappingGetArea( p, p->vMapping );
|
||||
if ( p->fVerbose )
|
||||
{
|
||||
printf( "Delay : FanViols = %5d Flow = %11.1f Area = %11.1f %4.1f %% ",
|
||||
0, Map_MappingGetAreaFlow(p), p->AreaBase, 0.0 );
|
||||
printf( "Delay : Delay = %5.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
|
||||
p->fRequiredGlo, Map_MappingGetAreaFlow(p), p->AreaBase, 0.0 );
|
||||
PRT( "Time", p->timeMatch );
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -103,8 +103,8 @@ PRT( "Time", p->timeMatch );
|
|||
p->AreaFinal = Map_MappingGetArea( p, p->vMapping );
|
||||
if ( p->fVerbose )
|
||||
{
|
||||
printf( "AreaFlow : FanViols = %5d Flow = %11.1f Area = %11.1f %4.1f %% ",
|
||||
0, Map_MappingGetAreaFlow(p), p->AreaFinal,
|
||||
printf( "AreaFlow : Delay = %5.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
|
||||
p->fRequiredGlo, Map_MappingGetAreaFlow(p), p->AreaFinal,
|
||||
100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase );
|
||||
PRT( "Time", clock() - clk );
|
||||
}
|
||||
|
|
@ -127,8 +127,8 @@ PRT( "Time", clock() - clk );
|
|||
p->AreaFinal = Map_MappingGetArea( p, p->vMapping );
|
||||
if ( p->fVerbose )
|
||||
{
|
||||
printf( "Area : FanViols = %5d Flow = %11.1f Area = %11.1f %4.1f %% ",
|
||||
0, 0.0, p->AreaFinal,
|
||||
printf( "Area : Delay = %5.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
|
||||
p->fRequiredGlo, 0.0, p->AreaFinal,
|
||||
100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase );
|
||||
PRT( "Time", clock() - clk );
|
||||
}
|
||||
|
|
@ -151,8 +151,8 @@ PRT( "Time", clock() - clk );
|
|||
p->AreaFinal = Map_MappingGetArea( p, p->vMapping );
|
||||
if ( p->fVerbose )
|
||||
{
|
||||
printf( "Area : FanViols = %5d Flow = %11.1f Area = %11.1f %4.1f %% ",
|
||||
0, 0.0, p->AreaFinal,
|
||||
printf( "Area : Delay = %5.2f Flow = %11.1f Area = %11.1f %4.1f %% ",
|
||||
p->fRequiredGlo, 0.0, p->AreaFinal,
|
||||
100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase );
|
||||
PRT( "Time", clock() - clk );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@ Map_Node_t * Map_ManReadConst1 ( Map_Man_t * p ) { return
|
|||
Map_Time_t * Map_ManReadInputArrivals( Map_Man_t * p ) { return p->pInputArrivals;}
|
||||
Mio_Library_t * Map_ManReadGenLib ( Map_Man_t * p ) { return p->pSuperLib->pGenlib; }
|
||||
bool Map_ManReadVerbose( Map_Man_t * p ) { return p->fVerbose; }
|
||||
float Map_ManReadAreaFinal( Map_Man_t * p ) { return p->AreaFinal; }
|
||||
float Map_ManReadRequiredGlo( Map_Man_t * p ) { return p->fRequiredGlo; }
|
||||
void Map_ManSetTimeToMap( Map_Man_t * p, int Time ) { p->timeToMap = Time; }
|
||||
void Map_ManSetTimeToNet( Map_Man_t * p, int Time ) { p->timeToNet = Time; }
|
||||
void Map_ManSetTimeSweep( Map_Man_t * p, int Time ) { p->timeSweep = Time; }
|
||||
|
|
@ -126,6 +128,7 @@ Map_Node_t ** Map_CutReadLeaves( Map_Cut_t * p ) { return p->pp
|
|||
unsigned Map_CutReadPhaseBest( Map_Cut_t * p, int fPhase ) { return p->M[fPhase].uPhaseBest;}
|
||||
unsigned Map_CutReadPhase0( Map_Cut_t * p ) { return p->M[0].uPhaseBest;}
|
||||
unsigned Map_CutReadPhase1( Map_Cut_t * p ) { return p->M[1].uPhaseBest;}
|
||||
Map_Cut_t * Map_CutReadNext( Map_Cut_t * p ) { return p->pNext; }
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
@ -190,7 +193,8 @@ Map_Man_t * Map_ManCreate( int nInputs, int nOutputs, int fVerbose )
|
|||
p->pSuperLib = Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame());
|
||||
p->nVarsMax = p->pSuperLib->nVarsMax;
|
||||
p->fVerbose = fVerbose;
|
||||
p->fEpsilon = (float)0.00001;
|
||||
// p->fEpsilon = (float)0.00001;
|
||||
p->fEpsilon = (float)0.001;
|
||||
assert( p->nVarsMax > 0 );
|
||||
|
||||
// start various data structures
|
||||
|
|
@ -210,6 +214,7 @@ Map_Man_t * Map_ManCreate( int nInputs, int nOutputs, int fVerbose )
|
|||
p->vMapping = Map_NodeVecAlloc( 100 );
|
||||
p->vInside = Map_NodeVecAlloc( 100 );
|
||||
p->vFanins = Map_NodeVecAlloc( 100 );
|
||||
p->vVisited = Map_NodeVecAlloc( 100 );
|
||||
|
||||
// create the PI nodes
|
||||
p->nInputs = nInputs;
|
||||
|
|
@ -253,6 +258,8 @@ void Map_ManFree( Map_Man_t * p )
|
|||
Map_NodeVecFree( p->vNodesTemp );
|
||||
if ( p->vMapping )
|
||||
Map_NodeVecFree( p->vMapping );
|
||||
if ( p->vVisited )
|
||||
Map_NodeVecFree( p->vVisited );
|
||||
Extra_MmFixedStop( p->mmNodes, 0 );
|
||||
Extra_MmFixedStop( p->mmCuts, 0 );
|
||||
FREE( p->pInputArrivals );
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// the largest number of cuts considered
|
||||
#define MAP_CUTS_MAX_COMPUTE 200
|
||||
#define MAP_CUTS_MAX_COMPUTE 1000
|
||||
// the largest number of cuts used
|
||||
#define MAP_CUTS_MAX_USE 50
|
||||
#define MAP_CUTS_MAX_USE 250
|
||||
|
||||
// temporary hash table to store the cuts
|
||||
typedef struct Map_CutTableStrutct_t Map_CutTable_t;
|
||||
|
|
@ -373,6 +373,14 @@ Map_Cut_t * Map_CutMergeLists( Map_Man_t * p, Map_CutTable_t * pTable,
|
|||
pTemp1 = ppArray1[i];
|
||||
pTemp2 = ppArray2[k];
|
||||
|
||||
if ( pTemp1->nLeaves == p->nVarsMax && pTemp2->nLeaves == p->nVarsMax )
|
||||
{
|
||||
if ( pTemp1->ppLeaves[0] != pTemp2->ppLeaves[0] )
|
||||
continue;
|
||||
if ( pTemp1->ppLeaves[1] != pTemp2->ppLeaves[1] )
|
||||
continue;
|
||||
}
|
||||
|
||||
// check if k-feasible cut exists
|
||||
nNodes = Map_CutMergeTwo( pTemp1, pTemp2, ppNodes, p->nVarsMax );
|
||||
if ( nNodes == 0 )
|
||||
|
|
@ -397,6 +405,14 @@ Map_Cut_t * Map_CutMergeLists( Map_Man_t * p, Map_CutTable_t * pTable,
|
|||
pTemp1 = ppArray1[k];
|
||||
pTemp2 = ppArray2[i];
|
||||
|
||||
if ( pTemp1->nLeaves == p->nVarsMax && pTemp2->nLeaves == p->nVarsMax )
|
||||
{
|
||||
if ( pTemp1->ppLeaves[0] != pTemp2->ppLeaves[0] )
|
||||
continue;
|
||||
if ( pTemp1->ppLeaves[1] != pTemp2->ppLeaves[1] )
|
||||
continue;
|
||||
}
|
||||
|
||||
// check if k-feasible cut exists
|
||||
nNodes = Map_CutMergeTwo( pTemp1, pTemp2, ppNodes, p->nVarsMax );
|
||||
if ( nNodes == 0 )
|
||||
|
|
@ -424,6 +440,14 @@ Map_Cut_t * Map_CutMergeLists( Map_Man_t * p, Map_CutTable_t * pTable,
|
|||
pTemp1 = ppArray1[k];
|
||||
pTemp2 = ppArray2[i];
|
||||
|
||||
if ( pTemp1->nLeaves == p->nVarsMax && pTemp2->nLeaves == p->nVarsMax )
|
||||
{
|
||||
if ( pTemp1->ppLeaves[0] != pTemp2->ppLeaves[0] )
|
||||
continue;
|
||||
if ( pTemp1->ppLeaves[1] != pTemp2->ppLeaves[1] )
|
||||
continue;
|
||||
}
|
||||
|
||||
// check if k-feasible cut exists
|
||||
nNodes = Map_CutMergeTwo( pTemp1, pTemp2, ppNodes, p->nVarsMax );
|
||||
if ( nNodes == 0 )
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@ struct Map_ManStruct_t_
|
|||
unsigned uTruthsLarge[10][32]; // the elementary truth tables
|
||||
int nCounts[32]; // the counter of minterms
|
||||
int nCountsBest[32];// the counter of minterms
|
||||
Map_NodeVec_t * vVisited; // the visited cuts during cut computation
|
||||
|
||||
// simulation info from the FRAIG manager
|
||||
int nSimRounds; // the number of words in the simulation info
|
||||
|
|
@ -262,13 +263,7 @@ struct Map_CutStruct_t_
|
|||
char nVolume; // the volume of this cut
|
||||
char fMark; // the mark to denote visited cut
|
||||
char Phase; // the mark to denote complemented cut
|
||||
// float fLevel; // the average level of the fanins
|
||||
|
||||
unsigned uTruthTemp[2]; // the temporary truth table used to derive other cuts
|
||||
unsigned uTruthZero[2]; // the temporary truth table used to derive other cuts
|
||||
unsigned uTruthDc[2]; // the don't-cares (SDCs) computed for this cut
|
||||
|
||||
Map_Match_t M[2]; // the matches for the positive/negative phase
|
||||
Map_Match_t M[2]; // the matches for positive/negative phase
|
||||
};
|
||||
|
||||
// the supergate internally represented
|
||||
|
|
|
|||
|
|
@ -22,20 +22,10 @@
|
|||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//static void Map_TruthsCutDcs( Map_Man_t * p, Map_Cut_t * pCut, unsigned uTruth[] );
|
||||
static void Map_TruthsCut( Map_Man_t * pMan, Map_Cut_t * pCut );
|
||||
static void Map_TruthsCut_rec( Map_Cut_t * pCut, unsigned uTruth[] );
|
||||
static void Map_TruthsUnmark_rec( Map_Cut_t * pCut );
|
||||
static void Map_TruthsCut( Map_Man_t * pMan, Map_Cut_t * pCut );
|
||||
static void Map_TruthsCutOne( Map_Man_t * p, Map_Cut_t * pCut, unsigned uTruth[] );
|
||||
static void Map_CutsCollect_rec( Map_Cut_t * pCut, Map_NodeVec_t * vVisited );
|
||||
|
||||
/*
|
||||
static int s_Same = 0;
|
||||
static int s_Diff = 0;
|
||||
static int s_Same2 = 0;
|
||||
static int s_Diff2 = 0;
|
||||
static int s_Truth = 0;
|
||||
static int s_Isop1 = 0;
|
||||
static int s_Isop2 = 0;
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -85,10 +75,6 @@ void Map_MappingTruths( Map_Man_t * pMan )
|
|||
Extra_ProgressBarUpdate( pProgress, i, "Tables ..." );
|
||||
}
|
||||
Extra_ProgressBarStop( pProgress );
|
||||
|
||||
// printf( "Same = %6d. Diff = %6d.\n", s_Same, s_Diff );
|
||||
// printf( "Same2 = %6d. Diff2 = %6d.\n", s_Same2, s_Diff2 );
|
||||
// printf( "Truth = %6d. Isop1 = %6d. Isop2 = %6d.\n", s_Truth, s_Isop1, s_Isop2 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -106,22 +92,11 @@ void Map_TruthsCut( Map_Man_t * p, Map_Cut_t * pCut )
|
|||
{
|
||||
unsigned uTruth[2], uCanon[2];
|
||||
unsigned char uPhases[16];
|
||||
int i;
|
||||
|
||||
// generally speaking, 1-input cut can be matched into a wire!
|
||||
if ( pCut->nLeaves == 1 )
|
||||
return;
|
||||
// set the leaf truth tables
|
||||
for ( i = 0; i < pCut->nLeaves; i++ )
|
||||
{
|
||||
pCut->ppLeaves[i]->pCuts->uTruthTemp[0] = p->uTruths[i][0];
|
||||
pCut->ppLeaves[i]->pCuts->uTruthTemp[1] = p->uTruths[i][1];
|
||||
}
|
||||
// recursively compute the truth table
|
||||
pCut->nVolume = 0;
|
||||
Map_TruthsCut_rec( pCut, uTruth );
|
||||
// recursively unmark the visited cuts
|
||||
Map_TruthsUnmark_rec( pCut );
|
||||
Map_TruthsCutOne( p, pCut, uTruth );
|
||||
|
||||
// compute the canonical form for the positive phase
|
||||
Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
|
||||
|
|
@ -140,15 +115,11 @@ void Map_TruthsCut( Map_Man_t * p, Map_Cut_t * pCut )
|
|||
// restore the truth table
|
||||
uTruth[0] = ~uTruth[0];
|
||||
uTruth[1] = ~uTruth[1];
|
||||
// enable don't-care computation
|
||||
// Map_TruthsCutDcs( p, pCut, uTruth );
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds several other choices using SDCs.]
|
||||
Synopsis [Computes the truth table of one cut.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -157,291 +128,99 @@ void Map_TruthsCut( Map_Man_t * p, Map_Cut_t * pCut )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_TruthsCutDcs( Map_Man_t * p, Map_Cut_t * pCut, unsigned uTruth[] )
|
||||
void Map_TruthsCutOne( Map_Man_t * p, Map_Cut_t * pCut, unsigned uTruth[] )
|
||||
{
|
||||
unsigned uIsop1[2], uIsop2[2], uCanon[2];
|
||||
unsigned char uPhases[16];
|
||||
|
||||
// add several other supergate classes derived using don't-cares
|
||||
if ( pCut->uTruthDc[0] )
|
||||
unsigned uTruth1[2], uTruth2[2];
|
||||
Map_Cut_t * pTemp;
|
||||
int i;
|
||||
// mark the cut leaves
|
||||
for ( i = 0; i < pCut->nLeaves; i++ )
|
||||
{
|
||||
int nOnes;
|
||||
nOnes = Map_TruthCountOnes( pCut->uTruthDc, pCut->nLeaves );
|
||||
if ( nOnes == 1 )
|
||||
pTemp = pCut->ppLeaves[i]->pCuts;
|
||||
pTemp->fMark = 1;
|
||||
pTemp->M[0].uPhaseBest = p->uTruths[i][0];
|
||||
pTemp->M[1].uPhaseBest = p->uTruths[i][1];
|
||||
}
|
||||
assert( pCut->fMark == 0 );
|
||||
|
||||
// collect the cuts in the cut cone
|
||||
p->vVisited->nSize = 0;
|
||||
Map_CutsCollect_rec( pCut, p->vVisited );
|
||||
assert( p->vVisited->nSize > 0 );
|
||||
pCut->nVolume = p->vVisited->nSize;
|
||||
|
||||
// compute the tables and unmark
|
||||
for ( i = 0; i < pCut->nLeaves; i++ )
|
||||
{
|
||||
pTemp = pCut->ppLeaves[i]->pCuts;
|
||||
pTemp->fMark = 0;
|
||||
}
|
||||
for ( i = 0; i < p->vVisited->nSize; i++ )
|
||||
{
|
||||
// get the cut
|
||||
pTemp = (Map_Cut_t *)p->vVisited->pArray[i];
|
||||
pTemp->fMark = 0;
|
||||
// get truth table of the first branch
|
||||
if ( Map_CutIsComplement(pTemp->pOne) )
|
||||
{
|
||||
uTruth[0] ^= pCut->uTruthDc[0];
|
||||
uTruth[1] ^= pCut->uTruthDc[1];
|
||||
|
||||
// compute the canonical form for the positive phase
|
||||
Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
|
||||
pCut->M[1].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon );
|
||||
pCut->M[1].uPhase = uPhases[0];
|
||||
p->nCanons++;
|
||||
|
||||
// compute the canonical form for the negative phase
|
||||
uTruth[0] = ~uTruth[0];
|
||||
uTruth[1] = ~uTruth[1];
|
||||
Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
|
||||
pCut->M[0].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon );
|
||||
pCut->M[0].uPhase = uPhases[0];
|
||||
p->nCanons++;
|
||||
}
|
||||
else if ( nOnes == 2 )
|
||||
{
|
||||
int Num1, Num2, RetValue;
|
||||
RetValue = Map_TruthDetectTwoFirst( pCut->uTruthDc, pCut->nLeaves );
|
||||
Num1 = RetValue & 255;
|
||||
Num2 = (RetValue >> 8) & 255;
|
||||
|
||||
// add the first bit
|
||||
Map_InfoFlipVar( uTruth, Num1 );
|
||||
|
||||
// compute the canonical form for the positive phase
|
||||
Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
|
||||
pCut->M[1].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon );
|
||||
pCut->M[1].uPhase = uPhases[0];
|
||||
p->nCanons++;
|
||||
|
||||
// compute the canonical form for the negative phase
|
||||
uTruth[0] = ~uTruth[0];
|
||||
uTruth[1] = ~uTruth[1];
|
||||
Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
|
||||
pCut->M[0].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon );
|
||||
pCut->M[0].uPhase = uPhases[0];
|
||||
p->nCanons++;
|
||||
|
||||
// add the first bit
|
||||
Map_InfoFlipVar( uTruth, Num2 );
|
||||
|
||||
// compute the canonical form for the positive phase
|
||||
Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
|
||||
pCut->M[1].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon );
|
||||
pCut->M[1].uPhase = uPhases[0];
|
||||
p->nCanons++;
|
||||
|
||||
// compute the canonical form for the negative phase
|
||||
uTruth[0] = ~uTruth[0];
|
||||
uTruth[1] = ~uTruth[1];
|
||||
Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
|
||||
pCut->M[0].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon );
|
||||
pCut->M[0].uPhase = uPhases[0];
|
||||
p->nCanons++;
|
||||
|
||||
// add the first bit
|
||||
Map_InfoFlipVar( uTruth, Num1 );
|
||||
|
||||
// compute the canonical form for the positive phase
|
||||
Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
|
||||
pCut->M[1].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon );
|
||||
pCut->M[1].uPhase = uPhases[0];
|
||||
p->nCanons++;
|
||||
|
||||
// compute the canonical form for the negative phase
|
||||
uTruth[0] = ~uTruth[0];
|
||||
uTruth[1] = ~uTruth[1];
|
||||
Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uTruth, uPhases, uCanon );
|
||||
pCut->M[0].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon );
|
||||
pCut->M[0].uPhase = uPhases[0];
|
||||
p->nCanons++;
|
||||
uTruth1[0] = ~Map_CutRegular(pTemp->pOne)->M[0].uPhaseBest;
|
||||
uTruth1[1] = ~Map_CutRegular(pTemp->pOne)->M[1].uPhaseBest;
|
||||
}
|
||||
else
|
||||
{
|
||||
// compute the ISOPs
|
||||
uIsop1[0] = Map_ComputeIsop_rec( p, uTruth[0] & ~pCut->uTruthDc[0], uTruth[0] | pCut->uTruthDc[0], 0, pCut->nLeaves, 0 );
|
||||
uIsop1[1] = uIsop1[0];
|
||||
if ( uIsop1[0] != uTruth[0] )
|
||||
{
|
||||
// compute the canonical form for the positive phase
|
||||
Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uIsop1, uPhases, uCanon );
|
||||
pCut->M[1].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon );
|
||||
pCut->M[1].uPhase = uPhases[0];
|
||||
p->nCanons++;
|
||||
|
||||
// compute the canonical form for the negative phase
|
||||
uIsop1[0] = ~uIsop1[0];
|
||||
uIsop1[1] = ~uIsop1[1];
|
||||
Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uIsop1, uPhases, uCanon );
|
||||
pCut->M[0].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon );
|
||||
pCut->M[0].uPhase = uPhases[0];
|
||||
p->nCanons++;
|
||||
}
|
||||
|
||||
uIsop2[0] = Map_ComputeIsop_rec( p, uTruth[0] & ~pCut->uTruthDc[0], uTruth[0] | pCut->uTruthDc[0], pCut->nLeaves-1, pCut->nLeaves, 1 );
|
||||
uIsop2[1] = uIsop2[0];
|
||||
if ( uIsop2[0] != uTruth[0] && uIsop2[0] != uIsop1[0] )
|
||||
{
|
||||
// compute the canonical form for the positive phase
|
||||
Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uIsop2, uPhases, uCanon );
|
||||
pCut->M[1].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon );
|
||||
p->nCanons++;
|
||||
|
||||
// compute the canonical form for the negative phase
|
||||
uIsop2[0] = ~uIsop2[0];
|
||||
uIsop2[1] = ~uIsop2[1];
|
||||
Map_CanonComputeSlow( p->uTruths, p->nVarsMax, pCut->nLeaves, uIsop2, uPhases, uCanon );
|
||||
pCut->M[0].pSupers = Map_SuperTableLookupC( p->pSuperLib, uCanon );
|
||||
pCut->M[0].uPhase = uPhases[0];
|
||||
p->nCanons++;
|
||||
}
|
||||
uTruth1[0] = Map_CutRegular(pTemp->pOne)->M[0].uPhaseBest;
|
||||
uTruth1[1] = Map_CutRegular(pTemp->pOne)->M[1].uPhaseBest;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recursively derives the truth table for the cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_TruthsCut_rec( Map_Cut_t * pCut, unsigned uTruthRes[] )
|
||||
{
|
||||
unsigned uTruth1[2], uTruth2[2];
|
||||
// if this is the elementary cut, its truth table is already available
|
||||
if ( pCut->nLeaves == 1 )
|
||||
{
|
||||
uTruthRes[0] = pCut->uTruthTemp[0];
|
||||
uTruthRes[1] = pCut->uTruthTemp[1];
|
||||
return;
|
||||
}
|
||||
// if this node was already visited, return its computed truth table
|
||||
if ( pCut->fMark )
|
||||
{
|
||||
uTruthRes[0] = pCut->uTruthTemp[0];
|
||||
uTruthRes[1] = pCut->uTruthTemp[1];
|
||||
return;
|
||||
}
|
||||
pCut->fMark = 1;
|
||||
pCut->nVolume++;
|
||||
|
||||
assert( !Map_IsComplement(pCut) );
|
||||
Map_TruthsCut_rec( Map_CutRegular(pCut->pOne), uTruth1 );
|
||||
if ( Map_CutIsComplement(pCut->pOne) )
|
||||
{
|
||||
uTruth1[0] = ~uTruth1[0];
|
||||
uTruth1[1] = ~uTruth1[1];
|
||||
}
|
||||
Map_TruthsCut_rec( Map_CutRegular(pCut->pTwo), uTruth2 );
|
||||
if ( Map_CutIsComplement(pCut->pTwo) )
|
||||
{
|
||||
uTruth2[0] = ~uTruth2[0];
|
||||
uTruth2[1] = ~uTruth2[1];
|
||||
}
|
||||
if ( !pCut->Phase )
|
||||
{
|
||||
uTruthRes[0] = pCut->uTruthTemp[0] = uTruth1[0] & uTruth2[0];
|
||||
uTruthRes[1] = pCut->uTruthTemp[1] = uTruth1[1] & uTruth2[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
uTruthRes[0] = pCut->uTruthTemp[0] = ~(uTruth1[0] & uTruth2[0]);
|
||||
uTruthRes[1] = pCut->uTruthTemp[1] = ~(uTruth1[1] & uTruth2[1]);
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recursively derives the truth table for the cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_TruthsUnmark_rec( Map_Cut_t * pCut )
|
||||
{
|
||||
if ( pCut->nLeaves == 1 )
|
||||
return;
|
||||
// if this node was already visited, return its computed truth table
|
||||
if ( pCut->fMark == 0 )
|
||||
return;
|
||||
pCut->fMark = 0;
|
||||
Map_TruthsUnmark_rec( Map_CutRegular(pCut->pOne) );
|
||||
Map_TruthsUnmark_rec( Map_CutRegular(pCut->pTwo) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns the truth table of the don't-care set.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_TruthsCutDontCare( Map_Man_t * pMan, Map_Cut_t * pCut, unsigned * uTruthDc )
|
||||
{
|
||||
if ( pCut->pOne || (pCut->uTruthZero[0] == 0 && pCut->uTruthZero[1] == 0) )
|
||||
return 0;
|
||||
assert( (pCut->uTruthTemp[0] & pCut->uTruthZero[0]) == 0 );
|
||||
assert( (pCut->uTruthTemp[1] & pCut->uTruthZero[1]) == 0 );
|
||||
uTruthDc[0] = ((~0) & (~pCut->uTruthTemp[0]) & (~pCut->uTruthZero[0]));
|
||||
uTruthDc[1] = ((~0) & (~pCut->uTruthTemp[1]) & (~pCut->uTruthZero[1]));
|
||||
if ( uTruthDc[0] == 0 && uTruthDc[1] == 0 )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Expand the truth table]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_TruthCountOnes( unsigned * uTruth, int nLeaves )
|
||||
{
|
||||
int i, nMints, Counter;
|
||||
nMints = (1 << nLeaves);
|
||||
Counter = 0;
|
||||
for ( i = 0; i < nMints; i++ )
|
||||
Counter += Map_InfoReadVar( uTruth, i );
|
||||
return Counter;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Expand the truth table]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Map_TruthDetectTwoFirst( unsigned * uTruth, int nLeaves )
|
||||
{
|
||||
int i, nMints, Num1 = -1, Num2 = -1;
|
||||
nMints = (1 << nLeaves);
|
||||
for ( i = 0; i < nMints; i++ )
|
||||
if ( Map_InfoReadVar( uTruth, i ) )
|
||||
// get truth table of the second branch
|
||||
if ( Map_CutIsComplement(pTemp->pTwo) )
|
||||
{
|
||||
if ( Num1 == -1 )
|
||||
Num1 = i;
|
||||
else if ( Num2 == -1 )
|
||||
Num2 = i;
|
||||
else
|
||||
break;
|
||||
uTruth2[0] = ~Map_CutRegular(pTemp->pTwo)->M[0].uPhaseBest;
|
||||
uTruth2[1] = ~Map_CutRegular(pTemp->pTwo)->M[1].uPhaseBest;
|
||||
}
|
||||
assert( Num1 != -1 && Num2 != -1 );
|
||||
return (Num1 << 8) | Num2;
|
||||
else
|
||||
{
|
||||
uTruth2[0] = Map_CutRegular(pTemp->pTwo)->M[0].uPhaseBest;
|
||||
uTruth2[1] = Map_CutRegular(pTemp->pTwo)->M[1].uPhaseBest;
|
||||
}
|
||||
// get the truth table of the output
|
||||
if ( !pTemp->Phase )
|
||||
{
|
||||
pTemp->M[0].uPhaseBest = uTruth1[0] & uTruth2[0];
|
||||
pTemp->M[1].uPhaseBest = uTruth1[1] & uTruth2[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
pTemp->M[0].uPhaseBest = ~(uTruth1[0] & uTruth2[0]);
|
||||
pTemp->M[1].uPhaseBest = ~(uTruth1[1] & uTruth2[1]);
|
||||
}
|
||||
}
|
||||
uTruth[0] = pTemp->M[0].uPhaseBest;
|
||||
uTruth[1] = pTemp->M[1].uPhaseBest;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recursively collect the cuts.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Map_CutsCollect_rec( Map_Cut_t * pCut, Map_NodeVec_t * vVisited )
|
||||
{
|
||||
if ( pCut->fMark )
|
||||
return;
|
||||
Map_CutsCollect_rec( Map_CutRegular(pCut->pOne), vVisited );
|
||||
Map_CutsCollect_rec( Map_CutRegular(pCut->pTwo), vVisited );
|
||||
assert( pCut->fMark == 0 );
|
||||
pCut->fMark = 1;
|
||||
Map_NodeVecPush( vVisited, (Map_Node_t *)pCut );
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -0,0 +1,260 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [fxu.c]
|
||||
|
||||
PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
|
||||
|
||||
Synopsis [The entrance into the fast extract module.]
|
||||
|
||||
Author [MVSIS Group]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - February 1, 2003.]
|
||||
|
||||
Revision [$Id: fxu.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "fxuInt.h"
|
||||
//#include "mvc.h"
|
||||
#include "fxu.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*===== fxuCreate.c ====================================================*/
|
||||
extern Fxu_Matrix * Fxu_CreateMatrix( Fxu_Data_t * pData );
|
||||
extern void Fxu_CreateCovers( Fxu_Matrix * p, Fxu_Data_t * pData );
|
||||
|
||||
static int s_MemoryTotal;
|
||||
static int s_MemoryPeak;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Performs fast_extract on a set of covers.]
|
||||
|
||||
Description [All the covers are given in the array p->ppCovers.
|
||||
The resulting covers are returned in the array p->ppCoversNew.
|
||||
The number of entries in both cover arrays is equal to the number
|
||||
of all values in the current nodes plus the max expected number
|
||||
of extracted nodes (p->nValuesCi + p->nValuesInt + p->nValuesExtMax).
|
||||
The first p->nValuesCi entries, corresponding to the CI nodes, are NULL.
|
||||
The next p->nValuesInt entries, corresponding to the int nodes, are covers
|
||||
from which the divisors are extracted. The last p->nValuesExtMax entries
|
||||
are reserved for the new covers to be extracted. The number of extracted
|
||||
covers is returned. This number does not exceed the given number (p->nNodesExt).
|
||||
Two other things are important for the correct operation of this procedure:
|
||||
(1) The input covers should be SCC-free. (2) The literal array (pCover->pLits)
|
||||
is allocated in each cover. The i-th entry in the literal array of a cover
|
||||
is the number of the cover in the array p->ppCovers, which represents this
|
||||
literal (variable value) in the given cover.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Fxu_FastExtract( Fxu_Data_t * pData )
|
||||
{
|
||||
Fxu_Matrix * p;
|
||||
Fxu_Single * pSingle;
|
||||
Fxu_Double * pDouble;
|
||||
int Weight1, Weight2, Weight3;
|
||||
|
||||
s_MemoryTotal = 0;
|
||||
s_MemoryPeak = 0;
|
||||
|
||||
// create the matrix
|
||||
p = Fxu_CreateMatrix( pData );
|
||||
if ( p == NULL )
|
||||
return -1;
|
||||
// if ( pData->fVerbose )
|
||||
// printf( "Memory usage after construction: Total = %d. Peak = %d.\n", s_MemoryTotal, s_MemoryPeak );
|
||||
//Fxu_MatrixPrint( NULL, p );
|
||||
|
||||
if ( pData->fOnlyS )
|
||||
{
|
||||
pData->nNodesNew = 0;
|
||||
do
|
||||
{
|
||||
Weight1 = Fxu_HeapSingleReadMaxWeight( p->pHeapSingle );
|
||||
if ( pData->fVerbose )
|
||||
printf( "Best single = %3d.\n", Weight1 );
|
||||
if ( Weight1 > 0 || Weight1 == 0 && pData->fUse0 )
|
||||
Fxu_UpdateSingle( p );
|
||||
else
|
||||
break;
|
||||
}
|
||||
while ( ++pData->nNodesNew < pData->nNodesExt );
|
||||
}
|
||||
else if ( pData->fOnlyD )
|
||||
{
|
||||
pData->nNodesNew = 0;
|
||||
do
|
||||
{
|
||||
Weight2 = Fxu_HeapDoubleReadMaxWeight( p->pHeapDouble );
|
||||
if ( pData->fVerbose )
|
||||
printf( "Best double = %3d.\n", Weight2 );
|
||||
if ( Weight2 > 0 || Weight2 == 0 && pData->fUse0 )
|
||||
Fxu_UpdateDouble( p );
|
||||
else
|
||||
break;
|
||||
}
|
||||
while ( ++pData->nNodesNew < pData->nNodesExt );
|
||||
}
|
||||
else if ( !pData->fUseCompl )
|
||||
{
|
||||
pData->nNodesNew = 0;
|
||||
do
|
||||
{
|
||||
Weight1 = Fxu_HeapSingleReadMaxWeight( p->pHeapSingle );
|
||||
Weight2 = Fxu_HeapDoubleReadMaxWeight( p->pHeapDouble );
|
||||
|
||||
if ( pData->fVerbose )
|
||||
printf( "Best double = %3d. Best single = %3d.\n", Weight2, Weight1 );
|
||||
//Fxu_Select( p, &pSingle, &pDouble );
|
||||
|
||||
if ( Weight1 >= Weight2 )
|
||||
{
|
||||
if ( Weight1 > 0 || Weight1 == 0 && pData->fUse0 )
|
||||
Fxu_UpdateSingle( p );
|
||||
else
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( Weight2 > 0 || Weight2 == 0 && pData->fUse0 )
|
||||
Fxu_UpdateDouble( p );
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
while ( ++pData->nNodesNew < pData->nNodesExt );
|
||||
}
|
||||
else
|
||||
{ // use the complement
|
||||
pData->nNodesNew = 0;
|
||||
do
|
||||
{
|
||||
Weight1 = Fxu_HeapSingleReadMaxWeight( p->pHeapSingle );
|
||||
Weight2 = Fxu_HeapDoubleReadMaxWeight( p->pHeapDouble );
|
||||
|
||||
// select the best single and double
|
||||
Weight3 = Fxu_Select( p, &pSingle, &pDouble );
|
||||
if ( pData->fVerbose )
|
||||
printf( "Best double = %3d. Best single = %3d. Best complement = %3d.\n",
|
||||
Weight2, Weight1, Weight3 );
|
||||
|
||||
if ( Weight3 > 0 || Weight3 == 0 && pData->fUse0 )
|
||||
Fxu_Update( p, pSingle, pDouble );
|
||||
else
|
||||
break;
|
||||
}
|
||||
while ( ++pData->nNodesNew < pData->nNodesExt );
|
||||
}
|
||||
|
||||
if ( pData->fVerbose )
|
||||
printf( "Total single = %3d. Total double = %3d. Total compl = %3d.\n", p->nDivs1, p->nDivs2, p->nDivs3 );
|
||||
|
||||
// create the new covers
|
||||
if ( pData->nNodesNew )
|
||||
Fxu_CreateCovers( p, pData );
|
||||
Fxu_MatrixDelete( p );
|
||||
// printf( "Memory usage after delocation: Total = %d. Peak = %d.\n", s_MemoryTotal, s_MemoryPeak );
|
||||
if ( pData->nNodesNew == pData->nNodesExt )
|
||||
printf( "Warning: The limit on the number of extracted divisors has been reached.\n" );
|
||||
return pData->nNodesNew;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Unmarks the cubes in the ring.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_MatrixRingCubesUnmark( Fxu_Matrix * p )
|
||||
{
|
||||
Fxu_Cube * pCube, * pCube2;
|
||||
// unmark the cubes
|
||||
Fxu_MatrixForEachCubeInRingSafe( p, pCube, pCube2 )
|
||||
pCube->pOrder = NULL;
|
||||
Fxu_MatrixRingCubesReset( p );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Unmarks the vars in the ring.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_MatrixRingVarsUnmark( Fxu_Matrix * p )
|
||||
{
|
||||
Fxu_Var * pVar, * pVar2;
|
||||
// unmark the vars
|
||||
Fxu_MatrixForEachVarInRingSafe( p, pVar, pVar2 )
|
||||
pVar->pOrder = NULL;
|
||||
Fxu_MatrixRingVarsReset( p );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
char * Fxu_MemFetch( Fxu_Matrix * p, int nBytes )
|
||||
{
|
||||
s_MemoryTotal += nBytes;
|
||||
if ( s_MemoryPeak < s_MemoryTotal )
|
||||
s_MemoryPeak = s_MemoryTotal;
|
||||
// return malloc( nBytes );
|
||||
return Extra_MmFixedEntryFetch( p->pMemMan );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_MemRecycle( Fxu_Matrix * p, char * pItem, int nBytes )
|
||||
{
|
||||
s_MemoryTotal -= nBytes;
|
||||
// free( pItem );
|
||||
Extra_MmFixedEntryRecycle( p->pMemMan, pItem );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [fxu.h]
|
||||
|
||||
PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
|
||||
|
||||
Synopsis [External declarations of fast extract for unate covers.]
|
||||
|
||||
Author [MVSIS Group]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - February 1, 2003.]
|
||||
|
||||
Revision [$Id: fxu.h,v 1.0 2003/02/01 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __FXU_H__
|
||||
#define __FXU_H__
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "vec.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// STRUCTURE DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef bool
|
||||
#define bool int
|
||||
#endif
|
||||
|
||||
typedef struct FxuDataStruct Fxu_Data_t;
|
||||
|
||||
// structure for the FX input/output data
|
||||
struct FxuDataStruct
|
||||
{
|
||||
// user specified parameters
|
||||
bool fOnlyS; // set to 1 to have only single-cube divs
|
||||
bool fOnlyD; // set to 1 to have only double-cube divs
|
||||
bool fUse0; // set to 1 to have 0-weight also extracted
|
||||
bool fUseCompl; // set to 1 to have complement taken into account
|
||||
bool fVerbose; // set to 1 to have verbose output
|
||||
int nPairsMax; // the maximum number of cube pairs to consider
|
||||
/*
|
||||
// parameters of the network
|
||||
int fMvNetwork; // the network has some MV nodes
|
||||
// the information about nodes
|
||||
int nNodesCi; // the number of CI nodes of the network
|
||||
int nNodesInt; // the number of internal nodes of the network
|
||||
int nNodesOld; // the number of CI and int nodes
|
||||
int nNodesNew; // the number of added nodes
|
||||
int nNodesExt; // the max number of (binary) nodes to be added by FX
|
||||
int nNodesAlloc; // the total number of all nodes
|
||||
int * pNode2Value; // for each node, the number of its first value
|
||||
// the information about values
|
||||
int nValuesCi; // the total number of values of CI nodes
|
||||
int nValuesInt; // the total number of values of int nodes
|
||||
int nValuesOld; // the number of CI and int values
|
||||
int nValuesNew; // the number of values added nodes
|
||||
int nValuesExt; // the total number of values of the added nodes
|
||||
int nValuesAlloc; // the total number of all values of all nodes
|
||||
int * pValue2Node; // for each value, the number of its node
|
||||
// the information about covers
|
||||
Mvc_Cover_t ** ppCovers; // for each value, the corresponding cover
|
||||
Mvc_Cover_t ** ppCoversNew; // for each value, the corresponding cover after FX
|
||||
// the MVC manager
|
||||
Mvc_Manager_t * pManMvc;
|
||||
*/
|
||||
// statistics
|
||||
int nNodesOld; // the old number of nodes
|
||||
int nNodesExt; // the number of divisors to extract
|
||||
int nNodesNew; // the number of divisors extracted
|
||||
|
||||
// the input information
|
||||
Vec_Ptr_t * vSops; // the SOPs for each node in the network
|
||||
Vec_Ptr_t * vFanins; // the fanins of each node in the network
|
||||
// output information
|
||||
Vec_Ptr_t * vSopsNew; // the SOPs for each node in the network after extraction
|
||||
Vec_Ptr_t * vFaninsNew; // the fanins of each node in the network after extraction
|
||||
// the SOP manager
|
||||
Extra_MmFlex_t * pManSop;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*===== fxu.c ==========================================================*/
|
||||
extern int Fxu_FastExtract( Fxu_Data_t * pData );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,425 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [fxuCreate.c]
|
||||
|
||||
PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
|
||||
|
||||
Synopsis [Create matrix from covers and covers from matrix.]
|
||||
|
||||
Author [MVSIS Group]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - February 1, 2003.]
|
||||
|
||||
Revision [$Id: fxuCreate.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "abc.h"
|
||||
#include "fxuInt.h"
|
||||
#include "fxu.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern int Fxu_PreprocessCubePairs( Fxu_Matrix * p, Vec_Ptr_t * vCovers, int nPairsTotal, int nPairsMax );
|
||||
|
||||
static void Fxu_CreateMatrixAddCube( Fxu_Matrix * p, Fxu_Cube * pCube, char * pSopCube, Vec_Fan_t * vFanins, int * pOrder );
|
||||
static int Fxu_CreateMatrixLitCompare( int * ptrX, int * ptrY );
|
||||
static void Fxu_CreateCoversNode( Fxu_Matrix * p, Fxu_Data_t * pData, int iNode, Fxu_Cube * pCubeFirst, Fxu_Cube * pCubeNext );
|
||||
static Fxu_Cube * Fxu_CreateCoversFirstCube( Fxu_Matrix * p, Fxu_Data_t * pData, int iNode );
|
||||
static Abc_Fan_t * s_pLits;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the sparse matrix from the array of Sop covers.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Fxu_Matrix * Fxu_CreateMatrix( Fxu_Data_t * pData )
|
||||
{
|
||||
Fxu_Matrix * p;
|
||||
Fxu_Var * pVar;
|
||||
Fxu_Cube * pCubeFirst, * pCubeNew;
|
||||
Fxu_Cube * pCube1, * pCube2;
|
||||
char * pSopCover;
|
||||
char * pSopCube;
|
||||
int * pOrder, nBitsMax;
|
||||
int i, v, c;
|
||||
int nCubesTotal;
|
||||
int nPairsTotal;
|
||||
int nPairsStore;
|
||||
int nCubes;
|
||||
int iCube, iPair;
|
||||
int nFanins;
|
||||
Vec_Fan_t * vFanins;
|
||||
|
||||
// collect all sorts of statistics
|
||||
nCubesTotal = 0;
|
||||
nPairsTotal = 0;
|
||||
nPairsStore = 0;
|
||||
nBitsMax = -1;
|
||||
for ( i = 0; i < pData->nNodesOld; i++ )
|
||||
if ( pSopCover = pData->vSops->pArray[i] )
|
||||
{
|
||||
nCubes = Abc_SopGetCubeNum( pSopCover );
|
||||
nFanins = Abc_SopGetVarNum( pSopCover );
|
||||
assert( nFanins > 1 && nCubes > 0 );
|
||||
|
||||
nCubesTotal += nCubes;
|
||||
nPairsTotal += nCubes * (nCubes - 1) / 2;
|
||||
nPairsStore += nCubes * nCubes;
|
||||
if ( nBitsMax < nFanins )
|
||||
nBitsMax = nFanins;
|
||||
}
|
||||
if ( nBitsMax <= 0 )
|
||||
{
|
||||
printf( "The current network does not have SOPs to perform extraction.\n" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( nPairsStore > 10000000 )
|
||||
{
|
||||
printf( "The problem is too large to be solved by \"fxu\" (%d cubes and %d cube pairs)\n", nCubesTotal, nPairsStore );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// start the matrix
|
||||
p = Fxu_MatrixAllocate();
|
||||
// create the column labels
|
||||
p->ppVars = ALLOC( Fxu_Var *, 2 * (pData->nNodesOld + pData->nNodesExt) );
|
||||
for ( i = 0; i < 2 * pData->nNodesOld; i++ )
|
||||
p->ppVars[i] = Fxu_MatrixAddVar( p );
|
||||
|
||||
// allocate storage for all cube pairs at once
|
||||
p->pppPairs = ALLOC( Fxu_Pair **, nCubesTotal + 100 );
|
||||
p->ppPairs = ALLOC( Fxu_Pair *, nPairsStore + 100 );
|
||||
memset( p->ppPairs, 0, sizeof(Fxu_Pair *) * nPairsStore );
|
||||
iCube = 0;
|
||||
iPair = 0;
|
||||
for ( i = 0; i < pData->nNodesOld; i++ )
|
||||
if ( pSopCover = pData->vSops->pArray[i] )
|
||||
{
|
||||
// get the number of cubes
|
||||
nCubes = Abc_SopGetCubeNum( pSopCover );
|
||||
// get the new var in the matrix
|
||||
pVar = p->ppVars[2*i+1];
|
||||
// assign the pair storage
|
||||
pVar->nCubes = nCubes;
|
||||
if ( nCubes > 0 )
|
||||
{
|
||||
pVar->ppPairs = p->pppPairs + iCube;
|
||||
pVar->ppPairs[0] = p->ppPairs + iPair;
|
||||
for ( v = 1; v < nCubes; v++ )
|
||||
pVar->ppPairs[v] = pVar->ppPairs[v-1] + nCubes;
|
||||
}
|
||||
// update
|
||||
iCube += nCubes;
|
||||
iPair += nCubes * nCubes;
|
||||
}
|
||||
assert( iCube == nCubesTotal );
|
||||
assert( iPair == nPairsStore );
|
||||
|
||||
|
||||
// allocate room for the reordered literals
|
||||
pOrder = ALLOC( int, nBitsMax );
|
||||
// create the rows
|
||||
for ( i = 0; i < pData->nNodesOld; i++ )
|
||||
if ( pSopCover = pData->vSops->pArray[i] )
|
||||
{
|
||||
// get the new var in the matrix
|
||||
pVar = p->ppVars[2*i+1];
|
||||
// here we sort the literals of the cover
|
||||
// in the increasing order of the numbers of the corresponding nodes
|
||||
// because literals should be added to the matrix in this order
|
||||
vFanins = pData->vFanins->pArray[i];
|
||||
s_pLits = vFanins->pArray;
|
||||
// start the variable order
|
||||
nFanins = Abc_SopGetVarNum( pSopCover );
|
||||
for ( v = 0; v < nFanins; v++ )
|
||||
pOrder[v] = v;
|
||||
// reorder the fanins
|
||||
qsort( (void *)pOrder, nFanins, sizeof(int),(int (*)(const void *, const void *))Fxu_CreateMatrixLitCompare);
|
||||
assert( s_pLits[ pOrder[0] ].iFan < s_pLits[ pOrder[nFanins-1] ].iFan );
|
||||
// create the corresponding cubes in the matrix
|
||||
pCubeFirst = NULL;
|
||||
c = 0;
|
||||
Abc_SopForEachCube( pSopCover, nFanins, pSopCube )
|
||||
{
|
||||
// create the cube
|
||||
pCubeNew = Fxu_MatrixAddCube( p, pVar, c );
|
||||
Fxu_CreateMatrixAddCube( p, pCubeNew, pSopCube, vFanins, pOrder );
|
||||
if ( pCubeFirst == NULL )
|
||||
pCubeFirst = pCubeNew;
|
||||
pCubeNew->pFirst = pCubeFirst;
|
||||
c++;
|
||||
}
|
||||
// set the first cube of this var
|
||||
pVar->pFirst = pCubeFirst;
|
||||
// create the divisors without preprocessing
|
||||
if ( nPairsTotal <= pData->nPairsMax )
|
||||
{
|
||||
for ( pCube1 = pCubeFirst; pCube1; pCube1 = pCube1->pNext )
|
||||
for ( pCube2 = pCube1? pCube1->pNext: NULL; pCube2; pCube2 = pCube2->pNext )
|
||||
Fxu_MatrixAddDivisor( p, pCube1, pCube2 );
|
||||
}
|
||||
}
|
||||
FREE( pOrder );
|
||||
|
||||
// consider the case when cube pairs should be preprocessed
|
||||
// before adding them to the set of divisors
|
||||
if ( nPairsTotal > pData->nPairsMax )
|
||||
Fxu_PreprocessCubePairs( p, pData->vSops, nPairsTotal, pData->nPairsMax );
|
||||
|
||||
// add the var pairs to the heap
|
||||
Fxu_MatrixComputeSingles( p );
|
||||
|
||||
// allocate temporary storage for pairs
|
||||
if ( pData->nPairsMax < 1000 )
|
||||
pData->nPairsMax = 1000;
|
||||
p->pPairsTemp = ALLOC( Fxu_Pair *, pData->nPairsMax * 10 + 100 );
|
||||
if ( pData->fVerbose )
|
||||
{
|
||||
double Density;
|
||||
Density = ((double)p->nEntries) / p->lVars.nItems / p->lCubes.nItems;
|
||||
fprintf( stdout, "Matrix: [vars x cubes] = [%d x %d] ",
|
||||
p->lVars.nItems, p->lCubes.nItems );
|
||||
fprintf( stdout, "Lits = %d Density = %.5f%%\n",
|
||||
p->nEntries, Density );
|
||||
fprintf( stdout, "1-cube divisors = %6d. ", p->lSingles.nItems );
|
||||
fprintf( stdout, "2-cube divisors = %6d. ", p->nDivsTotal );
|
||||
fprintf( stdout, "Cube pairs = %6d.", nPairsTotal );
|
||||
fprintf( stdout, "\n" );
|
||||
}
|
||||
// Fxu_MatrixPrint( stdout, p );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds one cube with literals to the matrix.]
|
||||
|
||||
Description [Create the cube and literals in the matrix corresponding
|
||||
to the given cube in the SOP cover. Co-singleton transform is performed here.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_CreateMatrixAddCube( Fxu_Matrix * p, Fxu_Cube * pCube, char * pSopCube, Vec_Fan_t * vFanins, int * pOrder )
|
||||
{
|
||||
Fxu_Var * pVar;
|
||||
int Value, i;
|
||||
// add literals to the matrix
|
||||
Abc_CubeForEachVar( pSopCube, Value, i )
|
||||
{
|
||||
Value = pSopCube[pOrder[i]];
|
||||
if ( Value == '0' )
|
||||
{
|
||||
pVar = p->ppVars[ 2 * vFanins->pArray[pOrder[i]].iFan + 1 ]; // CST
|
||||
Fxu_MatrixAddLiteral( p, pCube, pVar );
|
||||
}
|
||||
else if ( Value == '1' )
|
||||
{
|
||||
pVar = p->ppVars[ 2 * vFanins->pArray[pOrder[i]].iFan ]; // CST
|
||||
Fxu_MatrixAddLiteral( p, pCube, pVar );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the new array of Sop covers from the sparse matrix.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_CreateCovers( Fxu_Matrix * p, Fxu_Data_t * pData )
|
||||
{
|
||||
Fxu_Cube * pCube, * pCubeFirst, * pCubeNext;
|
||||
int iNode, n;
|
||||
char * pSopCover;
|
||||
|
||||
// get the first cube of the first internal node
|
||||
pCubeFirst = Fxu_CreateCoversFirstCube( p, pData, 0 );
|
||||
|
||||
// go through the internal nodes
|
||||
for ( n = 0; n < pData->nNodesOld; n++ )
|
||||
if ( pSopCover = pData->vSops->pArray[n] )
|
||||
{
|
||||
// get the number of this node
|
||||
iNode = n;
|
||||
// get the next first cube
|
||||
pCubeNext = Fxu_CreateCoversFirstCube( p, pData, iNode + 1 );
|
||||
// check if there any new variables in these cubes
|
||||
for ( pCube = pCubeFirst; pCube != pCubeNext; pCube = pCube->pNext )
|
||||
if ( pCube->lLits.pTail && pCube->lLits.pTail->iVar >= 2 * pData->nNodesOld )
|
||||
break;
|
||||
if ( pCube != pCubeNext )
|
||||
Fxu_CreateCoversNode( p, pData, iNode, pCubeFirst, pCubeNext );
|
||||
// update the first cube
|
||||
pCubeFirst = pCubeNext;
|
||||
}
|
||||
|
||||
// add the covers for the extracted nodes
|
||||
for ( n = 0; n < pData->nNodesNew; n++ )
|
||||
{
|
||||
// get the number of this node
|
||||
iNode = pData->nNodesOld + n;
|
||||
// get the next first cube
|
||||
pCubeNext = Fxu_CreateCoversFirstCube( p, pData, iNode + 1 );
|
||||
// the node should be added
|
||||
Fxu_CreateCoversNode( p, pData, iNode, pCubeFirst, pCubeNext );
|
||||
// update the first cube
|
||||
pCubeFirst = pCubeNext;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Create Sop covers for one node that has changed.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_CreateCoversNode( Fxu_Matrix * p, Fxu_Data_t * pData, int iNode, Fxu_Cube * pCubeFirst, Fxu_Cube * pCubeNext )
|
||||
{
|
||||
Vec_Int_t * vInputsNew;
|
||||
char * pSopCover;
|
||||
char * pSopCube;
|
||||
Fxu_Var * pVar;
|
||||
Fxu_Cube * pCube;
|
||||
Fxu_Lit * pLit;
|
||||
int iNum, nCubes, v;
|
||||
int fEmptyCube;
|
||||
|
||||
// collect positive polarity variable in the cubes between pCubeFirst and pCubeNext
|
||||
Fxu_MatrixRingVarsStart( p );
|
||||
for ( pCube = pCubeFirst; pCube != pCubeNext; pCube = pCube->pNext )
|
||||
for ( pLit = pCube->lLits.pHead; pLit; pLit = pLit->pHNext )
|
||||
{
|
||||
pVar = p->ppVars[ 2 * (pLit->pVar->iVar/2) + 1 ];
|
||||
if ( pVar->pOrder == NULL )
|
||||
Fxu_MatrixRingVarsAdd( p, pVar );
|
||||
}
|
||||
Fxu_MatrixRingVarsStop( p );
|
||||
|
||||
// collect the variable numbers
|
||||
vInputsNew = Vec_IntAlloc( 4 );
|
||||
Fxu_MatrixForEachVarInRing( p, pVar )
|
||||
Vec_IntPush( vInputsNew, pVar->iVar / 2 );
|
||||
Fxu_MatrixRingVarsUnmark( p );
|
||||
|
||||
// sort the vars by their number
|
||||
Vec_IntSort( vInputsNew, 0 );
|
||||
|
||||
// mark the vars with their numbers in the sorted array
|
||||
for ( v = 0; v < vInputsNew->nSize; v++ )
|
||||
{
|
||||
p->ppVars[ 2 * vInputsNew->pArray[v] + 0 ]->lLits.nItems = v; // hack - reuse lLits.nItems
|
||||
p->ppVars[ 2 * vInputsNew->pArray[v] + 1 ]->lLits.nItems = v; // hack - reuse lLits.nItems
|
||||
}
|
||||
|
||||
// count the number of cubes
|
||||
nCubes = 0;
|
||||
for ( pCube = pCubeFirst; pCube != pCubeNext; pCube = pCube->pNext )
|
||||
if ( pCube->lLits.nItems )
|
||||
nCubes++;
|
||||
|
||||
// allocate room for the new cover
|
||||
pSopCover = Abc_SopStart( pData->pManSop, nCubes, vInputsNew->nSize );
|
||||
// set the correct polarity of the cover
|
||||
if ( iNode < pData->nNodesOld && Abc_SopGetPhase( pData->vSops->pArray[iNode] ) == 0 )
|
||||
Abc_SopComplement( pSopCover );
|
||||
|
||||
// add the cubes
|
||||
nCubes = 0;
|
||||
for ( pCube = pCubeFirst; pCube != pCubeNext; pCube = pCube->pNext )
|
||||
{
|
||||
if ( pCube->lLits.nItems == 0 )
|
||||
continue;
|
||||
// get hold of the SOP cube
|
||||
pSopCube = pSopCover + nCubes * (vInputsNew->nSize + 3);
|
||||
// insert literals
|
||||
fEmptyCube = 1;
|
||||
for ( pLit = pCube->lLits.pHead; pLit; pLit = pLit->pHNext )
|
||||
{
|
||||
iNum = pLit->pVar->lLits.nItems; // hack - reuse lLits.nItems
|
||||
assert( iNum < vInputsNew->nSize );
|
||||
if ( pLit->pVar->iVar / 2 < pData->nNodesOld )
|
||||
pSopCube[iNum] = (pLit->pVar->iVar & 1)? '0' : '1'; // reverse CST
|
||||
else
|
||||
pSopCube[iNum] = (pLit->pVar->iVar & 1)? '1' : '0'; // no CST
|
||||
fEmptyCube = 0;
|
||||
}
|
||||
assert( !fEmptyCube );
|
||||
// count the cube
|
||||
nCubes++;
|
||||
}
|
||||
assert( nCubes == Abc_SopGetCubeNum(pSopCover) );
|
||||
|
||||
pData->vSopsNew->pArray[iNode] = pSopCover;
|
||||
pData->vFaninsNew->pArray[iNode] = vInputsNew;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds the var to storage.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Fxu_Cube * Fxu_CreateCoversFirstCube( Fxu_Matrix * p, Fxu_Data_t * pData, int iVar )
|
||||
{
|
||||
int v;
|
||||
for ( v = iVar; v < pData->nNodesOld + pData->nNodesNew; v++ )
|
||||
if ( p->ppVars[ 2*v + 1 ]->pFirst )
|
||||
return p->ppVars[ 2*v + 1 ]->pFirst;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Compares the vars by their number.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Fxu_CreateMatrixLitCompare( int * ptrX, int * ptrY )
|
||||
{
|
||||
return s_pLits[*ptrX].iFan - s_pLits[*ptrY].iFan;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -0,0 +1,445 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [fxuHeapD.c]
|
||||
|
||||
PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
|
||||
|
||||
Synopsis [The priority queue for double cube divisors.]
|
||||
|
||||
Author [MVSIS Group]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - February 1, 2003.]
|
||||
|
||||
Revision [$Id: fxuHeapD.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "fxuInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define FXU_HEAP_DOUBLE_WEIGHT(pDiv) ((pDiv)->Weight)
|
||||
#define FXU_HEAP_DOUBLE_CURRENT(p, pDiv) ((p)->pTree[(pDiv)->HNum])
|
||||
#define FXU_HEAP_DOUBLE_PARENT_EXISTS(p, pDiv) ((pDiv)->HNum > 1)
|
||||
#define FXU_HEAP_DOUBLE_CHILD1_EXISTS(p, pDiv) (((pDiv)->HNum << 1) <= p->nItems)
|
||||
#define FXU_HEAP_DOUBLE_CHILD2_EXISTS(p, pDiv) ((((pDiv)->HNum << 1)+1) <= p->nItems)
|
||||
#define FXU_HEAP_DOUBLE_PARENT(p, pDiv) ((p)->pTree[(pDiv)->HNum >> 1])
|
||||
#define FXU_HEAP_DOUBLE_CHILD1(p, pDiv) ((p)->pTree[(pDiv)->HNum << 1])
|
||||
#define FXU_HEAP_DOUBLE_CHILD2(p, pDiv) ((p)->pTree[((pDiv)->HNum << 1)+1])
|
||||
#define FXU_HEAP_DOUBLE_ASSERT(p, pDiv) assert( (pDiv)->HNum >= 1 && (pDiv)->HNum <= p->nItemsAlloc )
|
||||
|
||||
static void Fxu_HeapDoubleResize( Fxu_HeapDouble * p );
|
||||
static void Fxu_HeapDoubleSwap( Fxu_Double ** pDiv1, Fxu_Double ** pDiv2 );
|
||||
static void Fxu_HeapDoubleMoveUp( Fxu_HeapDouble * p, Fxu_Double * pDiv );
|
||||
static void Fxu_HeapDoubleMoveDn( Fxu_HeapDouble * p, Fxu_Double * pDiv );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Fxu_HeapDouble * Fxu_HeapDoubleStart()
|
||||
{
|
||||
Fxu_HeapDouble * p;
|
||||
p = ALLOC( Fxu_HeapDouble, 1 );
|
||||
memset( p, 0, sizeof(Fxu_HeapDouble) );
|
||||
p->nItems = 0;
|
||||
p->nItemsAlloc = 10000;
|
||||
p->pTree = ALLOC( Fxu_Double *, p->nItemsAlloc + 1 );
|
||||
p->pTree[0] = NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_HeapDoubleResize( Fxu_HeapDouble * p )
|
||||
{
|
||||
p->nItemsAlloc *= 2;
|
||||
p->pTree = REALLOC( Fxu_Double *, p->pTree, p->nItemsAlloc + 1 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_HeapDoubleStop( Fxu_HeapDouble * p )
|
||||
{
|
||||
free( p->pTree );
|
||||
free( p );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_HeapDoublePrint( FILE * pFile, Fxu_HeapDouble * p )
|
||||
{
|
||||
Fxu_Double * pDiv;
|
||||
int Counter = 1;
|
||||
int Degree = 1;
|
||||
|
||||
Fxu_HeapDoubleCheck( p );
|
||||
fprintf( pFile, "The contents of the heap:\n" );
|
||||
fprintf( pFile, "Level %d: ", Degree );
|
||||
Fxu_HeapDoubleForEachItem( p, pDiv )
|
||||
{
|
||||
assert( Counter == p->pTree[Counter]->HNum );
|
||||
fprintf( pFile, "%2d=%3d ", Counter, FXU_HEAP_DOUBLE_WEIGHT(p->pTree[Counter]) );
|
||||
if ( ++Counter == (1 << Degree) )
|
||||
{
|
||||
fprintf( pFile, "\n" );
|
||||
Degree++;
|
||||
fprintf( pFile, "Level %d: ", Degree );
|
||||
}
|
||||
}
|
||||
fprintf( pFile, "\n" );
|
||||
fprintf( pFile, "End of the heap printout.\n" );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_HeapDoubleCheck( Fxu_HeapDouble * p )
|
||||
{
|
||||
Fxu_Double * pDiv;
|
||||
Fxu_HeapDoubleForEachItem( p, pDiv )
|
||||
{
|
||||
assert( pDiv->HNum == p->i );
|
||||
Fxu_HeapDoubleCheckOne( p, pDiv );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_HeapDoubleCheckOne( Fxu_HeapDouble * p, Fxu_Double * pDiv )
|
||||
{
|
||||
int Weight1, Weight2;
|
||||
if ( FXU_HEAP_DOUBLE_CHILD1_EXISTS(p,pDiv) )
|
||||
{
|
||||
Weight1 = FXU_HEAP_DOUBLE_WEIGHT(pDiv);
|
||||
Weight2 = FXU_HEAP_DOUBLE_WEIGHT( FXU_HEAP_DOUBLE_CHILD1(p,pDiv) );
|
||||
assert( Weight1 >= Weight2 );
|
||||
}
|
||||
if ( FXU_HEAP_DOUBLE_CHILD2_EXISTS(p,pDiv) )
|
||||
{
|
||||
Weight1 = FXU_HEAP_DOUBLE_WEIGHT(pDiv);
|
||||
Weight2 = FXU_HEAP_DOUBLE_WEIGHT( FXU_HEAP_DOUBLE_CHILD2(p,pDiv) );
|
||||
assert( Weight1 >= Weight2 );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_HeapDoubleInsert( Fxu_HeapDouble * p, Fxu_Double * pDiv )
|
||||
{
|
||||
if ( p->nItems == p->nItemsAlloc )
|
||||
Fxu_HeapDoubleResize( p );
|
||||
// put the last entry to the last place and move up
|
||||
p->pTree[++p->nItems] = pDiv;
|
||||
pDiv->HNum = p->nItems;
|
||||
// move the last entry up if necessary
|
||||
Fxu_HeapDoubleMoveUp( p, pDiv );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_HeapDoubleUpdate( Fxu_HeapDouble * p, Fxu_Double * pDiv )
|
||||
{
|
||||
//printf( "Updating divisor %d.\n", pDiv->Num );
|
||||
|
||||
FXU_HEAP_DOUBLE_ASSERT(p,pDiv);
|
||||
if ( FXU_HEAP_DOUBLE_PARENT_EXISTS(p,pDiv) &&
|
||||
FXU_HEAP_DOUBLE_WEIGHT(pDiv) > FXU_HEAP_DOUBLE_WEIGHT( FXU_HEAP_DOUBLE_PARENT(p,pDiv) ) )
|
||||
Fxu_HeapDoubleMoveUp( p, pDiv );
|
||||
else if ( FXU_HEAP_DOUBLE_CHILD1_EXISTS(p,pDiv) &&
|
||||
FXU_HEAP_DOUBLE_WEIGHT(pDiv) < FXU_HEAP_DOUBLE_WEIGHT( FXU_HEAP_DOUBLE_CHILD1(p,pDiv) ) )
|
||||
Fxu_HeapDoubleMoveDn( p, pDiv );
|
||||
else if ( FXU_HEAP_DOUBLE_CHILD2_EXISTS(p,pDiv) &&
|
||||
FXU_HEAP_DOUBLE_WEIGHT(pDiv) < FXU_HEAP_DOUBLE_WEIGHT( FXU_HEAP_DOUBLE_CHILD2(p,pDiv) ) )
|
||||
Fxu_HeapDoubleMoveDn( p, pDiv );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_HeapDoubleDelete( Fxu_HeapDouble * p, Fxu_Double * pDiv )
|
||||
{
|
||||
FXU_HEAP_DOUBLE_ASSERT(p,pDiv);
|
||||
// put the last entry to the deleted place
|
||||
// decrement the number of entries
|
||||
p->pTree[pDiv->HNum] = p->pTree[p->nItems--];
|
||||
p->pTree[pDiv->HNum]->HNum = pDiv->HNum;
|
||||
// move the top entry down if necessary
|
||||
Fxu_HeapDoubleUpdate( p, p->pTree[pDiv->HNum] );
|
||||
pDiv->HNum = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Fxu_Double * Fxu_HeapDoubleReadMax( Fxu_HeapDouble * p )
|
||||
{
|
||||
if ( p->nItems == 0 )
|
||||
return NULL;
|
||||
return p->pTree[1];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Fxu_Double * Fxu_HeapDoubleGetMax( Fxu_HeapDouble * p )
|
||||
{
|
||||
Fxu_Double * pDiv;
|
||||
if ( p->nItems == 0 )
|
||||
return NULL;
|
||||
// prepare the return value
|
||||
pDiv = p->pTree[1];
|
||||
pDiv->HNum = 0;
|
||||
// put the last entry on top
|
||||
// decrement the number of entries
|
||||
p->pTree[1] = p->pTree[p->nItems--];
|
||||
p->pTree[1]->HNum = 1;
|
||||
// move the top entry down if necessary
|
||||
Fxu_HeapDoubleMoveDn( p, p->pTree[1] );
|
||||
return pDiv;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Fxu_HeapDoubleReadMaxWeight( Fxu_HeapDouble * p )
|
||||
{
|
||||
if ( p->nItems == 0 )
|
||||
return -1;
|
||||
else
|
||||
return FXU_HEAP_DOUBLE_WEIGHT(p->pTree[1]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_HeapDoubleSwap( Fxu_Double ** pDiv1, Fxu_Double ** pDiv2 )
|
||||
{
|
||||
Fxu_Double * pDiv;
|
||||
int Temp;
|
||||
pDiv = *pDiv1;
|
||||
*pDiv1 = *pDiv2;
|
||||
*pDiv2 = pDiv;
|
||||
Temp = (*pDiv1)->HNum;
|
||||
(*pDiv1)->HNum = (*pDiv2)->HNum;
|
||||
(*pDiv2)->HNum = Temp;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_HeapDoubleMoveUp( Fxu_HeapDouble * p, Fxu_Double * pDiv )
|
||||
{
|
||||
Fxu_Double ** ppDiv, ** ppPar;
|
||||
ppDiv = &FXU_HEAP_DOUBLE_CURRENT(p, pDiv);
|
||||
while ( FXU_HEAP_DOUBLE_PARENT_EXISTS(p,*ppDiv) )
|
||||
{
|
||||
ppPar = &FXU_HEAP_DOUBLE_PARENT(p,*ppDiv);
|
||||
if ( FXU_HEAP_DOUBLE_WEIGHT(*ppDiv) > FXU_HEAP_DOUBLE_WEIGHT(*ppPar) )
|
||||
{
|
||||
Fxu_HeapDoubleSwap( ppDiv, ppPar );
|
||||
ppDiv = ppPar;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_HeapDoubleMoveDn( Fxu_HeapDouble * p, Fxu_Double * pDiv )
|
||||
{
|
||||
Fxu_Double ** ppChild1, ** ppChild2, ** ppDiv;
|
||||
ppDiv = &FXU_HEAP_DOUBLE_CURRENT(p, pDiv);
|
||||
while ( FXU_HEAP_DOUBLE_CHILD1_EXISTS(p,*ppDiv) )
|
||||
{ // if Child1 does not exist, Child2 also does not exists
|
||||
|
||||
// get the children
|
||||
ppChild1 = &FXU_HEAP_DOUBLE_CHILD1(p,*ppDiv);
|
||||
if ( FXU_HEAP_DOUBLE_CHILD2_EXISTS(p,*ppDiv) )
|
||||
{
|
||||
ppChild2 = &FXU_HEAP_DOUBLE_CHILD2(p,*ppDiv);
|
||||
|
||||
// consider two cases
|
||||
if ( FXU_HEAP_DOUBLE_WEIGHT(*ppDiv) >= FXU_HEAP_DOUBLE_WEIGHT(*ppChild1) &&
|
||||
FXU_HEAP_DOUBLE_WEIGHT(*ppDiv) >= FXU_HEAP_DOUBLE_WEIGHT(*ppChild2) )
|
||||
{ // Div is larger than both, skip
|
||||
break;
|
||||
}
|
||||
else
|
||||
{ // Div is smaller than one of them, then swap it with larger
|
||||
if ( FXU_HEAP_DOUBLE_WEIGHT(*ppChild1) >= FXU_HEAP_DOUBLE_WEIGHT(*ppChild2) )
|
||||
{
|
||||
Fxu_HeapDoubleSwap( ppDiv, ppChild1 );
|
||||
// update the pointer
|
||||
ppDiv = ppChild1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Fxu_HeapDoubleSwap( ppDiv, ppChild2 );
|
||||
// update the pointer
|
||||
ppDiv = ppChild2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // Child2 does not exist
|
||||
{
|
||||
// consider two cases
|
||||
if ( FXU_HEAP_DOUBLE_WEIGHT(*ppDiv) >= FXU_HEAP_DOUBLE_WEIGHT(*ppChild1) )
|
||||
{ // Div is larger than Child1, skip
|
||||
break;
|
||||
}
|
||||
else
|
||||
{ // Div is smaller than Child1, then swap them
|
||||
Fxu_HeapDoubleSwap( ppDiv, ppChild1 );
|
||||
// update the pointer
|
||||
ppDiv = ppChild1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,444 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [fxuHeapS.c]
|
||||
|
||||
PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
|
||||
|
||||
Synopsis [The priority queue for variables.]
|
||||
|
||||
Author [MVSIS Group]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - February 1, 2003.]
|
||||
|
||||
Revision [$Id: fxuHeapS.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "fxuInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define FXU_HEAP_SINGLE_WEIGHT(pSingle) ((pSingle)->Weight)
|
||||
#define FXU_HEAP_SINGLE_CURRENT(p, pSingle) ((p)->pTree[(pSingle)->HNum])
|
||||
#define FXU_HEAP_SINGLE_PARENT_EXISTS(p, pSingle) ((pSingle)->HNum > 1)
|
||||
#define FXU_HEAP_SINGLE_CHILD1_EXISTS(p, pSingle) (((pSingle)->HNum << 1) <= p->nItems)
|
||||
#define FXU_HEAP_SINGLE_CHILD2_EXISTS(p, pSingle) ((((pSingle)->HNum << 1)+1) <= p->nItems)
|
||||
#define FXU_HEAP_SINGLE_PARENT(p, pSingle) ((p)->pTree[(pSingle)->HNum >> 1])
|
||||
#define FXU_HEAP_SINGLE_CHILD1(p, pSingle) ((p)->pTree[(pSingle)->HNum << 1])
|
||||
#define FXU_HEAP_SINGLE_CHILD2(p, pSingle) ((p)->pTree[((pSingle)->HNum << 1)+1])
|
||||
#define FXU_HEAP_SINGLE_ASSERT(p, pSingle) assert( (pSingle)->HNum >= 1 && (pSingle)->HNum <= p->nItemsAlloc )
|
||||
|
||||
static void Fxu_HeapSingleResize( Fxu_HeapSingle * p );
|
||||
static void Fxu_HeapSingleSwap( Fxu_Single ** pSingle1, Fxu_Single ** pSingle2 );
|
||||
static void Fxu_HeapSingleMoveUp( Fxu_HeapSingle * p, Fxu_Single * pSingle );
|
||||
static void Fxu_HeapSingleMoveDn( Fxu_HeapSingle * p, Fxu_Single * pSingle );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Fxu_HeapSingle * Fxu_HeapSingleStart()
|
||||
{
|
||||
Fxu_HeapSingle * p;
|
||||
p = ALLOC( Fxu_HeapSingle, 1 );
|
||||
memset( p, 0, sizeof(Fxu_HeapSingle) );
|
||||
p->nItems = 0;
|
||||
p->nItemsAlloc = 2000;
|
||||
p->pTree = ALLOC( Fxu_Single *, p->nItemsAlloc + 10 );
|
||||
p->pTree[0] = NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_HeapSingleResize( Fxu_HeapSingle * p )
|
||||
{
|
||||
p->nItemsAlloc *= 2;
|
||||
p->pTree = REALLOC( Fxu_Single *, p->pTree, p->nItemsAlloc + 10 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_HeapSingleStop( Fxu_HeapSingle * p )
|
||||
{
|
||||
int i;
|
||||
i = 0;
|
||||
free( p->pTree );
|
||||
i = 1;
|
||||
free( p );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_HeapSinglePrint( FILE * pFile, Fxu_HeapSingle * p )
|
||||
{
|
||||
Fxu_Single * pSingle;
|
||||
int Counter = 1;
|
||||
int Degree = 1;
|
||||
|
||||
Fxu_HeapSingleCheck( p );
|
||||
fprintf( pFile, "The contents of the heap:\n" );
|
||||
fprintf( pFile, "Level %d: ", Degree );
|
||||
Fxu_HeapSingleForEachItem( p, pSingle )
|
||||
{
|
||||
assert( Counter == p->pTree[Counter]->HNum );
|
||||
fprintf( pFile, "%2d=%3d ", Counter, FXU_HEAP_SINGLE_WEIGHT(p->pTree[Counter]) );
|
||||
if ( ++Counter == (1 << Degree) )
|
||||
{
|
||||
fprintf( pFile, "\n" );
|
||||
Degree++;
|
||||
fprintf( pFile, "Level %d: ", Degree );
|
||||
}
|
||||
}
|
||||
fprintf( pFile, "\n" );
|
||||
fprintf( pFile, "End of the heap printout.\n" );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_HeapSingleCheck( Fxu_HeapSingle * p )
|
||||
{
|
||||
Fxu_Single * pSingle;
|
||||
Fxu_HeapSingleForEachItem( p, pSingle )
|
||||
{
|
||||
assert( pSingle->HNum == p->i );
|
||||
Fxu_HeapSingleCheckOne( p, pSingle );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_HeapSingleCheckOne( Fxu_HeapSingle * p, Fxu_Single * pSingle )
|
||||
{
|
||||
int Weight1, Weight2;
|
||||
if ( FXU_HEAP_SINGLE_CHILD1_EXISTS(p,pSingle) )
|
||||
{
|
||||
Weight1 = FXU_HEAP_SINGLE_WEIGHT(pSingle);
|
||||
Weight2 = FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_CHILD1(p,pSingle) );
|
||||
assert( Weight1 >= Weight2 );
|
||||
}
|
||||
if ( FXU_HEAP_SINGLE_CHILD2_EXISTS(p,pSingle) )
|
||||
{
|
||||
Weight1 = FXU_HEAP_SINGLE_WEIGHT(pSingle);
|
||||
Weight2 = FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_CHILD2(p,pSingle) );
|
||||
assert( Weight1 >= Weight2 );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_HeapSingleInsert( Fxu_HeapSingle * p, Fxu_Single * pSingle )
|
||||
{
|
||||
if ( p->nItems == p->nItemsAlloc )
|
||||
Fxu_HeapSingleResize( p );
|
||||
// put the last entry to the last place and move up
|
||||
p->pTree[++p->nItems] = pSingle;
|
||||
pSingle->HNum = p->nItems;
|
||||
// move the last entry up if necessary
|
||||
Fxu_HeapSingleMoveUp( p, pSingle );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_HeapSingleUpdate( Fxu_HeapSingle * p, Fxu_Single * pSingle )
|
||||
{
|
||||
FXU_HEAP_SINGLE_ASSERT(p,pSingle);
|
||||
if ( FXU_HEAP_SINGLE_PARENT_EXISTS(p,pSingle) &&
|
||||
FXU_HEAP_SINGLE_WEIGHT(pSingle) > FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_PARENT(p,pSingle) ) )
|
||||
Fxu_HeapSingleMoveUp( p, pSingle );
|
||||
else if ( FXU_HEAP_SINGLE_CHILD1_EXISTS(p,pSingle) &&
|
||||
FXU_HEAP_SINGLE_WEIGHT(pSingle) < FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_CHILD1(p,pSingle) ) )
|
||||
Fxu_HeapSingleMoveDn( p, pSingle );
|
||||
else if ( FXU_HEAP_SINGLE_CHILD2_EXISTS(p,pSingle) &&
|
||||
FXU_HEAP_SINGLE_WEIGHT(pSingle) < FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_CHILD2(p,pSingle) ) )
|
||||
Fxu_HeapSingleMoveDn( p, pSingle );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_HeapSingleDelete( Fxu_HeapSingle * p, Fxu_Single * pSingle )
|
||||
{
|
||||
int Place = pSingle->HNum;
|
||||
FXU_HEAP_SINGLE_ASSERT(p,pSingle);
|
||||
// put the last entry to the deleted place
|
||||
// decrement the number of entries
|
||||
p->pTree[Place] = p->pTree[p->nItems--];
|
||||
p->pTree[Place]->HNum = Place;
|
||||
// move the top entry down if necessary
|
||||
Fxu_HeapSingleUpdate( p, p->pTree[Place] );
|
||||
pSingle->HNum = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Fxu_Single * Fxu_HeapSingleReadMax( Fxu_HeapSingle * p )
|
||||
{
|
||||
if ( p->nItems == 0 )
|
||||
return NULL;
|
||||
return p->pTree[1];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Fxu_Single * Fxu_HeapSingleGetMax( Fxu_HeapSingle * p )
|
||||
{
|
||||
Fxu_Single * pSingle;
|
||||
if ( p->nItems == 0 )
|
||||
return NULL;
|
||||
// prepare the return value
|
||||
pSingle = p->pTree[1];
|
||||
pSingle->HNum = 0;
|
||||
// put the last entry on top
|
||||
// decrement the number of entries
|
||||
p->pTree[1] = p->pTree[p->nItems--];
|
||||
p->pTree[1]->HNum = 1;
|
||||
// move the top entry down if necessary
|
||||
Fxu_HeapSingleMoveDn( p, p->pTree[1] );
|
||||
return pSingle;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Fxu_HeapSingleReadMaxWeight( Fxu_HeapSingle * p )
|
||||
{
|
||||
if ( p->nItems == 0 )
|
||||
return -1;
|
||||
return FXU_HEAP_SINGLE_WEIGHT(p->pTree[1]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_HeapSingleSwap( Fxu_Single ** pSingle1, Fxu_Single ** pSingle2 )
|
||||
{
|
||||
Fxu_Single * pSingle;
|
||||
int Temp;
|
||||
pSingle = *pSingle1;
|
||||
*pSingle1 = *pSingle2;
|
||||
*pSingle2 = pSingle;
|
||||
Temp = (*pSingle1)->HNum;
|
||||
(*pSingle1)->HNum = (*pSingle2)->HNum;
|
||||
(*pSingle2)->HNum = Temp;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_HeapSingleMoveUp( Fxu_HeapSingle * p, Fxu_Single * pSingle )
|
||||
{
|
||||
Fxu_Single ** ppSingle, ** ppPar;
|
||||
ppSingle = &FXU_HEAP_SINGLE_CURRENT(p, pSingle);
|
||||
while ( FXU_HEAP_SINGLE_PARENT_EXISTS(p,*ppSingle) )
|
||||
{
|
||||
ppPar = &FXU_HEAP_SINGLE_PARENT(p,*ppSingle);
|
||||
if ( FXU_HEAP_SINGLE_WEIGHT(*ppSingle) > FXU_HEAP_SINGLE_WEIGHT(*ppPar) )
|
||||
{
|
||||
Fxu_HeapSingleSwap( ppSingle, ppPar );
|
||||
ppSingle = ppPar;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_HeapSingleMoveDn( Fxu_HeapSingle * p, Fxu_Single * pSingle )
|
||||
{
|
||||
Fxu_Single ** ppChild1, ** ppChild2, ** ppSingle;
|
||||
ppSingle = &FXU_HEAP_SINGLE_CURRENT(p, pSingle);
|
||||
while ( FXU_HEAP_SINGLE_CHILD1_EXISTS(p,*ppSingle) )
|
||||
{ // if Child1 does not exist, Child2 also does not exists
|
||||
|
||||
// get the children
|
||||
ppChild1 = &FXU_HEAP_SINGLE_CHILD1(p,*ppSingle);
|
||||
if ( FXU_HEAP_SINGLE_CHILD2_EXISTS(p,*ppSingle) )
|
||||
{
|
||||
ppChild2 = &FXU_HEAP_SINGLE_CHILD2(p,*ppSingle);
|
||||
|
||||
// consider two cases
|
||||
if ( FXU_HEAP_SINGLE_WEIGHT(*ppSingle) >= FXU_HEAP_SINGLE_WEIGHT(*ppChild1) &&
|
||||
FXU_HEAP_SINGLE_WEIGHT(*ppSingle) >= FXU_HEAP_SINGLE_WEIGHT(*ppChild2) )
|
||||
{ // Var is larger than both, skip
|
||||
break;
|
||||
}
|
||||
else
|
||||
{ // Var is smaller than one of them, then swap it with larger
|
||||
if ( FXU_HEAP_SINGLE_WEIGHT(*ppChild1) >= FXU_HEAP_SINGLE_WEIGHT(*ppChild2) )
|
||||
{
|
||||
Fxu_HeapSingleSwap( ppSingle, ppChild1 );
|
||||
// update the pointer
|
||||
ppSingle = ppChild1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Fxu_HeapSingleSwap( ppSingle, ppChild2 );
|
||||
// update the pointer
|
||||
ppSingle = ppChild2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // Child2 does not exist
|
||||
{
|
||||
// consider two cases
|
||||
if ( FXU_HEAP_SINGLE_WEIGHT(*ppSingle) >= FXU_HEAP_SINGLE_WEIGHT(*ppChild1) )
|
||||
{ // Var is larger than Child1, skip
|
||||
break;
|
||||
}
|
||||
else
|
||||
{ // Var is smaller than Child1, then swap them
|
||||
Fxu_HeapSingleSwap( ppSingle, ppChild1 );
|
||||
// update the pointer
|
||||
ppSingle = ppChild1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -0,0 +1,541 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [fxuInt.h]
|
||||
|
||||
PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
|
||||
|
||||
Synopsis [Internal declarations of fast extract for unate covers.]
|
||||
|
||||
Author [MVSIS Group]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - February 1, 2003.]
|
||||
|
||||
Revision [$Id: fxuInt.h,v 1.3 2003/04/10 05:42:44 donald Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __FXU_INT_H__
|
||||
#define __FXU_INT_H__
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "util.h"
|
||||
#include "extra.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// uncomment this macro to switch to standard memory management
|
||||
//#define USE_SYSTEM_MEMORY_MANAGEMENT
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// STRUCTURE DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
Here is an informal description of the FX data structure.
|
||||
(1) The sparse matrix is filled with literals, associated with
|
||||
cubes (row) and variables (columns). The matrix contains
|
||||
all the cubes of all the nodes in the network.
|
||||
(2) A cube is associated with
|
||||
(a) its literals in the matrix,
|
||||
(b) the output variable of the node, to which this cube belongs,
|
||||
(3) A variable is associated with
|
||||
(a) its literals in the matrix and
|
||||
(b) the list of cube pairs in the cover, for which it is the output
|
||||
(4) A cube pair is associated with two cubes and contains the counters
|
||||
of literals in the base and in the cubes without the base
|
||||
(5) A double-cube divisor is associated with list of all cube pairs
|
||||
that produce it and its current weight (which is updated automatically
|
||||
each time a new pair is added or an old pair is removed).
|
||||
(6) A single-cube divisor is associated the pair of variables.
|
||||
*/
|
||||
|
||||
// sparse matrix
|
||||
typedef struct FxuMatrix Fxu_Matrix; // the sparse matrix
|
||||
|
||||
// sparse matrix contents: cubes (rows), vars (columns), literals (entries)
|
||||
typedef struct FxuCube Fxu_Cube; // one cube in the sparse matrix
|
||||
typedef struct FxuVar Fxu_Var; // one literal in the sparse matrix
|
||||
typedef struct FxuLit Fxu_Lit; // one entry in the sparse matrix
|
||||
|
||||
// double cube divisors
|
||||
typedef struct FxuPair Fxu_Pair; // the pair of cubes
|
||||
typedef struct FxuDouble Fxu_Double; // the double-cube divisor
|
||||
typedef struct FxuSingle Fxu_Single; // the two-literal single-cube divisor
|
||||
|
||||
// various lists
|
||||
typedef struct FxuListCube Fxu_ListCube; // the list of cubes
|
||||
typedef struct FxuListVar Fxu_ListVar; // the list of literals
|
||||
typedef struct FxuListLit Fxu_ListLit; // the list of entries
|
||||
typedef struct FxuListPair Fxu_ListPair; // the list of pairs
|
||||
typedef struct FxuListDouble Fxu_ListDouble; // the list of divisors
|
||||
typedef struct FxuListSingle Fxu_ListSingle; // the list of single-cube divisors
|
||||
|
||||
// various heaps
|
||||
typedef struct FxuHeapDouble Fxu_HeapDouble; // the heap of divisors
|
||||
typedef struct FxuHeapSingle Fxu_HeapSingle; // the heap of variables
|
||||
|
||||
|
||||
// various lists
|
||||
|
||||
// the list of cubes in the sparse matrix
|
||||
struct FxuListCube
|
||||
{
|
||||
Fxu_Cube * pHead;
|
||||
Fxu_Cube * pTail;
|
||||
int nItems;
|
||||
};
|
||||
|
||||
// the list of literals in the sparse matrix
|
||||
struct FxuListVar
|
||||
{
|
||||
Fxu_Var * pHead;
|
||||
Fxu_Var * pTail;
|
||||
int nItems;
|
||||
};
|
||||
|
||||
// the list of entries in the sparse matrix
|
||||
struct FxuListLit
|
||||
{
|
||||
Fxu_Lit * pHead;
|
||||
Fxu_Lit * pTail;
|
||||
int nItems;
|
||||
};
|
||||
|
||||
// the list of cube pair in the sparse matrix
|
||||
struct FxuListPair
|
||||
{
|
||||
Fxu_Pair * pHead;
|
||||
Fxu_Pair * pTail;
|
||||
int nItems;
|
||||
};
|
||||
|
||||
// the list of divisors in the sparse matrix
|
||||
struct FxuListDouble
|
||||
{
|
||||
Fxu_Double * pHead;
|
||||
Fxu_Double * pTail;
|
||||
int nItems;
|
||||
};
|
||||
|
||||
// the list of divisors in the sparse matrix
|
||||
struct FxuListSingle
|
||||
{
|
||||
Fxu_Single * pHead;
|
||||
Fxu_Single * pTail;
|
||||
int nItems;
|
||||
};
|
||||
|
||||
|
||||
// various heaps
|
||||
|
||||
// the heap of double cube divisors by weight
|
||||
struct FxuHeapDouble
|
||||
{
|
||||
Fxu_Double ** pTree;
|
||||
int nItems;
|
||||
int nItemsAlloc;
|
||||
int i;
|
||||
};
|
||||
|
||||
// the heap of variable by their occurrence in the cubes
|
||||
struct FxuHeapSingle
|
||||
{
|
||||
Fxu_Single ** pTree;
|
||||
int nItems;
|
||||
int nItemsAlloc;
|
||||
int i;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// sparse matrix
|
||||
struct FxuMatrix // ~ 30 words
|
||||
{
|
||||
// information about the network
|
||||
// int fMvNetwork; // set to 1 if the network has MV nodes
|
||||
// int * pValue2Node; // the mapping of values into nodes
|
||||
// the cubes
|
||||
Fxu_ListCube lCubes; // the double linked list of cubes
|
||||
// the values (binary literals)
|
||||
Fxu_ListVar lVars; // the double linked list of variables
|
||||
Fxu_Var ** ppVars; // the array of variables
|
||||
// the double cube divisors
|
||||
Fxu_ListDouble * pTable; // the hash table of divisors
|
||||
int nTableSize; // the hash table size
|
||||
int nDivs; // the number of divisors in the table
|
||||
int nDivsTotal; // the number of divisors in the table
|
||||
Fxu_HeapDouble * pHeapDouble; // the heap of divisors by weight
|
||||
// the single cube divisors
|
||||
Fxu_ListSingle lSingles; // the linked list of single cube divisors
|
||||
Fxu_HeapSingle * pHeapSingle; // the heap of variables by the number of literals in the matrix
|
||||
// storage for cube pairs
|
||||
Fxu_Pair *** pppPairs;
|
||||
Fxu_Pair ** ppPairs;
|
||||
// temporary storage for cubes
|
||||
Fxu_Cube * pOrderCubes;
|
||||
Fxu_Cube ** ppTailCubes;
|
||||
// temporary storage for variables
|
||||
Fxu_Var * pOrderVars;
|
||||
Fxu_Var ** ppTailVars;
|
||||
// temporary storage for pairs
|
||||
Fxu_Pair ** pPairsTemp;
|
||||
int nPairsTemp;
|
||||
// int nPairsMax;
|
||||
// statistics
|
||||
int nEntries; // the total number of entries in the sparse matrix
|
||||
int nDivs1; // the single cube divisors taken
|
||||
int nDivs2; // the double cube divisors taken
|
||||
int nDivs3; // the double cube divisors with complement
|
||||
// memory manager
|
||||
Extra_MmFixed_t * pMemMan; // the memory manager for all small sized entries
|
||||
};
|
||||
|
||||
// the cube in the sparse matrix
|
||||
struct FxuCube // 9 words
|
||||
{
|
||||
int iCube; // the number of this cube in the cover
|
||||
Fxu_Cube * pFirst; // the pointer to the first cube of this cover
|
||||
Fxu_Var * pVar; // the variable representing the output of the cover
|
||||
Fxu_ListLit lLits; // the row in the table
|
||||
Fxu_Cube * pPrev; // the previous cube
|
||||
Fxu_Cube * pNext; // the next cube
|
||||
Fxu_Cube * pOrder; // the specialized linked list of cubes
|
||||
};
|
||||
|
||||
// the variable in the sparse matrix
|
||||
struct FxuVar // 10 words
|
||||
{
|
||||
int iVar; // the number of this variable
|
||||
int nCubes; // the number of cubes assoc with this var
|
||||
Fxu_Cube * pFirst; // the first cube assoc with this var
|
||||
Fxu_Pair *** ppPairs; // the pairs of cubes assoc with this var
|
||||
Fxu_ListLit lLits; // the column in the table
|
||||
Fxu_Var * pPrev; // the previous variable
|
||||
Fxu_Var * pNext; // the next variable
|
||||
Fxu_Var * pOrder; // the specialized linked list of variables
|
||||
};
|
||||
|
||||
// the literal entry in the sparse matrix
|
||||
struct FxuLit // 8 words
|
||||
{
|
||||
int iVar; // the number of this variable
|
||||
int iCube; // the number of this cube
|
||||
Fxu_Cube * pCube; // the cube of this literal
|
||||
Fxu_Var * pVar; // the variable of this literal
|
||||
Fxu_Lit * pHPrev; // prev lit in the cube
|
||||
Fxu_Lit * pHNext; // next lit in the cube
|
||||
Fxu_Lit * pVPrev; // prev lit of the var
|
||||
Fxu_Lit * pVNext; // next lit of the var
|
||||
};
|
||||
|
||||
// the cube pair
|
||||
struct FxuPair // 10 words
|
||||
{
|
||||
int nLits1; // the number of literals in the two cubes
|
||||
int nLits2; // the number of literals in the two cubes
|
||||
int nBase; // the number of literals in the base
|
||||
Fxu_Double * pDiv; // the divisor of this pair
|
||||
Fxu_Cube * pCube1; // the first cube of the pair
|
||||
Fxu_Cube * pCube2; // the second cube of the pair
|
||||
int iCube1; // the first cube of the pair
|
||||
int iCube2; // the second cube of the pair
|
||||
Fxu_Pair * pDPrev; // the previous pair in the divisor
|
||||
Fxu_Pair * pDNext; // the next pair in the divisor
|
||||
};
|
||||
|
||||
// the double cube divisor
|
||||
struct FxuDouble // 10 words
|
||||
{
|
||||
int Num; // the unique number of this divisor
|
||||
int HNum; // the heap number of this divisor
|
||||
int Weight; // the weight of this divisor
|
||||
unsigned Key; // the hash key of this divisor
|
||||
Fxu_ListPair lPairs; // the pairs of cubes, which produce this divisor
|
||||
Fxu_Double * pPrev; // the previous divisor in the table
|
||||
Fxu_Double * pNext; // the next divisor in the table
|
||||
Fxu_Double * pOrder; // the specialized linked list of divisors
|
||||
};
|
||||
|
||||
// the single cube divisor
|
||||
struct FxuSingle // 7 words
|
||||
{
|
||||
int Num; // the unique number of this divisor
|
||||
int HNum; // the heap number of this divisor
|
||||
int Weight; // the weight of this divisor
|
||||
Fxu_Var * pVar1; // the first variable of the single-cube divisor
|
||||
Fxu_Var * pVar2; // the second variable of the single-cube divisor
|
||||
Fxu_Single * pPrev; // the previous divisor in the list
|
||||
Fxu_Single * pNext; // the next divisor in the list
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// minimum/maximum
|
||||
#define Fxu_Min( a, b ) ( ((a)<(b))? (a):(b) )
|
||||
#define Fxu_Max( a, b ) ( ((a)>(b))? (a):(b) )
|
||||
|
||||
// selection of the minimum/maximum cube in the pair
|
||||
#define Fxu_PairMinCube( pPair ) (((pPair)->iCube1 < (pPair)->iCube2)? (pPair)->pCube1: (pPair)->pCube2)
|
||||
#define Fxu_PairMaxCube( pPair ) (((pPair)->iCube1 > (pPair)->iCube2)? (pPair)->pCube1: (pPair)->pCube2)
|
||||
#define Fxu_PairMinCubeInt( pPair ) (((pPair)->iCube1 < (pPair)->iCube2)? (pPair)->iCube1: (pPair)->iCube2)
|
||||
#define Fxu_PairMaxCubeInt( pPair ) (((pPair)->iCube1 > (pPair)->iCube2)? (pPair)->iCube1: (pPair)->iCube2)
|
||||
|
||||
// iterators
|
||||
|
||||
#define Fxu_MatrixForEachCube( Matrix, Cube )\
|
||||
for ( Cube = (Matrix)->lCubes.pHead;\
|
||||
Cube;\
|
||||
Cube = Cube->pNext )
|
||||
#define Fxu_MatrixForEachCubeSafe( Matrix, Cube, Cube2 )\
|
||||
for ( Cube = (Matrix)->lCubes.pHead, Cube2 = (Cube? Cube->pNext: NULL);\
|
||||
Cube;\
|
||||
Cube = Cube2, Cube2 = (Cube? Cube->pNext: NULL) )
|
||||
|
||||
#define Fxu_MatrixForEachVariable( Matrix, Var )\
|
||||
for ( Var = (Matrix)->lVars.pHead;\
|
||||
Var;\
|
||||
Var = Var->pNext )
|
||||
#define Fxu_MatrixForEachVariableSafe( Matrix, Var, Var2 )\
|
||||
for ( Var = (Matrix)->lVars.pHead, Var2 = (Var? Var->pNext: NULL);\
|
||||
Var;\
|
||||
Var = Var2, Var2 = (Var? Var->pNext: NULL) )
|
||||
|
||||
#define Fxu_MatrixForEachSingle( Matrix, Single )\
|
||||
for ( Single = (Matrix)->lSingles.pHead;\
|
||||
Single;\
|
||||
Single = Single->pNext )
|
||||
#define Fxu_MatrixForEachSingleSafe( Matrix, Single, Single2 )\
|
||||
for ( Single = (Matrix)->lSingles.pHead, Single2 = (Single? Single->pNext: NULL);\
|
||||
Single;\
|
||||
Single = Single2, Single2 = (Single? Single->pNext: NULL) )
|
||||
|
||||
#define Fxu_TableForEachDouble( Matrix, Key, Div )\
|
||||
for ( Div = (Matrix)->pTable[Key].pHead;\
|
||||
Div;\
|
||||
Div = Div->pNext )
|
||||
#define Fxu_TableForEachDoubleSafe( Matrix, Key, Div, Div2 )\
|
||||
for ( Div = (Matrix)->pTable[Key].pHead, Div2 = (Div? Div->pNext: NULL);\
|
||||
Div;\
|
||||
Div = Div2, Div2 = (Div? Div->pNext: NULL) )
|
||||
|
||||
#define Fxu_MatrixForEachDouble( Matrix, Div, Index )\
|
||||
for ( Index = 0; Index < (Matrix)->nTableSize; Index++ )\
|
||||
Fxu_TableForEachDouble( Matrix, Index, Div )
|
||||
#define Fxu_MatrixForEachDoubleSafe( Matrix, Div, Div2, Index )\
|
||||
for ( Index = 0; Index < (Matrix)->nTableSize; Index++ )\
|
||||
Fxu_TableForEachDoubleSafe( Matrix, Index, Div, Div2 )
|
||||
|
||||
|
||||
#define Fxu_CubeForEachLiteral( Cube, Lit )\
|
||||
for ( Lit = (Cube)->lLits.pHead;\
|
||||
Lit;\
|
||||
Lit = Lit->pHNext )
|
||||
#define Fxu_CubeForEachLiteralSafe( Cube, Lit, Lit2 )\
|
||||
for ( Lit = (Cube)->lLits.pHead, Lit2 = (Lit? Lit->pHNext: NULL);\
|
||||
Lit;\
|
||||
Lit = Lit2, Lit2 = (Lit? Lit->pHNext: NULL) )
|
||||
|
||||
#define Fxu_VarForEachLiteral( Var, Lit )\
|
||||
for ( Lit = (Var)->lLits.pHead;\
|
||||
Lit;\
|
||||
Lit = Lit->pVNext )
|
||||
|
||||
#define Fxu_CubeForEachDivisor( Cube, Div )\
|
||||
for ( Div = (Cube)->lDivs.pHead;\
|
||||
Div;\
|
||||
Div = Div->pCNext )
|
||||
|
||||
#define Fxu_DoubleForEachPair( Div, Pair )\
|
||||
for ( Pair = (Div)->lPairs.pHead;\
|
||||
Pair;\
|
||||
Pair = Pair->pDNext )
|
||||
#define Fxu_DoubleForEachPairSafe( Div, Pair, Pair2 )\
|
||||
for ( Pair = (Div)->lPairs.pHead, Pair2 = (Pair? Pair->pDNext: NULL);\
|
||||
Pair;\
|
||||
Pair = Pair2, Pair2 = (Pair? Pair->pDNext: NULL) )
|
||||
|
||||
|
||||
// iterator through the cube pairs belonging to the given cube
|
||||
#define Fxu_CubeForEachPair( pCube, pPair, i )\
|
||||
for ( i = 0;\
|
||||
i < pCube->pVar->nCubes &&\
|
||||
(((unsigned)(pPair = pCube->pVar->ppPairs[pCube->iCube][i])) >= 0);\
|
||||
i++ )\
|
||||
if ( pPair )
|
||||
|
||||
// iterator through all the items in the heap
|
||||
#define Fxu_HeapDoubleForEachItem( Heap, Div )\
|
||||
for ( Heap->i = 1;\
|
||||
Heap->i <= Heap->nItems && (Div = Heap->pTree[Heap->i]);\
|
||||
Heap->i++ )
|
||||
#define Fxu_HeapSingleForEachItem( Heap, Single )\
|
||||
for ( Heap->i = 1;\
|
||||
Heap->i <= Heap->nItems && (Single = Heap->pTree[Heap->i]);\
|
||||
Heap->i++ )
|
||||
|
||||
// starting the rings
|
||||
#define Fxu_MatrixRingCubesStart( Matrix ) (((Matrix)->ppTailCubes = &((Matrix)->pOrderCubes)), ((Matrix)->pOrderCubes = NULL))
|
||||
#define Fxu_MatrixRingVarsStart( Matrix ) (((Matrix)->ppTailVars = &((Matrix)->pOrderVars)), ((Matrix)->pOrderVars = NULL))
|
||||
// stopping the rings
|
||||
#define Fxu_MatrixRingCubesStop( Matrix )
|
||||
#define Fxu_MatrixRingVarsStop( Matrix )
|
||||
// resetting the rings
|
||||
#define Fxu_MatrixRingCubesReset( Matrix ) (((Matrix)->pOrderCubes = NULL), ((Matrix)->ppTailCubes = NULL))
|
||||
#define Fxu_MatrixRingVarsReset( Matrix ) (((Matrix)->pOrderVars = NULL), ((Matrix)->ppTailVars = NULL))
|
||||
// adding to the rings
|
||||
#define Fxu_MatrixRingCubesAdd( Matrix, Cube) ((*((Matrix)->ppTailCubes) = Cube), ((Matrix)->ppTailCubes = &(Cube)->pOrder), ((Cube)->pOrder = (Fxu_Cube *)1))
|
||||
#define Fxu_MatrixRingVarsAdd( Matrix, Var ) ((*((Matrix)->ppTailVars ) = Var ), ((Matrix)->ppTailVars = &(Var)->pOrder ), ((Var)->pOrder = (Fxu_Var *)1))
|
||||
// iterating through the rings
|
||||
#define Fxu_MatrixForEachCubeInRing( Matrix, Cube )\
|
||||
if ( (Matrix)->pOrderCubes )\
|
||||
for ( Cube = (Matrix)->pOrderCubes;\
|
||||
Cube != (Fxu_Cube *)1;\
|
||||
Cube = Cube->pOrder )
|
||||
#define Fxu_MatrixForEachCubeInRingSafe( Matrix, Cube, Cube2 )\
|
||||
if ( (Matrix)->pOrderCubes )\
|
||||
for ( Cube = (Matrix)->pOrderCubes, Cube2 = ((Cube != (Fxu_Cube *)1)? Cube->pOrder: (Fxu_Cube *)1);\
|
||||
Cube != (Fxu_Cube *)1;\
|
||||
Cube = Cube2, Cube2 = ((Cube != (Fxu_Cube *)1)? Cube->pOrder: (Fxu_Cube *)1) )
|
||||
#define Fxu_MatrixForEachVarInRing( Matrix, Var )\
|
||||
if ( (Matrix)->pOrderVars )\
|
||||
for ( Var = (Matrix)->pOrderVars;\
|
||||
Var != (Fxu_Var *)1;\
|
||||
Var = Var->pOrder )
|
||||
#define Fxu_MatrixForEachVarInRingSafe( Matrix, Var, Var2 )\
|
||||
if ( (Matrix)->pOrderVars )\
|
||||
for ( Var = (Matrix)->pOrderVars, Var2 = ((Var != (Fxu_Var *)1)? Var->pOrder: (Fxu_Var *)1);\
|
||||
Var != (Fxu_Var *)1;\
|
||||
Var = Var2, Var2 = ((Var != (Fxu_Var *)1)? Var->pOrder: (Fxu_Var *)1) )
|
||||
// the procedures are related to the above macros
|
||||
extern void Fxu_MatrixRingCubesUnmark( Fxu_Matrix * p );
|
||||
extern void Fxu_MatrixRingVarsUnmark( Fxu_Matrix * p );
|
||||
|
||||
|
||||
// macros working with memory
|
||||
// MEM_ALLOC: allocate the given number (Size) of items of type (Type)
|
||||
// MEM_FREE: deallocate the pointer (Pointer) to the given number (Size) of items of type (Type)
|
||||
#ifdef USE_SYSTEM_MEMORY_MANAGEMENT
|
||||
#define MEM_ALLOC_FXU( Manager, Type, Size ) ((Type *)malloc( (Size) * sizeof(Type) ))
|
||||
#define MEM_FREE_FXU( Manager, Type, Size, Pointer ) if ( Pointer ) { free(Pointer); Pointer = NULL; }
|
||||
#else
|
||||
#define MEM_ALLOC_FXU( Manager, Type, Size )\
|
||||
((Type *)Fxu_MemFetch( Manager, (Size) * sizeof(Type) ))
|
||||
#define MEM_FREE_FXU( Manager, Type, Size, Pointer )\
|
||||
if ( Pointer ) { Fxu_MemRecycle( Manager, (char *)(Pointer), (Size) * sizeof(Type) ); Pointer = NULL; }
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*===== fxu.c ====================================================*/
|
||||
extern char * Fxu_MemFetch( Fxu_Matrix * p, int nBytes );
|
||||
extern void Fxu_MemRecycle( Fxu_Matrix * p, char * pItem, int nBytes );
|
||||
/*===== fxuCreate.c ====================================================*/
|
||||
/*===== fxuReduce.c ====================================================*/
|
||||
/*===== fxuPrint.c ====================================================*/
|
||||
extern void Fxu_MatrixPrint( FILE * pFile, Fxu_Matrix * p );
|
||||
extern void Fxu_MatrixPrintDivisorProfile( FILE * pFile, Fxu_Matrix * p );
|
||||
/*===== fxuSelect.c ====================================================*/
|
||||
extern int Fxu_Select( Fxu_Matrix * p, Fxu_Single ** ppSingle, Fxu_Double ** ppDouble );
|
||||
extern int Fxu_SelectSCD( Fxu_Matrix * p, int Weight, Fxu_Var ** ppVar1, Fxu_Var ** ppVar2 );
|
||||
/*===== fxuUpdate.c ====================================================*/
|
||||
extern void Fxu_Update( Fxu_Matrix * p, Fxu_Single * pSingle, Fxu_Double * pDouble );
|
||||
extern void Fxu_UpdateDouble( Fxu_Matrix * p );
|
||||
extern void Fxu_UpdateSingle( Fxu_Matrix * p );
|
||||
/*===== fxuPair.c ====================================================*/
|
||||
extern void Fxu_PairCanonicize( Fxu_Cube ** ppCube1, Fxu_Cube ** ppCube2 );
|
||||
extern unsigned Fxu_PairHashKeyArray( Fxu_Matrix * p, int piVarsC1[], int piVarsC2[], int nVarsC1, int nVarsC2 );
|
||||
extern unsigned Fxu_PairHashKey( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2, int * pnBase, int * pnLits1, int * pnLits2 );
|
||||
extern unsigned Fxu_PairHashKeyMv( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2, int * pnBase, int * pnLits1, int * pnLits2 );
|
||||
extern int Fxu_PairCompare( Fxu_Pair * pPair1, Fxu_Pair * pPair2 );
|
||||
extern void Fxu_PairAllocStorage( Fxu_Var * pVar, int nCubes );
|
||||
extern void Fxu_PairFreeStorage( Fxu_Var * pVar );
|
||||
extern void Fxu_PairClearStorage( Fxu_Cube * pCube );
|
||||
extern Fxu_Pair * Fxu_PairAlloc( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2 );
|
||||
extern void Fxu_PairAdd( Fxu_Pair * pPair );
|
||||
/*===== fxuSingle.c ====================================================*/
|
||||
extern void Fxu_MatrixComputeSingles( Fxu_Matrix * p );
|
||||
extern void Fxu_MatrixComputeSinglesOne( Fxu_Matrix * p, Fxu_Var * pVar );
|
||||
extern int Fxu_SingleCountCoincidence( Fxu_Matrix * p, Fxu_Var * pVar1, Fxu_Var * pVar2 );
|
||||
/*===== fxuMatrix.c ====================================================*/
|
||||
// matrix
|
||||
extern Fxu_Matrix * Fxu_MatrixAllocate();
|
||||
extern void Fxu_MatrixDelete( Fxu_Matrix * p );
|
||||
// double-cube divisor
|
||||
extern void Fxu_MatrixAddDivisor( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2 );
|
||||
extern void Fxu_MatrixDelDivisor( Fxu_Matrix * p, Fxu_Double * pDiv );
|
||||
// single-cube divisor
|
||||
extern void Fxu_MatrixAddSingle( Fxu_Matrix * p, Fxu_Var * pVar1, Fxu_Var * pVar2, int Weight );
|
||||
// variable
|
||||
extern Fxu_Var * Fxu_MatrixAddVar( Fxu_Matrix * p );
|
||||
// cube
|
||||
extern Fxu_Cube * Fxu_MatrixAddCube( Fxu_Matrix * p, Fxu_Var * pVar, int iCube );
|
||||
// literal
|
||||
extern void Fxu_MatrixAddLiteral( Fxu_Matrix * p, Fxu_Cube * pCube, Fxu_Var * pVar );
|
||||
extern void Fxu_MatrixDelLiteral( Fxu_Matrix * p, Fxu_Lit * pLit );
|
||||
/*===== fxuList.c ====================================================*/
|
||||
// matrix -> variable
|
||||
extern void Fxu_ListMatrixAddVariable( Fxu_Matrix * p, Fxu_Var * pVar );
|
||||
extern void Fxu_ListMatrixDelVariable( Fxu_Matrix * p, Fxu_Var * pVar );
|
||||
// matrix -> cube
|
||||
extern void Fxu_ListMatrixAddCube( Fxu_Matrix * p, Fxu_Cube * pCube );
|
||||
extern void Fxu_ListMatrixDelCube( Fxu_Matrix * p, Fxu_Cube * pCube );
|
||||
// matrix -> single
|
||||
extern void Fxu_ListMatrixAddSingle( Fxu_Matrix * p, Fxu_Single * pSingle );
|
||||
extern void Fxu_ListMatrixDelSingle( Fxu_Matrix * p, Fxu_Single * pSingle );
|
||||
// table -> divisor
|
||||
extern void Fxu_ListTableAddDivisor( Fxu_Matrix * p, Fxu_Double * pDiv );
|
||||
extern void Fxu_ListTableDelDivisor( Fxu_Matrix * p, Fxu_Double * pDiv );
|
||||
// cube -> literal
|
||||
extern void Fxu_ListCubeAddLiteral( Fxu_Cube * pCube, Fxu_Lit * pLit );
|
||||
extern void Fxu_ListCubeDelLiteral( Fxu_Cube * pCube, Fxu_Lit * pLit );
|
||||
// var -> literal
|
||||
extern void Fxu_ListVarAddLiteral( Fxu_Var * pVar, Fxu_Lit * pLit );
|
||||
extern void Fxu_ListVarDelLiteral( Fxu_Var * pVar, Fxu_Lit * pLit );
|
||||
// divisor -> pair
|
||||
extern void Fxu_ListDoubleAddPairLast( Fxu_Double * pDiv, Fxu_Pair * pLink );
|
||||
extern void Fxu_ListDoubleAddPairFirst( Fxu_Double * pDiv, Fxu_Pair * pLink );
|
||||
extern void Fxu_ListDoubleAddPairMiddle( Fxu_Double * pDiv, Fxu_Pair * pSpot, Fxu_Pair * pLink );
|
||||
extern void Fxu_ListDoubleDelPair( Fxu_Double * pDiv, Fxu_Pair * pPair );
|
||||
/*===== fxuHeapDouble.c ====================================================*/
|
||||
extern Fxu_HeapDouble * Fxu_HeapDoubleStart();
|
||||
extern void Fxu_HeapDoubleStop( Fxu_HeapDouble * p );
|
||||
extern void Fxu_HeapDoublePrint( FILE * pFile, Fxu_HeapDouble * p );
|
||||
extern void Fxu_HeapDoubleCheck( Fxu_HeapDouble * p );
|
||||
extern void Fxu_HeapDoubleCheckOne( Fxu_HeapDouble * p, Fxu_Double * pDiv );
|
||||
|
||||
extern void Fxu_HeapDoubleInsert( Fxu_HeapDouble * p, Fxu_Double * pDiv );
|
||||
extern void Fxu_HeapDoubleUpdate( Fxu_HeapDouble * p, Fxu_Double * pDiv );
|
||||
extern void Fxu_HeapDoubleDelete( Fxu_HeapDouble * p, Fxu_Double * pDiv );
|
||||
extern int Fxu_HeapDoubleReadMaxWeight( Fxu_HeapDouble * p );
|
||||
extern Fxu_Double * Fxu_HeapDoubleReadMax( Fxu_HeapDouble * p );
|
||||
extern Fxu_Double * Fxu_HeapDoubleGetMax( Fxu_HeapDouble * p );
|
||||
/*===== fxuHeapSingle.c ====================================================*/
|
||||
extern Fxu_HeapSingle * Fxu_HeapSingleStart();
|
||||
extern void Fxu_HeapSingleStop( Fxu_HeapSingle * p );
|
||||
extern void Fxu_HeapSinglePrint( FILE * pFile, Fxu_HeapSingle * p );
|
||||
extern void Fxu_HeapSingleCheck( Fxu_HeapSingle * p );
|
||||
extern void Fxu_HeapSingleCheckOne( Fxu_HeapSingle * p, Fxu_Single * pSingle );
|
||||
|
||||
extern void Fxu_HeapSingleInsert( Fxu_HeapSingle * p, Fxu_Single * pSingle );
|
||||
extern void Fxu_HeapSingleUpdate( Fxu_HeapSingle * p, Fxu_Single * pSingle );
|
||||
extern void Fxu_HeapSingleDelete( Fxu_HeapSingle * p, Fxu_Single * pSingle );
|
||||
extern int Fxu_HeapSingleReadMaxWeight( Fxu_HeapSingle * p );
|
||||
extern Fxu_Single * Fxu_HeapSingleReadMax( Fxu_HeapSingle * p );
|
||||
extern Fxu_Single * Fxu_HeapSingleGetMax( Fxu_HeapSingle * p );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,522 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [fxuList.c]
|
||||
|
||||
PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
|
||||
|
||||
Synopsis [Operations on lists.]
|
||||
|
||||
Author [MVSIS Group]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - February 1, 2003.]
|
||||
|
||||
Revision [$Id: fxuList.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "fxuInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// matrix -> var
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_ListMatrixAddVariable( Fxu_Matrix * p, Fxu_Var * pLink )
|
||||
{
|
||||
Fxu_ListVar * pList = &p->lVars;
|
||||
if ( pList->pHead == NULL )
|
||||
{
|
||||
pList->pHead = pLink;
|
||||
pList->pTail = pLink;
|
||||
pLink->pPrev = NULL;
|
||||
pLink->pNext = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
pLink->pNext = NULL;
|
||||
pList->pTail->pNext = pLink;
|
||||
pLink->pPrev = pList->pTail;
|
||||
pList->pTail = pLink;
|
||||
}
|
||||
pList->nItems++;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_ListMatrixDelVariable( Fxu_Matrix * p, Fxu_Var * pLink )
|
||||
{
|
||||
Fxu_ListVar * pList = &p->lVars;
|
||||
if ( pList->pHead == pLink )
|
||||
pList->pHead = pLink->pNext;
|
||||
if ( pList->pTail == pLink )
|
||||
pList->pTail = pLink->pPrev;
|
||||
if ( pLink->pPrev )
|
||||
pLink->pPrev->pNext = pLink->pNext;
|
||||
if ( pLink->pNext )
|
||||
pLink->pNext->pPrev = pLink->pPrev;
|
||||
pList->nItems--;
|
||||
}
|
||||
|
||||
|
||||
// matrix -> cube
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_ListMatrixAddCube( Fxu_Matrix * p, Fxu_Cube * pLink )
|
||||
{
|
||||
Fxu_ListCube * pList = &p->lCubes;
|
||||
if ( pList->pHead == NULL )
|
||||
{
|
||||
pList->pHead = pLink;
|
||||
pList->pTail = pLink;
|
||||
pLink->pPrev = NULL;
|
||||
pLink->pNext = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
pLink->pNext = NULL;
|
||||
pList->pTail->pNext = pLink;
|
||||
pLink->pPrev = pList->pTail;
|
||||
pList->pTail = pLink;
|
||||
}
|
||||
pList->nItems++;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_ListMatrixDelCube( Fxu_Matrix * p, Fxu_Cube * pLink )
|
||||
{
|
||||
Fxu_ListCube * pList = &p->lCubes;
|
||||
if ( pList->pHead == pLink )
|
||||
pList->pHead = pLink->pNext;
|
||||
if ( pList->pTail == pLink )
|
||||
pList->pTail = pLink->pPrev;
|
||||
if ( pLink->pPrev )
|
||||
pLink->pPrev->pNext = pLink->pNext;
|
||||
if ( pLink->pNext )
|
||||
pLink->pNext->pPrev = pLink->pPrev;
|
||||
pList->nItems--;
|
||||
}
|
||||
|
||||
|
||||
// matrix -> single
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_ListMatrixAddSingle( Fxu_Matrix * p, Fxu_Single * pLink )
|
||||
{
|
||||
Fxu_ListSingle * pList = &p->lSingles;
|
||||
if ( pList->pHead == NULL )
|
||||
{
|
||||
pList->pHead = pLink;
|
||||
pList->pTail = pLink;
|
||||
pLink->pPrev = NULL;
|
||||
pLink->pNext = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
pLink->pNext = NULL;
|
||||
pList->pTail->pNext = pLink;
|
||||
pLink->pPrev = pList->pTail;
|
||||
pList->pTail = pLink;
|
||||
}
|
||||
pList->nItems++;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_ListMatrixDelSingle( Fxu_Matrix * p, Fxu_Single * pLink )
|
||||
{
|
||||
Fxu_ListSingle * pList = &p->lSingles;
|
||||
if ( pList->pHead == pLink )
|
||||
pList->pHead = pLink->pNext;
|
||||
if ( pList->pTail == pLink )
|
||||
pList->pTail = pLink->pPrev;
|
||||
if ( pLink->pPrev )
|
||||
pLink->pPrev->pNext = pLink->pNext;
|
||||
if ( pLink->pNext )
|
||||
pLink->pNext->pPrev = pLink->pPrev;
|
||||
pList->nItems--;
|
||||
}
|
||||
|
||||
|
||||
// table -> divisor
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_ListTableAddDivisor( Fxu_Matrix * p, Fxu_Double * pLink )
|
||||
{
|
||||
Fxu_ListDouble * pList = &(p->pTable[pLink->Key]);
|
||||
if ( pList->pHead == NULL )
|
||||
{
|
||||
pList->pHead = pLink;
|
||||
pList->pTail = pLink;
|
||||
pLink->pPrev = NULL;
|
||||
pLink->pNext = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
pLink->pNext = NULL;
|
||||
pList->pTail->pNext = pLink;
|
||||
pLink->pPrev = pList->pTail;
|
||||
pList->pTail = pLink;
|
||||
}
|
||||
pList->nItems++;
|
||||
p->nDivs++;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_ListTableDelDivisor( Fxu_Matrix * p, Fxu_Double * pLink )
|
||||
{
|
||||
Fxu_ListDouble * pList = &(p->pTable[pLink->Key]);
|
||||
if ( pList->pHead == pLink )
|
||||
pList->pHead = pLink->pNext;
|
||||
if ( pList->pTail == pLink )
|
||||
pList->pTail = pLink->pPrev;
|
||||
if ( pLink->pPrev )
|
||||
pLink->pPrev->pNext = pLink->pNext;
|
||||
if ( pLink->pNext )
|
||||
pLink->pNext->pPrev = pLink->pPrev;
|
||||
pList->nItems--;
|
||||
p->nDivs--;
|
||||
}
|
||||
|
||||
|
||||
// cube -> literal
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_ListCubeAddLiteral( Fxu_Cube * pCube, Fxu_Lit * pLink )
|
||||
{
|
||||
Fxu_ListLit * pList = &(pCube->lLits);
|
||||
if ( pList->pHead == NULL )
|
||||
{
|
||||
pList->pHead = pLink;
|
||||
pList->pTail = pLink;
|
||||
pLink->pHPrev = NULL;
|
||||
pLink->pHNext = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
pLink->pHNext = NULL;
|
||||
pList->pTail->pHNext = pLink;
|
||||
pLink->pHPrev = pList->pTail;
|
||||
pList->pTail = pLink;
|
||||
}
|
||||
pList->nItems++;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_ListCubeDelLiteral( Fxu_Cube * pCube, Fxu_Lit * pLink )
|
||||
{
|
||||
Fxu_ListLit * pList = &(pCube->lLits);
|
||||
if ( pList->pHead == pLink )
|
||||
pList->pHead = pLink->pHNext;
|
||||
if ( pList->pTail == pLink )
|
||||
pList->pTail = pLink->pHPrev;
|
||||
if ( pLink->pHPrev )
|
||||
pLink->pHPrev->pHNext = pLink->pHNext;
|
||||
if ( pLink->pHNext )
|
||||
pLink->pHNext->pHPrev = pLink->pHPrev;
|
||||
pList->nItems--;
|
||||
}
|
||||
|
||||
|
||||
// var -> literal
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_ListVarAddLiteral( Fxu_Var * pVar, Fxu_Lit * pLink )
|
||||
{
|
||||
Fxu_ListLit * pList = &(pVar->lLits);
|
||||
if ( pList->pHead == NULL )
|
||||
{
|
||||
pList->pHead = pLink;
|
||||
pList->pTail = pLink;
|
||||
pLink->pVPrev = NULL;
|
||||
pLink->pVNext = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
pLink->pVNext = NULL;
|
||||
pList->pTail->pVNext = pLink;
|
||||
pLink->pVPrev = pList->pTail;
|
||||
pList->pTail = pLink;
|
||||
}
|
||||
pList->nItems++;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_ListVarDelLiteral( Fxu_Var * pVar, Fxu_Lit * pLink )
|
||||
{
|
||||
Fxu_ListLit * pList = &(pVar->lLits);
|
||||
if ( pList->pHead == pLink )
|
||||
pList->pHead = pLink->pVNext;
|
||||
if ( pList->pTail == pLink )
|
||||
pList->pTail = pLink->pVPrev;
|
||||
if ( pLink->pVPrev )
|
||||
pLink->pVPrev->pVNext = pLink->pVNext;
|
||||
if ( pLink->pVNext )
|
||||
pLink->pVNext->pVPrev = pLink->pVPrev;
|
||||
pList->nItems--;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// divisor -> pair
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_ListDoubleAddPairLast( Fxu_Double * pDiv, Fxu_Pair * pLink )
|
||||
{
|
||||
Fxu_ListPair * pList = &pDiv->lPairs;
|
||||
if ( pList->pHead == NULL )
|
||||
{
|
||||
pList->pHead = pLink;
|
||||
pList->pTail = pLink;
|
||||
pLink->pDPrev = NULL;
|
||||
pLink->pDNext = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
pLink->pDNext = NULL;
|
||||
pList->pTail->pDNext = pLink;
|
||||
pLink->pDPrev = pList->pTail;
|
||||
pList->pTail = pLink;
|
||||
}
|
||||
pList->nItems++;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_ListDoubleAddPairFirst( Fxu_Double * pDiv, Fxu_Pair * pLink )
|
||||
{
|
||||
Fxu_ListPair * pList = &pDiv->lPairs;
|
||||
if ( pList->pHead == NULL )
|
||||
{
|
||||
pList->pHead = pLink;
|
||||
pList->pTail = pLink;
|
||||
pLink->pDPrev = NULL;
|
||||
pLink->pDNext = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
pLink->pDPrev = NULL;
|
||||
pList->pHead->pDPrev = pLink;
|
||||
pLink->pDNext = pList->pHead;
|
||||
pList->pHead = pLink;
|
||||
}
|
||||
pList->nItems++;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds the entry in the middle of the list after the spot.]
|
||||
|
||||
Description [Assumes that spot points to the link, after which the given
|
||||
link should be added. Spot cannot be NULL or the tail of the list.
|
||||
Therefore, the head and the tail of the list are not changed.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_ListDoubleAddPairMiddle( Fxu_Double * pDiv, Fxu_Pair * pSpot, Fxu_Pair * pLink )
|
||||
{
|
||||
Fxu_ListPair * pList = &pDiv->lPairs;
|
||||
assert( pSpot );
|
||||
assert( pSpot != pList->pTail );
|
||||
pLink->pDPrev = pSpot;
|
||||
pLink->pDNext = pSpot->pDNext;
|
||||
pLink->pDPrev->pDNext = pLink;
|
||||
pLink->pDNext->pDPrev = pLink;
|
||||
pList->nItems++;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_ListDoubleDelPair( Fxu_Double * pDiv, Fxu_Pair * pLink )
|
||||
{
|
||||
Fxu_ListPair * pList = &pDiv->lPairs;
|
||||
if ( pList->pHead == pLink )
|
||||
pList->pHead = pLink->pDNext;
|
||||
if ( pList->pTail == pLink )
|
||||
pList->pTail = pLink->pDPrev;
|
||||
if ( pLink->pDPrev )
|
||||
pLink->pDPrev->pDNext = pLink->pDNext;
|
||||
if ( pLink->pDNext )
|
||||
pLink->pDNext->pDPrev = pLink->pDPrev;
|
||||
pList->nItems--;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_ListDoubleAddPairPlace( Fxu_Double * pDiv, Fxu_Pair * pPair, Fxu_Pair * pPairSpot )
|
||||
{
|
||||
printf( "Fxu_ListDoubleAddPairPlace() is called!\n" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,382 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [fxuMatrix.c]
|
||||
|
||||
PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
|
||||
|
||||
Synopsis [Procedures to manipulate the sparse matrix.]
|
||||
|
||||
Author [MVSIS Group]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - February 1, 2003.]
|
||||
|
||||
Revision [$Id: fxuMatrix.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "fxuInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern unsigned int Cudd_Prime( unsigned int p );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Fxu_Matrix * Fxu_MatrixAllocate()
|
||||
{
|
||||
Fxu_Matrix * p;
|
||||
p = ALLOC( Fxu_Matrix, 1 );
|
||||
memset( p, 0, sizeof(Fxu_Matrix) );
|
||||
p->nTableSize = Cudd_Prime(10000);
|
||||
p->pTable = ALLOC( Fxu_ListDouble, p->nTableSize );
|
||||
memset( p->pTable, 0, sizeof(Fxu_ListDouble) * p->nTableSize );
|
||||
#ifndef USE_SYSTEM_MEMORY_MANAGEMENT
|
||||
{
|
||||
// get the largest size in bytes for the following structures:
|
||||
// Fxu_Cube, Fxu_Var, Fxu_Lit, Fxu_Pair, Fxu_Double, Fxu_Single
|
||||
// (currently, Fxu_Var, Fxu_Pair, Fxu_Double take 10 machine words)
|
||||
int nSizeMax, nSizeCur;
|
||||
nSizeMax = -1;
|
||||
nSizeCur = sizeof(Fxu_Cube);
|
||||
if ( nSizeMax < nSizeCur )
|
||||
nSizeMax = nSizeCur;
|
||||
nSizeCur = sizeof(Fxu_Var);
|
||||
if ( nSizeMax < nSizeCur )
|
||||
nSizeMax = nSizeCur;
|
||||
nSizeCur = sizeof(Fxu_Lit);
|
||||
if ( nSizeMax < nSizeCur )
|
||||
nSizeMax = nSizeCur;
|
||||
nSizeCur = sizeof(Fxu_Pair);
|
||||
if ( nSizeMax < nSizeCur )
|
||||
nSizeMax = nSizeCur;
|
||||
nSizeCur = sizeof(Fxu_Double);
|
||||
if ( nSizeMax < nSizeCur )
|
||||
nSizeMax = nSizeCur;
|
||||
nSizeCur = sizeof(Fxu_Single);
|
||||
if ( nSizeMax < nSizeCur )
|
||||
nSizeMax = nSizeCur;
|
||||
p->pMemMan = Extra_MmFixedStart( nSizeMax );
|
||||
}
|
||||
#endif
|
||||
p->pHeapDouble = Fxu_HeapDoubleStart();
|
||||
p->pHeapSingle = Fxu_HeapSingleStart();
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_MatrixDelete( Fxu_Matrix * p )
|
||||
{
|
||||
Fxu_HeapDoubleCheck( p->pHeapDouble );
|
||||
Fxu_HeapDoubleStop( p->pHeapDouble );
|
||||
Fxu_HeapSingleStop( p->pHeapSingle );
|
||||
|
||||
// delete other things
|
||||
#ifdef USE_SYSTEM_MEMORY_MANAGEMENT
|
||||
// this code is not needed when the custom memory manager is used
|
||||
{
|
||||
Fxu_Cube * pCube, * pCube2;
|
||||
Fxu_Var * pVar, * pVar2;
|
||||
Fxu_Lit * pLit, * pLit2;
|
||||
Fxu_Double * pDiv, * pDiv2;
|
||||
Fxu_Single * pSingle, * pSingle2;
|
||||
Fxu_Pair * pPair, * pPair2;
|
||||
int i;
|
||||
// delete the divisors
|
||||
Fxu_MatrixForEachDoubleSafe( p, pDiv, pDiv2, i )
|
||||
{
|
||||
Fxu_DoubleForEachPairSafe( pDiv, pPair, pPair2 )
|
||||
MEM_FREE_FXU( p, Fxu_Pair, 1, pPair );
|
||||
MEM_FREE_FXU( p, Fxu_Double, 1, pDiv );
|
||||
}
|
||||
Fxu_MatrixForEachSingleSafe( p, pSingle, pSingle2 )
|
||||
MEM_FREE_FXU( p, Fxu_Single, 1, pSingle );
|
||||
// delete the entries
|
||||
Fxu_MatrixForEachCube( p, pCube )
|
||||
Fxu_CubeForEachLiteralSafe( pCube, pLit, pLit2 )
|
||||
MEM_FREE_FXU( p, Fxu_Lit, 1, pLit );
|
||||
// delete the cubes
|
||||
Fxu_MatrixForEachCubeSafe( p, pCube, pCube2 )
|
||||
MEM_FREE_FXU( p, Fxu_Cube, 1, pCube );
|
||||
// delete the vars
|
||||
Fxu_MatrixForEachVariableSafe( p, pVar, pVar2 )
|
||||
MEM_FREE_FXU( p, Fxu_Var, 1, pVar );
|
||||
}
|
||||
#else
|
||||
Extra_MmFixedStop( p->pMemMan, 0 );
|
||||
#endif
|
||||
|
||||
FREE( p->pppPairs );
|
||||
FREE( p->ppPairs );
|
||||
FREE( p->pPairsTemp );
|
||||
FREE( p->pTable );
|
||||
FREE( p->ppVars );
|
||||
FREE( p );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds a variable to the matrix.]
|
||||
|
||||
Description [This procedure always adds variables at the end of the matrix.
|
||||
It assigns the var's node and number. It adds the var to the linked list of
|
||||
all variables and to the table of all nodes.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Fxu_Var * Fxu_MatrixAddVar( Fxu_Matrix * p )
|
||||
{
|
||||
Fxu_Var * pVar;
|
||||
pVar = MEM_ALLOC_FXU( p, Fxu_Var, 1 );
|
||||
memset( pVar, 0, sizeof(Fxu_Var) );
|
||||
pVar->iVar = p->lVars.nItems;
|
||||
p->ppVars[pVar->iVar] = pVar;
|
||||
Fxu_ListMatrixAddVariable( p, pVar );
|
||||
return pVar;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds a literal to the matrix.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Fxu_Cube * Fxu_MatrixAddCube( Fxu_Matrix * p, Fxu_Var * pVar, int iCube )
|
||||
{
|
||||
Fxu_Cube * pCube;
|
||||
pCube = MEM_ALLOC_FXU( p, Fxu_Cube, 1 );
|
||||
memset( pCube, 0, sizeof(Fxu_Cube) );
|
||||
pCube->pVar = pVar;
|
||||
pCube->iCube = iCube;
|
||||
Fxu_ListMatrixAddCube( p, pCube );
|
||||
return pCube;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds a literal to the matrix.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_MatrixAddLiteral( Fxu_Matrix * p, Fxu_Cube * pCube, Fxu_Var * pVar )
|
||||
{
|
||||
Fxu_Lit * pLit;
|
||||
pLit = MEM_ALLOC_FXU( p, Fxu_Lit, 1 );
|
||||
memset( pLit, 0, sizeof(Fxu_Lit) );
|
||||
// insert the literal into two linked lists
|
||||
Fxu_ListCubeAddLiteral( pCube, pLit );
|
||||
Fxu_ListVarAddLiteral( pVar, pLit );
|
||||
// set the back pointers
|
||||
pLit->pCube = pCube;
|
||||
pLit->pVar = pVar;
|
||||
pLit->iCube = pCube->iCube;
|
||||
pLit->iVar = pVar->iVar;
|
||||
// increment the literal counter
|
||||
p->nEntries++;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Deletes the divisor from the matrix.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_MatrixDelDivisor( Fxu_Matrix * p, Fxu_Double * pDiv )
|
||||
{
|
||||
// delete divisor from the table
|
||||
Fxu_ListTableDelDivisor( p, pDiv );
|
||||
// recycle the divisor
|
||||
MEM_FREE_FXU( p, Fxu_Double, 1, pDiv );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Deletes the literal fromthe matrix.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_MatrixDelLiteral( Fxu_Matrix * p, Fxu_Lit * pLit )
|
||||
{
|
||||
// delete the literal
|
||||
Fxu_ListCubeDelLiteral( pLit->pCube, pLit );
|
||||
Fxu_ListVarDelLiteral( pLit->pVar, pLit );
|
||||
MEM_FREE_FXU( p, Fxu_Lit, 1, pLit );
|
||||
// increment the literal counter
|
||||
p->nEntries--;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates and adds a single cube divisor.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_MatrixAddSingle( Fxu_Matrix * p, Fxu_Var * pVar1, Fxu_Var * pVar2, int Weight )
|
||||
{
|
||||
Fxu_Single * pSingle;
|
||||
assert( pVar1->iVar < pVar2->iVar );
|
||||
pSingle = MEM_ALLOC_FXU( p, Fxu_Single, 1 );
|
||||
memset( pSingle, 0, sizeof(Fxu_Single) );
|
||||
pSingle->Num = p->lSingles.nItems;
|
||||
pSingle->Weight = Weight;
|
||||
pSingle->HNum = 0;
|
||||
pSingle->pVar1 = pVar1;
|
||||
pSingle->pVar2 = pVar2;
|
||||
Fxu_ListMatrixAddSingle( p, pSingle );
|
||||
// add to the heap
|
||||
Fxu_HeapSingleInsert( p->pHeapSingle, pSingle );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_MatrixAddDivisor( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2 )
|
||||
{
|
||||
Fxu_Pair * pPair;
|
||||
Fxu_Double * pDiv;
|
||||
int nBase, nLits1, nLits2;
|
||||
int fFound;
|
||||
unsigned Key;
|
||||
|
||||
// canonicize the pair
|
||||
Fxu_PairCanonicize( &pCube1, &pCube2 );
|
||||
|
||||
/*
|
||||
// compute the hash key
|
||||
if ( p->fMvNetwork )
|
||||
// if ( 0 )
|
||||
{ // in case of MV network, if all the values in the cube-free divisor
|
||||
// belong to the same MV variable, this cube pair is not a divisor
|
||||
Key = Fxu_PairHashKeyMv( p, pCube1, pCube2, &nBase, &nLits1, &nLits2 );
|
||||
if ( Key == 0 )
|
||||
return;
|
||||
}
|
||||
else
|
||||
*/
|
||||
Key = Fxu_PairHashKey( p, pCube1, pCube2, &nBase, &nLits1, &nLits2 );
|
||||
|
||||
// create the cube pair
|
||||
pPair = Fxu_PairAlloc( p, pCube1, pCube2 );
|
||||
pPair->nBase = nBase;
|
||||
pPair->nLits1 = nLits1;
|
||||
pPair->nLits2 = nLits2;
|
||||
|
||||
// check if the divisor for this pair already exists
|
||||
fFound = 0;
|
||||
Key %= p->nTableSize;
|
||||
Fxu_TableForEachDouble( p, Key, pDiv )
|
||||
if ( Fxu_PairCompare( pPair, pDiv->lPairs.pTail ) ) // they are equal
|
||||
{
|
||||
fFound = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !fFound )
|
||||
{ // create the new divisor
|
||||
pDiv = MEM_ALLOC_FXU( p, Fxu_Double, 1 );
|
||||
memset( pDiv, 0, sizeof(Fxu_Double) );
|
||||
pDiv->Key = Key;
|
||||
// set the number of this divisor
|
||||
pDiv->Num = p->nDivsTotal++; // p->nDivs;
|
||||
// insert the divisor in the table
|
||||
Fxu_ListTableAddDivisor( p, pDiv );
|
||||
// set the initial cost of the divisor
|
||||
pDiv->Weight -= pPair->nLits1 + pPair->nLits2;
|
||||
}
|
||||
|
||||
// link the pair to the cubes
|
||||
Fxu_PairAdd( pPair );
|
||||
// connect the pair and the divisor
|
||||
pPair->pDiv = pDiv;
|
||||
Fxu_ListDoubleAddPairLast( pDiv, pPair );
|
||||
// update the max number of pairs in a divisor
|
||||
// if ( p->nPairsMax < pDiv->lPairs.nItems )
|
||||
// p->nPairsMax = pDiv->lPairs.nItems;
|
||||
// update the divisor's weight
|
||||
pDiv->Weight += pPair->nLits1 + pPair->nLits2 - 1 + pPair->nBase;
|
||||
if ( fFound ) // update the divisor in the heap
|
||||
Fxu_HeapDoubleUpdate( p->pHeapDouble, pDiv );
|
||||
else // add the new divisor to the heap
|
||||
Fxu_HeapDoubleInsert( p->pHeapDouble, pDiv );
|
||||
}
|
||||
|
||||
/*
|
||||
{
|
||||
int piVarsC1[100], piVarsC2[100], nVarsC1, nVarsC2;
|
||||
Fxu_Double * pDivCur;
|
||||
Fxu_MatrixGetDoubleVars( p, pDiv, piVarsC1, piVarsC2, &nVarsC1, &nVarsC2 );
|
||||
pDivCur = Fxu_MatrixFindDouble( p, piVarsC1, piVarsC2, nVarsC1, nVarsC2 );
|
||||
assert( pDivCur == pDiv );
|
||||
}
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,555 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [fxuPair.c]
|
||||
|
||||
PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
|
||||
|
||||
Synopsis [Operations on cube pairs.]
|
||||
|
||||
Author [MVSIS Group]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - February 1, 2003.]
|
||||
|
||||
Revision [$Id: fxuPair.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "fxuInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define MAX_PRIMES 304
|
||||
|
||||
static s_Primes[MAX_PRIMES] =
|
||||
{
|
||||
2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37,
|
||||
41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89,
|
||||
97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151,
|
||||
157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223,
|
||||
227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
|
||||
283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359,
|
||||
367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433,
|
||||
439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503,
|
||||
509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593,
|
||||
599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659,
|
||||
661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743,
|
||||
751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827,
|
||||
829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911,
|
||||
919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997,
|
||||
1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069,
|
||||
1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163,
|
||||
1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249,
|
||||
1259, 1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321,
|
||||
1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439,
|
||||
1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511,
|
||||
1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601,
|
||||
1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693,
|
||||
1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783,
|
||||
1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877,
|
||||
1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987,
|
||||
1993, 1997, 1999, 2003
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find the canonical permutation of two cubes in the pair.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_PairCanonicize( Fxu_Cube ** ppCube1, Fxu_Cube ** ppCube2 )
|
||||
{
|
||||
Fxu_Lit * pLit1, * pLit2;
|
||||
Fxu_Cube * pCubeTemp;
|
||||
|
||||
// walk through the cubes to determine
|
||||
// the one that has higher first variable
|
||||
pLit1 = (*ppCube1)->lLits.pHead;
|
||||
pLit2 = (*ppCube2)->lLits.pHead;
|
||||
while ( 1 )
|
||||
{
|
||||
if ( pLit1->iVar == pLit2->iVar )
|
||||
{
|
||||
pLit1 = pLit1->pHNext;
|
||||
pLit2 = pLit2->pHNext;
|
||||
continue;
|
||||
}
|
||||
assert( pLit1 && pLit2 ); // this is true if the covers are SCC-free
|
||||
if ( pLit1->iVar > pLit2->iVar )
|
||||
{ // swap the cubes
|
||||
pCubeTemp = *ppCube1;
|
||||
*ppCube1 = *ppCube2;
|
||||
*ppCube2 = pCubeTemp;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find the canonical permutation of two cubes in the pair.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_PairCanonicize2( Fxu_Cube ** ppCube1, Fxu_Cube ** ppCube2 )
|
||||
{
|
||||
Fxu_Cube * pCubeTemp;
|
||||
// canonicize the pair by ordering the cubes
|
||||
if ( (*ppCube1)->iCube > (*ppCube2)->iCube )
|
||||
{ // swap the cubes
|
||||
pCubeTemp = *ppCube1;
|
||||
*ppCube1 = *ppCube2;
|
||||
*ppCube2 = pCubeTemp;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
unsigned Fxu_PairHashKeyArray( Fxu_Matrix * p, int piVarsC1[], int piVarsC2[], int nVarsC1, int nVarsC2 )
|
||||
{
|
||||
int Offset1 = 100, Offset2 = 200, i;
|
||||
unsigned Key;
|
||||
// compute the hash key
|
||||
Key = 0;
|
||||
for ( i = 0; i < nVarsC1; i++ )
|
||||
Key ^= s_Primes[Offset1+i] * piVarsC1[i];
|
||||
for ( i = 0; i < nVarsC2; i++ )
|
||||
Key ^= s_Primes[Offset2+i] * piVarsC2[i];
|
||||
return Key;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the hash key of the divisor represented by the pair of cubes.]
|
||||
|
||||
Description [Goes through the variables in both cubes. Skips the identical
|
||||
ones (this corresponds to making the cubes cube-free). Computes the hash
|
||||
value of the cubes. Assigns the number of literals in the base and in the
|
||||
cubes without base.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
unsigned Fxu_PairHashKey( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2,
|
||||
int * pnBase, int * pnLits1, int * pnLits2 )
|
||||
{
|
||||
int Offset1 = 100, Offset2 = 200;
|
||||
int nBase, nLits1, nLits2;
|
||||
Fxu_Lit * pLit1, * pLit2;
|
||||
unsigned Key;
|
||||
|
||||
// compute the hash key
|
||||
Key = 0;
|
||||
nLits1 = 0;
|
||||
nLits2 = 0;
|
||||
nBase = 0;
|
||||
pLit1 = pCube1->lLits.pHead;
|
||||
pLit2 = pCube2->lLits.pHead;
|
||||
while ( 1 )
|
||||
{
|
||||
if ( pLit1 && pLit2 )
|
||||
{
|
||||
if ( pLit1->iVar == pLit2->iVar )
|
||||
{ // ensure cube-free
|
||||
pLit1 = pLit1->pHNext;
|
||||
pLit2 = pLit2->pHNext;
|
||||
// add this literal to the base
|
||||
nBase++;
|
||||
}
|
||||
else if ( pLit1->iVar < pLit2->iVar )
|
||||
{
|
||||
Key ^= s_Primes[Offset1+nLits1] * pLit1->iVar;
|
||||
pLit1 = pLit1->pHNext;
|
||||
nLits1++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Key ^= s_Primes[Offset2+nLits2] * pLit2->iVar;
|
||||
pLit2 = pLit2->pHNext;
|
||||
nLits2++;
|
||||
}
|
||||
}
|
||||
else if ( pLit1 && !pLit2 )
|
||||
{
|
||||
Key ^= s_Primes[Offset1+nLits1] * pLit1->iVar;
|
||||
pLit1 = pLit1->pHNext;
|
||||
nLits1++;
|
||||
}
|
||||
else if ( !pLit1 && pLit2 )
|
||||
{
|
||||
Key ^= s_Primes[Offset2+nLits2] * pLit2->iVar;
|
||||
pLit2 = pLit2->pHNext;
|
||||
nLits2++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
*pnBase = nBase;
|
||||
*pnLits1 = nLits1;
|
||||
*pnLits2 = nLits2;
|
||||
return Key;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Compares the two pairs.]
|
||||
|
||||
Description [Returns 1 if the divisors represented by these pairs
|
||||
are equal.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Fxu_PairCompare( Fxu_Pair * pPair1, Fxu_Pair * pPair2 )
|
||||
{
|
||||
Fxu_Lit * pD1C1, * pD1C2;
|
||||
Fxu_Lit * pD2C1, * pD2C2;
|
||||
int TopVar1, TopVar2;
|
||||
int Code;
|
||||
|
||||
if ( pPair1->nLits1 != pPair2->nLits1 )
|
||||
return 0;
|
||||
if ( pPair1->nLits2 != pPair2->nLits2 )
|
||||
return 0;
|
||||
|
||||
pD1C1 = pPair1->pCube1->lLits.pHead;
|
||||
pD1C2 = pPair1->pCube2->lLits.pHead;
|
||||
|
||||
pD2C1 = pPair2->pCube1->lLits.pHead;
|
||||
pD2C2 = pPair2->pCube2->lLits.pHead;
|
||||
|
||||
Code = pD1C1? 8: 0;
|
||||
Code |= pD1C2? 4: 0;
|
||||
Code |= pD2C1? 2: 0;
|
||||
Code |= pD2C2? 1: 0;
|
||||
assert( Code == 15 );
|
||||
|
||||
while ( 1 )
|
||||
{
|
||||
switch ( Code )
|
||||
{
|
||||
case 0: // -- -- NULL NULL NULL NULL
|
||||
return 1;
|
||||
case 1: // -- -1 NULL NULL NULL pD2C2
|
||||
return 0;
|
||||
case 2: // -- 1- NULL NULL pD2C1 NULL
|
||||
return 0;
|
||||
case 3: // -- 11 NULL NULL pD2C1 pD2C2
|
||||
if ( pD2C1->iVar != pD2C2->iVar )
|
||||
return 0;
|
||||
pD2C1 = pD2C1->pHNext;
|
||||
pD2C2 = pD2C2->pHNext;
|
||||
break;
|
||||
case 4: // -1 -- NULL pD1C2 NULL NULL
|
||||
return 0;
|
||||
case 5: // -1 -1 NULL pD1C2 NULL pD2C2
|
||||
if ( pD1C2->iVar != pD2C2->iVar )
|
||||
return 0;
|
||||
pD1C2 = pD1C2->pHNext;
|
||||
pD2C2 = pD2C2->pHNext;
|
||||
break;
|
||||
case 6: // -1 1- NULL pD1C2 pD2C1 NULL
|
||||
return 0;
|
||||
case 7: // -1 11 NULL pD1C2 pD2C1 pD2C2
|
||||
TopVar2 = Fxu_Min( pD2C1->iVar, pD2C2->iVar );
|
||||
if ( TopVar2 == pD1C2->iVar )
|
||||
{
|
||||
if ( pD2C1->iVar <= pD2C2->iVar )
|
||||
return 0;
|
||||
pD1C2 = pD1C2->pHNext;
|
||||
pD2C2 = pD2C2->pHNext;
|
||||
}
|
||||
else if ( TopVar2 < pD1C2->iVar )
|
||||
{
|
||||
if ( pD2C1->iVar != pD2C2->iVar )
|
||||
return 0;
|
||||
pD2C1 = pD2C1->pHNext;
|
||||
pD2C2 = pD2C2->pHNext;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
case 8: // 1- -- pD1C1 NULL NULL NULL
|
||||
return 0;
|
||||
case 9: // 1- -1 pD1C1 NULL NULL pD2C2
|
||||
return 0;
|
||||
case 10: // 1- 1- pD1C1 NULL pD2C1 NULL
|
||||
if ( pD1C1->iVar != pD2C1->iVar )
|
||||
return 0;
|
||||
pD1C1 = pD1C1->pHNext;
|
||||
pD2C1 = pD2C1->pHNext;
|
||||
break;
|
||||
case 11: // 1- 11 pD1C1 NULL pD2C1 pD2C2
|
||||
TopVar2 = Fxu_Min( pD2C1->iVar, pD2C2->iVar );
|
||||
if ( TopVar2 == pD1C1->iVar )
|
||||
{
|
||||
if ( pD2C1->iVar >= pD2C2->iVar )
|
||||
return 0;
|
||||
pD1C1 = pD1C1->pHNext;
|
||||
pD2C1 = pD2C1->pHNext;
|
||||
}
|
||||
else if ( TopVar2 < pD1C1->iVar )
|
||||
{
|
||||
if ( pD2C1->iVar != pD2C2->iVar )
|
||||
return 0;
|
||||
pD2C1 = pD2C1->pHNext;
|
||||
pD2C2 = pD2C2->pHNext;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
case 12: // 11 -- pD1C1 pD1C2 NULL NULL
|
||||
if ( pD1C1->iVar != pD1C2->iVar )
|
||||
return 0;
|
||||
pD1C1 = pD1C1->pHNext;
|
||||
pD1C2 = pD1C2->pHNext;
|
||||
break;
|
||||
case 13: // 11 -1 pD1C1 pD1C2 NULL pD2C2
|
||||
TopVar1 = Fxu_Min( pD1C1->iVar, pD1C2->iVar );
|
||||
if ( TopVar1 == pD2C2->iVar )
|
||||
{
|
||||
if ( pD1C1->iVar <= pD1C2->iVar )
|
||||
return 0;
|
||||
pD1C2 = pD1C2->pHNext;
|
||||
pD2C2 = pD2C2->pHNext;
|
||||
}
|
||||
else if ( TopVar1 < pD2C2->iVar )
|
||||
{
|
||||
if ( pD1C1->iVar != pD1C2->iVar )
|
||||
return 0;
|
||||
pD1C1 = pD1C1->pHNext;
|
||||
pD1C2 = pD1C2->pHNext;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
case 14: // 11 1- pD1C1 pD1C2 pD2C1 NULL
|
||||
TopVar1 = Fxu_Min( pD1C1->iVar, pD1C2->iVar );
|
||||
if ( TopVar1 == pD2C1->iVar )
|
||||
{
|
||||
if ( pD1C1->iVar >= pD1C2->iVar )
|
||||
return 0;
|
||||
pD1C1 = pD1C1->pHNext;
|
||||
pD2C1 = pD2C1->pHNext;
|
||||
}
|
||||
else if ( TopVar1 < pD2C1->iVar )
|
||||
{
|
||||
if ( pD1C1->iVar != pD1C2->iVar )
|
||||
return 0;
|
||||
pD1C1 = pD1C1->pHNext;
|
||||
pD1C2 = pD1C2->pHNext;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
break;
|
||||
case 15: // 11 11 pD1C1 pD1C2 pD2C1 pD2C2
|
||||
TopVar1 = Fxu_Min( pD1C1->iVar, pD1C2->iVar );
|
||||
TopVar2 = Fxu_Min( pD2C1->iVar, pD2C2->iVar );
|
||||
if ( TopVar1 == TopVar2 )
|
||||
{
|
||||
if ( pD1C1->iVar == pD1C2->iVar )
|
||||
{
|
||||
if ( pD2C1->iVar != pD2C2->iVar )
|
||||
return 0;
|
||||
pD1C1 = pD1C1->pHNext;
|
||||
pD1C2 = pD1C2->pHNext;
|
||||
pD2C1 = pD2C1->pHNext;
|
||||
pD2C2 = pD2C2->pHNext;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( pD2C1->iVar == pD2C2->iVar )
|
||||
return 0;
|
||||
if ( pD1C1->iVar < pD1C2->iVar )
|
||||
{
|
||||
if ( pD2C1->iVar > pD2C2->iVar )
|
||||
return 0;
|
||||
pD1C1 = pD1C1->pHNext;
|
||||
pD2C1 = pD2C1->pHNext;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( pD2C1->iVar < pD2C2->iVar )
|
||||
return 0;
|
||||
pD1C2 = pD1C2->pHNext;
|
||||
pD2C2 = pD2C2->pHNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( TopVar1 < TopVar2 )
|
||||
{
|
||||
if ( pD1C1->iVar != pD1C2->iVar )
|
||||
return 0;
|
||||
pD1C1 = pD1C1->pHNext;
|
||||
pD1C2 = pD1C2->pHNext;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( pD2C1->iVar != pD2C2->iVar )
|
||||
return 0;
|
||||
pD2C1 = pD2C1->pHNext;
|
||||
pD2C2 = pD2C2->pHNext;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert( 0 );
|
||||
break;
|
||||
}
|
||||
|
||||
Code = pD1C1? 8: 0;
|
||||
Code |= pD1C2? 4: 0;
|
||||
Code |= pD2C1? 2: 0;
|
||||
Code |= pD2C2? 1: 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates the storage for cubes pairs.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_PairAllocStorage( Fxu_Var * pVar, int nCubes )
|
||||
{
|
||||
int k;
|
||||
// assert( pVar->nCubes == 0 );
|
||||
pVar->nCubes = nCubes;
|
||||
// allocate memory for all the pairs
|
||||
pVar->ppPairs = ALLOC( Fxu_Pair **, nCubes );
|
||||
pVar->ppPairs[0] = ALLOC( Fxu_Pair *, nCubes * nCubes );
|
||||
memset( pVar->ppPairs[0], 0, sizeof(Fxu_Pair *) * nCubes * nCubes );
|
||||
for ( k = 1; k < nCubes; k++ )
|
||||
pVar->ppPairs[k] = pVar->ppPairs[k-1] + nCubes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Clears all pairs associated with this cube.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_PairClearStorage( Fxu_Cube * pCube )
|
||||
{
|
||||
Fxu_Var * pVar;
|
||||
int i;
|
||||
pVar = pCube->pVar;
|
||||
for ( i = 0; i < pVar->nCubes; i++ )
|
||||
{
|
||||
pVar->ppPairs[pCube->iCube][i] = NULL;
|
||||
pVar->ppPairs[i][pCube->iCube] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Clears all pairs associated with this cube.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_PairFreeStorage( Fxu_Var * pVar )
|
||||
{
|
||||
if ( pVar->ppPairs )
|
||||
{
|
||||
FREE( pVar->ppPairs[0] );
|
||||
FREE( pVar->ppPairs );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds the pair to storage.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Fxu_Pair * Fxu_PairAlloc( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2 )
|
||||
{
|
||||
Fxu_Pair * pPair;
|
||||
assert( pCube1->pVar == pCube2->pVar );
|
||||
pPair = MEM_ALLOC_FXU( p, Fxu_Pair, 1 );
|
||||
memset( pPair, 0, sizeof(Fxu_Pair) );
|
||||
pPair->pCube1 = pCube1;
|
||||
pPair->pCube2 = pCube2;
|
||||
pPair->iCube1 = pCube1->iCube;
|
||||
pPair->iCube2 = pCube2->iCube;
|
||||
return pPair;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds the pair to storage.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_PairAdd( Fxu_Pair * pPair )
|
||||
{
|
||||
Fxu_Var * pVar;
|
||||
|
||||
pVar = pPair->pCube1->pVar;
|
||||
assert( pVar == pPair->pCube2->pVar );
|
||||
|
||||
pVar->ppPairs[pPair->iCube1][pPair->iCube2] = pPair;
|
||||
pVar->ppPairs[pPair->iCube2][pPair->iCube1] = pPair;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,195 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [fxuPrint.c]
|
||||
|
||||
PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
|
||||
|
||||
Synopsis [Various printing procedures.]
|
||||
|
||||
Author [MVSIS Group]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - February 1, 2003.]
|
||||
|
||||
Revision [$Id: fxuPrint.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "fxuInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_MatrixPrint( FILE * pFile, Fxu_Matrix * p )
|
||||
{
|
||||
Fxu_Var * pVar;
|
||||
Fxu_Cube * pCube;
|
||||
Fxu_Double * pDiv;
|
||||
Fxu_Single * pSingle;
|
||||
Fxu_Lit * pLit;
|
||||
Fxu_Pair * pPair;
|
||||
int i, LastNum;
|
||||
int fStdout;
|
||||
|
||||
fStdout = 1;
|
||||
if ( pFile == NULL )
|
||||
{
|
||||
pFile = fopen( "matrix.txt", "w" );
|
||||
fStdout = 0;
|
||||
}
|
||||
|
||||
fprintf( pFile, "Matrix has %d vars, %d cubes, %d literals, %d divisors.\n",
|
||||
p->lVars.nItems, p->lCubes.nItems, p->nEntries, p->nDivs );
|
||||
fprintf( pFile, "Divisors selected so far: single = %d, double = %d.\n",
|
||||
p->nDivs1, p->nDivs2 );
|
||||
fprintf( pFile, "\n" );
|
||||
|
||||
// print the numbers on top of the matrix
|
||||
for ( i = 0; i < 12; i++ )
|
||||
fprintf( pFile, " " );
|
||||
Fxu_MatrixForEachVariable( p, pVar )
|
||||
fprintf( pFile, "%d", pVar->iVar % 10 );
|
||||
fprintf( pFile, "\n" );
|
||||
|
||||
// print the rows
|
||||
Fxu_MatrixForEachCube( p, pCube )
|
||||
{
|
||||
fprintf( pFile, "%4d", pCube->iCube );
|
||||
fprintf( pFile, " " );
|
||||
fprintf( pFile, "%4d", pCube->pVar->iVar );
|
||||
fprintf( pFile, " " );
|
||||
|
||||
// print the literals
|
||||
LastNum = -1;
|
||||
Fxu_CubeForEachLiteral( pCube, pLit )
|
||||
{
|
||||
for ( i = LastNum + 1; i < pLit->pVar->iVar; i++ )
|
||||
fprintf( pFile, "." );
|
||||
fprintf( pFile, "1" );
|
||||
LastNum = i;
|
||||
}
|
||||
for ( i = LastNum + 1; i < p->lVars.nItems; i++ )
|
||||
fprintf( pFile, "." );
|
||||
fprintf( pFile, "\n" );
|
||||
}
|
||||
fprintf( pFile, "\n" );
|
||||
|
||||
// print the double-cube divisors
|
||||
fprintf( pFile, "The double divisors are:\n" );
|
||||
Fxu_MatrixForEachDouble( p, pDiv, i )
|
||||
{
|
||||
fprintf( pFile, "Divisor #%3d (lit=%d,%d) (w=%2d): ",
|
||||
pDiv->Num, pDiv->lPairs.pHead->nLits1,
|
||||
pDiv->lPairs.pHead->nLits2, pDiv->Weight );
|
||||
Fxu_DoubleForEachPair( pDiv, pPair )
|
||||
fprintf( pFile, " <%d, %d> (b=%d)",
|
||||
pPair->pCube1->iCube, pPair->pCube2->iCube, pPair->nBase );
|
||||
fprintf( pFile, "\n" );
|
||||
}
|
||||
fprintf( pFile, "\n" );
|
||||
|
||||
// print the divisors associated with each cube
|
||||
fprintf( pFile, "The cubes are:\n" );
|
||||
Fxu_MatrixForEachCube( p, pCube )
|
||||
{
|
||||
fprintf( pFile, "Cube #%3d: ", pCube->iCube );
|
||||
if ( pCube->pVar->ppPairs )
|
||||
Fxu_CubeForEachPair( pCube, pPair, i )
|
||||
fprintf( pFile, " <%d %d> (d=%d) (b=%d)",
|
||||
pPair->iCube1, pPair->iCube2, pPair->pDiv->Num, pPair->nBase );
|
||||
fprintf( pFile, "\n" );
|
||||
}
|
||||
fprintf( pFile, "\n" );
|
||||
|
||||
// print the single-cube divisors
|
||||
fprintf( pFile, "The single divisors are:\n" );
|
||||
Fxu_MatrixForEachSingle( p, pSingle )
|
||||
{
|
||||
fprintf( pFile, "Single-cube divisor #%5d: Var1 = %4d. Var2 = %4d. Weight = %2d\n",
|
||||
pSingle->Num, pSingle->pVar1->iVar, pSingle->pVar2->iVar, pSingle->Weight );
|
||||
}
|
||||
fprintf( pFile, "\n" );
|
||||
|
||||
/*
|
||||
{
|
||||
int Index;
|
||||
fprintf( pFile, "Distribution of divisors in the hash table:\n" );
|
||||
for ( Index = 0; Index < p->nTableSize; Index++ )
|
||||
fprintf( pFile, " %d", p->pTable[Index].nItems );
|
||||
fprintf( pFile, "\n" );
|
||||
}
|
||||
*/
|
||||
if ( !fStdout )
|
||||
fclose( pFile );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_MatrixPrintDivisorProfile( FILE * pFile, Fxu_Matrix * p )
|
||||
{
|
||||
Fxu_Double * pDiv;
|
||||
int WeightMax;
|
||||
int * pProfile;
|
||||
int Counter1; // the number of -1 weight
|
||||
int CounterL; // the number of less than -1 weight
|
||||
int i;
|
||||
|
||||
WeightMax = Fxu_HeapDoubleReadMaxWeight( p->pHeapDouble );
|
||||
pProfile = ALLOC( int, (WeightMax + 1) );
|
||||
memset( pProfile, 0, sizeof(int) * (WeightMax + 1) );
|
||||
|
||||
Counter1 = 0;
|
||||
CounterL = 0;
|
||||
Fxu_MatrixForEachDouble( p, pDiv, i )
|
||||
{
|
||||
assert( pDiv->Weight <= WeightMax );
|
||||
if ( pDiv->Weight == -1 )
|
||||
Counter1++;
|
||||
else if ( pDiv->Weight < 0 )
|
||||
CounterL++;
|
||||
else
|
||||
pProfile[ pDiv->Weight ]++;
|
||||
}
|
||||
|
||||
fprintf( pFile, "The double divisors profile:\n" );
|
||||
fprintf( pFile, "Weight < -1 divisors = %6d\n", CounterL );
|
||||
fprintf( pFile, "Weight -1 divisors = %6d\n", Counter1 );
|
||||
for ( i = 0; i <= WeightMax; i++ )
|
||||
if ( pProfile[i] )
|
||||
fprintf( pFile, "Weight %3d divisors = %6d\n", i, pProfile[i] );
|
||||
fprintf( pFile, "End of divisor profile printout\n" );
|
||||
FREE( pProfile );
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,194 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [fxuReduce.c]
|
||||
|
||||
PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
|
||||
|
||||
Synopsis [Procedures to reduce the number of considered cube pairs.]
|
||||
|
||||
Author [MVSIS Group]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - February 1, 2003.]
|
||||
|
||||
Revision [$Id: fxuReduce.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "abc.h"
|
||||
#include "fxuInt.h"
|
||||
#include "fxu.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int Fxu_CountPairDiffs( char * pCover, unsigned char pDiffs[] );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Precomputes the pairs to use for creating two-cube divisors.]
|
||||
|
||||
Description [This procedure takes the matrix with variables and cubes
|
||||
allocated (p), the original covers of the nodes (i-sets) and their number
|
||||
(ppCovers,nCovers). The maximum number of pairs to compute and the total
|
||||
number of pairs in existence. This procedure adds to the storage of
|
||||
divisors exactly the given number of pairs (nPairsMax) while taking
|
||||
first those pairs that have the smallest number of literals in their
|
||||
cube-free form.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Fxu_PreprocessCubePairs( Fxu_Matrix * p, Vec_Ptr_t * vCovers, int nPairsTotal, int nPairsMax )
|
||||
{
|
||||
unsigned char * pnLitsDiff; // storage for the counters of diff literals
|
||||
int * pnPairCounters; // the counters of pairs for each number of diff literals
|
||||
Fxu_Cube * pCubeFirst, * pCubeLast;
|
||||
Fxu_Cube * pCube1, * pCube2;
|
||||
Fxu_Var * pVar;
|
||||
int nCubes, nBitsMax, nSum;
|
||||
int CutOffNum, CutOffQuant;
|
||||
int iPair, iQuant, k, c;
|
||||
int clk = clock();
|
||||
char * pSopCover;
|
||||
int nFanins;
|
||||
|
||||
assert( nPairsMax < nPairsTotal );
|
||||
|
||||
// allocate storage for counter of diffs
|
||||
pnLitsDiff = ALLOC( unsigned char, nPairsTotal );
|
||||
// go through the covers and precompute the distances between the pairs
|
||||
iPair = 0;
|
||||
nBitsMax = -1;
|
||||
for ( c = 0; c < vCovers->nSize; c++ )
|
||||
if ( pSopCover = vCovers->pArray[c] )
|
||||
{
|
||||
nFanins = Abc_SopGetVarNum(pSopCover);
|
||||
// precompute the differences
|
||||
Fxu_CountPairDiffs( pSopCover, pnLitsDiff + iPair );
|
||||
// update the counter
|
||||
nCubes = Abc_SopGetCubeNum( pSopCover );
|
||||
iPair += nCubes * (nCubes - 1) / 2;
|
||||
if ( nBitsMax < nFanins )
|
||||
nBitsMax = nFanins;
|
||||
}
|
||||
assert( iPair == nPairsTotal );
|
||||
|
||||
// allocate storage for counters of cube pairs by difference
|
||||
pnPairCounters = ALLOC( int, 2 * nBitsMax );
|
||||
memset( pnPairCounters, 0, sizeof(int) * 2 * nBitsMax );
|
||||
// count the number of different pairs
|
||||
for ( k = 0; k < nPairsTotal; k++ )
|
||||
pnPairCounters[ pnLitsDiff[k] ]++;
|
||||
// determine what pairs to take starting from the lower
|
||||
// so that there would be exactly pPairsMax pairs
|
||||
assert( pnPairCounters[0] == 0 ); // otherwise, covers are not dup-free
|
||||
assert( pnPairCounters[1] == 0 ); // otherwise, covers are not SCC-free
|
||||
nSum = 0;
|
||||
for ( k = 0; k < 2 * nBitsMax; k++ )
|
||||
{
|
||||
nSum += pnPairCounters[k];
|
||||
if ( nSum >= nPairsMax )
|
||||
{
|
||||
CutOffNum = k;
|
||||
CutOffQuant = pnPairCounters[k] - (nSum - nPairsMax);
|
||||
break;
|
||||
}
|
||||
}
|
||||
FREE( pnPairCounters );
|
||||
|
||||
// set to 0 all the pairs above the cut-off number and quantity
|
||||
iQuant = 0;
|
||||
iPair = 0;
|
||||
for ( k = 0; k < nPairsTotal; k++ )
|
||||
if ( pnLitsDiff[k] > CutOffNum )
|
||||
pnLitsDiff[k] = 0;
|
||||
else if ( pnLitsDiff[k] == CutOffNum )
|
||||
{
|
||||
if ( iQuant++ >= CutOffQuant )
|
||||
pnLitsDiff[k] = 0;
|
||||
else
|
||||
iPair++;
|
||||
}
|
||||
else
|
||||
iPair++;
|
||||
assert( iPair == nPairsMax );
|
||||
|
||||
// collect the corresponding pairs and add the divisors
|
||||
iPair = 0;
|
||||
for ( c = 0; c < vCovers->nSize; c++ )
|
||||
if ( pSopCover = vCovers->pArray[c] )
|
||||
{
|
||||
// get the var
|
||||
pVar = p->ppVars[2*c+1];
|
||||
// get the first cube
|
||||
pCubeFirst = pVar->pFirst;
|
||||
// get the last cube
|
||||
pCubeLast = pCubeFirst;
|
||||
for ( k = 0; k < pVar->nCubes; k++ )
|
||||
pCubeLast = pCubeLast->pNext;
|
||||
assert( pCubeLast == NULL || pCubeLast->pVar != pVar );
|
||||
|
||||
// go through the cube pairs
|
||||
for ( pCube1 = pCubeFirst; pCube1 != pCubeLast; pCube1 = pCube1->pNext )
|
||||
for ( pCube2 = pCube1->pNext; pCube2 != pCubeLast; pCube2 = pCube2->pNext )
|
||||
if ( pnLitsDiff[iPair++] )
|
||||
{ // create the divisors for this pair
|
||||
Fxu_MatrixAddDivisor( p, pCube1, pCube2 );
|
||||
}
|
||||
}
|
||||
assert( iPair == nPairsTotal );
|
||||
FREE( pnLitsDiff );
|
||||
//PRT( "Preprocess", clock() - clk );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Counts the differences in each cube pair in the cover.]
|
||||
|
||||
Description [Takes the cover (pCover) and the array where the
|
||||
diff counters go (pDiffs). The array pDiffs should have as many
|
||||
entries as there are different pairs of cubes in the cover: n(n-1)/2.
|
||||
Fills out the array pDiffs with the following info: For each cube
|
||||
pair, included in the array is the number of literals in both cubes
|
||||
after they are made cube free.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Fxu_CountPairDiffs( char * pCover, unsigned char pDiffs[] )
|
||||
{
|
||||
char * pCube1, * pCube2;
|
||||
int nOnes, nCubePairs, nFanins, v;
|
||||
nCubePairs = 0;
|
||||
nFanins = Abc_SopGetVarNum(pCover);
|
||||
Abc_SopForEachCube( pCover, nFanins, pCube1 )
|
||||
Abc_SopForEachCube( pCube1, nFanins, pCube2 )
|
||||
{
|
||||
if ( pCube1 == pCube2 )
|
||||
continue;
|
||||
nOnes = 0;
|
||||
for ( v = 0; v < nFanins; v++ )
|
||||
nOnes += (pCube1[v] != pCube2[v]);
|
||||
pDiffs[nCubePairs++] = nOnes;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,603 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [fxuSelect.c]
|
||||
|
||||
PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
|
||||
|
||||
Synopsis [Procedures to select the best divisor/complement pair.]
|
||||
|
||||
Author [MVSIS Group]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - February 1, 2003.]
|
||||
|
||||
Revision [$Id: fxuSelect.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "fxuInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define MAX_SIZE_LOOKAHEAD 20
|
||||
|
||||
static int Fxu_MatrixFindComplement( Fxu_Matrix * p, int iVar );
|
||||
|
||||
static Fxu_Double * Fxu_MatrixFindComplementSingle( Fxu_Matrix * p, Fxu_Single * pSingle );
|
||||
static Fxu_Single * Fxu_MatrixFindComplementDouble2( Fxu_Matrix * p, Fxu_Double * pDouble );
|
||||
static Fxu_Double * Fxu_MatrixFindComplementDouble4( Fxu_Matrix * p, Fxu_Double * pDouble );
|
||||
|
||||
Fxu_Double * Fxu_MatrixFindDouble( Fxu_Matrix * p,
|
||||
int piVarsC1[], int piVarsC2[], int nVarsC1, int nVarsC2 );
|
||||
void Fxu_MatrixGetDoubleVars( Fxu_Matrix * p, Fxu_Double * pDouble,
|
||||
int piVarsC1[], int piVarsC2[], int * pnVarsC1, int * pnVarsC2 );
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Selects the best pair (Single,Double) and returns their weight.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Fxu_Select( Fxu_Matrix * p, Fxu_Single ** ppSingle, Fxu_Double ** ppDouble )
|
||||
{
|
||||
// the top entries
|
||||
Fxu_Single * pSingles[MAX_SIZE_LOOKAHEAD];
|
||||
Fxu_Double * pDoubles[MAX_SIZE_LOOKAHEAD];
|
||||
// the complements
|
||||
Fxu_Double * pSCompl[MAX_SIZE_LOOKAHEAD];
|
||||
Fxu_Single * pDComplS[MAX_SIZE_LOOKAHEAD];
|
||||
Fxu_Double * pDComplD[MAX_SIZE_LOOKAHEAD];
|
||||
Fxu_Pair * pPair;
|
||||
int nSingles;
|
||||
int nDoubles;
|
||||
int i;
|
||||
int WeightBest;
|
||||
int WeightCur;
|
||||
int iNum, fBestS;
|
||||
|
||||
// collect the top entries from the queues
|
||||
for ( nSingles = 0; nSingles < MAX_SIZE_LOOKAHEAD; nSingles++ )
|
||||
{
|
||||
pSingles[nSingles] = Fxu_HeapSingleGetMax( p->pHeapSingle );
|
||||
if ( pSingles[nSingles] == NULL )
|
||||
break;
|
||||
}
|
||||
// put them back into the queue
|
||||
for ( i = 0; i < nSingles; i++ )
|
||||
if ( pSingles[i] )
|
||||
Fxu_HeapSingleInsert( p->pHeapSingle, pSingles[i] );
|
||||
|
||||
// the same for doubles
|
||||
// collect the top entries from the queues
|
||||
for ( nDoubles = 0; nDoubles < MAX_SIZE_LOOKAHEAD; nDoubles++ )
|
||||
{
|
||||
pDoubles[nDoubles] = Fxu_HeapDoubleGetMax( p->pHeapDouble );
|
||||
if ( pDoubles[nDoubles] == NULL )
|
||||
break;
|
||||
}
|
||||
// put them back into the queue
|
||||
for ( i = 0; i < nDoubles; i++ )
|
||||
if ( pDoubles[i] )
|
||||
Fxu_HeapDoubleInsert( p->pHeapDouble, pDoubles[i] );
|
||||
|
||||
// for each single, find the complement double (if any)
|
||||
for ( i = 0; i < nSingles; i++ )
|
||||
if ( pSingles[i] )
|
||||
pSCompl[i] = Fxu_MatrixFindComplementSingle( p, pSingles[i] );
|
||||
|
||||
// for each double, find the complement single or double (if any)
|
||||
for ( i = 0; i < nDoubles; i++ )
|
||||
if ( pDoubles[i] )
|
||||
{
|
||||
pPair = pDoubles[i]->lPairs.pHead;
|
||||
if ( pPair->nLits1 == 1 && pPair->nLits2 == 1 )
|
||||
{
|
||||
pDComplS[i] = Fxu_MatrixFindComplementDouble2( p, pDoubles[i] );
|
||||
pDComplD[i] = NULL;
|
||||
}
|
||||
// else if ( pPair->nLits1 == 2 && pPair->nLits2 == 2 )
|
||||
// {
|
||||
// pDComplS[i] = NULL;
|
||||
// pDComplD[i] = Fxu_MatrixFindComplementDouble4( p, pDoubles[i] );
|
||||
// }
|
||||
else
|
||||
{
|
||||
pDComplS[i] = NULL;
|
||||
pDComplD[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// select the best pair
|
||||
WeightBest = -1;
|
||||
for ( i = 0; i < nSingles; i++ )
|
||||
{
|
||||
WeightCur = pSingles[i]->Weight;
|
||||
if ( pSCompl[i] )
|
||||
{
|
||||
// add the weight of the double
|
||||
WeightCur += pSCompl[i]->Weight;
|
||||
// there is no need to implement this double, so...
|
||||
pPair = pSCompl[i]->lPairs.pHead;
|
||||
WeightCur += pPair->nLits1 + pPair->nLits2;
|
||||
}
|
||||
if ( WeightBest < WeightCur )
|
||||
{
|
||||
WeightBest = WeightCur;
|
||||
*ppSingle = pSingles[i];
|
||||
*ppDouble = pSCompl[i];
|
||||
fBestS = 1;
|
||||
iNum = i;
|
||||
}
|
||||
}
|
||||
for ( i = 0; i < nDoubles; i++ )
|
||||
{
|
||||
WeightCur = pDoubles[i]->Weight;
|
||||
if ( pDComplS[i] )
|
||||
{
|
||||
// add the weight of the single
|
||||
WeightCur += pDComplS[i]->Weight;
|
||||
// there is no need to implement this double, so...
|
||||
pPair = pDoubles[i]->lPairs.pHead;
|
||||
WeightCur += pPair->nLits1 + pPair->nLits2;
|
||||
}
|
||||
if ( WeightBest < WeightCur )
|
||||
{
|
||||
WeightBest = WeightCur;
|
||||
*ppSingle = pDComplS[i];
|
||||
*ppDouble = pDoubles[i];
|
||||
fBestS = 0;
|
||||
iNum = i;
|
||||
}
|
||||
}
|
||||
/*
|
||||
// print the statistics
|
||||
printf( "\n" );
|
||||
for ( i = 0; i < nSingles; i++ )
|
||||
{
|
||||
printf( "Single #%d: Weight = %3d. ", i, pSingles[i]->Weight );
|
||||
printf( "Compl: " );
|
||||
if ( pSCompl[i] == NULL )
|
||||
printf( "None." );
|
||||
else
|
||||
printf( "D Weight = %3d Sum = %3d",
|
||||
pSCompl[i]->Weight, pSCompl[i]->Weight + pSingles[i]->Weight );
|
||||
printf( "\n" );
|
||||
}
|
||||
printf( "\n" );
|
||||
for ( i = 0; i < nDoubles; i++ )
|
||||
{
|
||||
printf( "Double #%d: Weight = %3d. ", i, pDoubles[i]->Weight );
|
||||
printf( "Compl: " );
|
||||
if ( pDComplS[i] == NULL && pDComplD[i] == NULL )
|
||||
printf( "None." );
|
||||
else if ( pDComplS[i] )
|
||||
printf( "S Weight = %3d Sum = %3d",
|
||||
pDComplS[i]->Weight, pDComplS[i]->Weight + pDoubles[i]->Weight );
|
||||
else if ( pDComplD[i] )
|
||||
printf( "D Weight = %3d Sum = %3d",
|
||||
pDComplD[i]->Weight, pDComplD[i]->Weight + pDoubles[i]->Weight );
|
||||
printf( "\n" );
|
||||
}
|
||||
if ( WeightBest == -1 )
|
||||
printf( "Selected NONE\n" );
|
||||
else
|
||||
{
|
||||
printf( "Selected = %s. ", fBestS? "S": "D" );
|
||||
printf( "Number = %d. ", iNum );
|
||||
printf( "Weight = %d.\n", WeightBest );
|
||||
}
|
||||
printf( "\n" );
|
||||
*/
|
||||
return WeightBest;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Fxu_Double * Fxu_MatrixFindComplementSingle( Fxu_Matrix * p, Fxu_Single * pSingle )
|
||||
{
|
||||
// int * pValue2Node = p->pValue2Node;
|
||||
int iVar1, iVar2;
|
||||
int iVar1C, iVar2C;
|
||||
// get the variables of this single div
|
||||
iVar1 = pSingle->pVar1->iVar;
|
||||
iVar2 = pSingle->pVar2->iVar;
|
||||
iVar1C = Fxu_MatrixFindComplement( p, iVar1 );
|
||||
iVar2C = Fxu_MatrixFindComplement( p, iVar2 );
|
||||
if ( iVar1C == -1 || iVar2C == -1 )
|
||||
return NULL;
|
||||
assert( iVar1C < iVar2C );
|
||||
return Fxu_MatrixFindDouble( p, &iVar1C, &iVar2C, 1, 1 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Fxu_Single * Fxu_MatrixFindComplementDouble2( Fxu_Matrix * p, Fxu_Double * pDouble )
|
||||
{
|
||||
// int * pValue2Node = p->pValue2Node;
|
||||
int piVarsC1[10], piVarsC2[10];
|
||||
int nVarsC1, nVarsC2;
|
||||
int iVar1, iVar2, iVarTemp;
|
||||
int iVar1C, iVar2C;
|
||||
Fxu_Single * pSingle;
|
||||
|
||||
// get the variables of this double div
|
||||
Fxu_MatrixGetDoubleVars( p, pDouble, piVarsC1, piVarsC2, &nVarsC1, &nVarsC2 );
|
||||
assert( nVarsC1 == 1 );
|
||||
assert( nVarsC2 == 1 );
|
||||
iVar1 = piVarsC1[0];
|
||||
iVar2 = piVarsC2[0];
|
||||
assert( iVar1 < iVar2 );
|
||||
|
||||
iVar1C = Fxu_MatrixFindComplement( p, iVar1 );
|
||||
iVar2C = Fxu_MatrixFindComplement( p, iVar2 );
|
||||
if ( iVar1C == -1 || iVar2C == -1 )
|
||||
return NULL;
|
||||
|
||||
// go through the queque and find this one
|
||||
// assert( iVar1C < iVar2C );
|
||||
if ( iVar1C > iVar2C )
|
||||
{
|
||||
iVarTemp = iVar1C;
|
||||
iVar1C = iVar2C;
|
||||
iVar2C = iVarTemp;
|
||||
}
|
||||
|
||||
Fxu_MatrixForEachSingle( p, pSingle )
|
||||
if ( pSingle->pVar1->iVar == iVar1C && pSingle->pVar2->iVar == iVar2C )
|
||||
return pSingle;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Fxu_Double * Fxu_MatrixFindComplementDouble4( Fxu_Matrix * p, Fxu_Double * pDouble )
|
||||
{
|
||||
// int * pValue2Node = p->pValue2Node;
|
||||
int piVarsC1[10], piVarsC2[10];
|
||||
int nVarsC1, nVarsC2;
|
||||
int iVar11, iVar12, iVar21, iVar22;
|
||||
int iVar11C, iVar12C, iVar21C, iVar22C;
|
||||
int RetValue;
|
||||
|
||||
// get the variables of this double div
|
||||
Fxu_MatrixGetDoubleVars( p, pDouble, piVarsC1, piVarsC2, &nVarsC1, &nVarsC2 );
|
||||
assert( nVarsC1 == 2 && nVarsC2 == 2 );
|
||||
|
||||
iVar11 = piVarsC1[0];
|
||||
iVar12 = piVarsC1[1];
|
||||
iVar21 = piVarsC2[0];
|
||||
iVar22 = piVarsC2[1];
|
||||
assert( iVar11 < iVar21 );
|
||||
|
||||
iVar11C = Fxu_MatrixFindComplement( p, iVar11 );
|
||||
iVar12C = Fxu_MatrixFindComplement( p, iVar12 );
|
||||
iVar21C = Fxu_MatrixFindComplement( p, iVar21 );
|
||||
iVar22C = Fxu_MatrixFindComplement( p, iVar22 );
|
||||
if ( iVar11C == -1 || iVar12C == -1 || iVar21C == -1 || iVar22C == -1 )
|
||||
return NULL;
|
||||
if ( iVar11C != iVar21 || iVar12C != iVar22 ||
|
||||
iVar21C != iVar11 || iVar22C != iVar12 )
|
||||
return NULL;
|
||||
|
||||
// a'b' + ab => a'b + ab'
|
||||
// a'b + ab' => a'b' + ab
|
||||
// swap the second pair in each cube
|
||||
RetValue = piVarsC1[1];
|
||||
piVarsC1[1] = piVarsC2[1];
|
||||
piVarsC2[1] = RetValue;
|
||||
|
||||
return Fxu_MatrixFindDouble( p, piVarsC1, piVarsC2, 2, 2 );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Fxu_MatrixFindComplement( Fxu_Matrix * p, int iVar )
|
||||
{
|
||||
return iVar ^ 1;
|
||||
/*
|
||||
// int * pValue2Node = p->pValue2Node;
|
||||
int iVarC;
|
||||
int iNode;
|
||||
int Beg, End;
|
||||
|
||||
// get the nodes
|
||||
iNode = pValue2Node[iVar];
|
||||
// get the first node with the same var
|
||||
for ( Beg = iVar; Beg >= 0; Beg-- )
|
||||
if ( pValue2Node[Beg] != iNode )
|
||||
{
|
||||
Beg++;
|
||||
break;
|
||||
}
|
||||
// get the last node with the same var
|
||||
for ( End = iVar; ; End++ )
|
||||
if ( pValue2Node[End] != iNode )
|
||||
{
|
||||
End--;
|
||||
break;
|
||||
}
|
||||
|
||||
// if one of the vars is not binary, quit
|
||||
if ( End - Beg > 1 )
|
||||
return -1;
|
||||
|
||||
// get the complements
|
||||
if ( iVar == Beg )
|
||||
iVarC = End;
|
||||
else if ( iVar == End )
|
||||
iVarC = Beg;
|
||||
else
|
||||
{
|
||||
assert( 0 );
|
||||
}
|
||||
return iVarC;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_MatrixGetDoubleVars( Fxu_Matrix * p, Fxu_Double * pDouble,
|
||||
int piVarsC1[], int piVarsC2[], int * pnVarsC1, int * pnVarsC2 )
|
||||
{
|
||||
Fxu_Pair * pPair;
|
||||
Fxu_Lit * pLit1, * pLit2;
|
||||
int nLits1, nLits2;
|
||||
|
||||
// get the first pair
|
||||
pPair = pDouble->lPairs.pHead;
|
||||
// init the parameters
|
||||
nLits1 = 0;
|
||||
nLits2 = 0;
|
||||
pLit1 = pPair->pCube1->lLits.pHead;
|
||||
pLit2 = pPair->pCube2->lLits.pHead;
|
||||
while ( 1 )
|
||||
{
|
||||
if ( pLit1 && pLit2 )
|
||||
{
|
||||
if ( pLit1->iVar == pLit2->iVar )
|
||||
{ // ensure cube-free
|
||||
pLit1 = pLit1->pHNext;
|
||||
pLit2 = pLit2->pHNext;
|
||||
}
|
||||
else if ( pLit1->iVar < pLit2->iVar )
|
||||
{
|
||||
piVarsC1[nLits1++] = pLit1->iVar;
|
||||
pLit1 = pLit1->pHNext;
|
||||
}
|
||||
else
|
||||
{
|
||||
piVarsC2[nLits2++] = pLit2->iVar;
|
||||
pLit2 = pLit2->pHNext;
|
||||
}
|
||||
}
|
||||
else if ( pLit1 && !pLit2 )
|
||||
{
|
||||
piVarsC1[nLits1++] = pLit1->iVar;
|
||||
pLit1 = pLit1->pHNext;
|
||||
}
|
||||
else if ( !pLit1 && pLit2 )
|
||||
{
|
||||
piVarsC2[nLits2++] = pLit2->iVar;
|
||||
pLit2 = pLit2->pHNext;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
*pnVarsC1 = nLits1;
|
||||
*pnVarsC2 = nLits2;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Fxu_Double * Fxu_MatrixFindDouble( Fxu_Matrix * p,
|
||||
int piVarsC1[], int piVarsC2[], int nVarsC1, int nVarsC2 )
|
||||
{
|
||||
int piVarsC1_[100], piVarsC2_[100];
|
||||
int nVarsC1_, nVarsC2_, i;
|
||||
Fxu_Double * pDouble;
|
||||
Fxu_Pair * pPair;
|
||||
unsigned Key;
|
||||
|
||||
assert( nVarsC1 > 0 );
|
||||
assert( nVarsC2 > 0 );
|
||||
assert( piVarsC1[0] < piVarsC2[0] );
|
||||
|
||||
// get the hash key
|
||||
Key = Fxu_PairHashKeyArray( p, piVarsC1, piVarsC2, nVarsC1, nVarsC2 );
|
||||
|
||||
// check if the divisor for this pair already exists
|
||||
Key %= p->nTableSize;
|
||||
Fxu_TableForEachDouble( p, Key, pDouble )
|
||||
{
|
||||
pPair = pDouble->lPairs.pHead;
|
||||
if ( pPair->nLits1 != nVarsC1 )
|
||||
continue;
|
||||
if ( pPair->nLits2 != nVarsC2 )
|
||||
continue;
|
||||
// get the cubes of this divisor
|
||||
Fxu_MatrixGetDoubleVars( p, pDouble, piVarsC1_, piVarsC2_, &nVarsC1_, &nVarsC2_ );
|
||||
// compare lits of the first cube
|
||||
for ( i = 0; i < nVarsC1; i++ )
|
||||
if ( piVarsC1[i] != piVarsC1_[i] )
|
||||
break;
|
||||
if ( i != nVarsC1 )
|
||||
continue;
|
||||
// compare lits of the second cube
|
||||
for ( i = 0; i < nVarsC2; i++ )
|
||||
if ( piVarsC2[i] != piVarsC2_[i] )
|
||||
break;
|
||||
if ( i != nVarsC2 )
|
||||
continue;
|
||||
return pDouble;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Fxu_SelectSCD( Fxu_Matrix * p, int WeightLimit, Fxu_Var ** ppVar1, Fxu_Var ** ppVar2 )
|
||||
{
|
||||
// int * pValue2Node = p->pValue2Node;
|
||||
Fxu_Var * pVar1;
|
||||
Fxu_Var * pVar2, * pVarTemp;
|
||||
Fxu_Lit * pLitV, * pLitH;
|
||||
int Coin;
|
||||
int CounterAll;
|
||||
int CounterTest;
|
||||
int WeightCur;
|
||||
int WeightBest;
|
||||
|
||||
CounterAll = 0;
|
||||
CounterTest = 0;
|
||||
|
||||
WeightBest = -10;
|
||||
|
||||
// iterate through the columns in the matrix
|
||||
Fxu_MatrixForEachVariable( p, pVar1 )
|
||||
{
|
||||
// start collecting the affected vars
|
||||
Fxu_MatrixRingVarsStart( p );
|
||||
|
||||
// go through all the literals of this variable
|
||||
for ( pLitV = pVar1->lLits.pHead; pLitV; pLitV = pLitV->pVNext )
|
||||
{
|
||||
// for this literal, go through all the horizontal literals
|
||||
for ( pLitH = pLitV->pHNext; pLitH; pLitH = pLitH->pHNext )
|
||||
{
|
||||
// get another variable
|
||||
pVar2 = pLitH->pVar;
|
||||
CounterAll++;
|
||||
// skip the var if it is already used
|
||||
if ( pVar2->pOrder )
|
||||
continue;
|
||||
// skip the var if it belongs to the same node
|
||||
// if ( pValue2Node[pVar1->iVar] == pValue2Node[pVar2->iVar] )
|
||||
// continue;
|
||||
// collect the var
|
||||
Fxu_MatrixRingVarsAdd( p, pVar2 );
|
||||
}
|
||||
}
|
||||
// stop collecting the selected vars
|
||||
Fxu_MatrixRingVarsStop( p );
|
||||
|
||||
// iterate through the selected vars
|
||||
Fxu_MatrixForEachVarInRing( p, pVar2 )
|
||||
{
|
||||
CounterTest++;
|
||||
|
||||
// count the coincidence
|
||||
Coin = Fxu_SingleCountCoincidence( p, pVar1, pVar2 );
|
||||
assert( Coin > 0 );
|
||||
|
||||
// get the new weight
|
||||
WeightCur = Coin - 2;
|
||||
|
||||
// compare the weights
|
||||
if ( WeightBest < WeightCur )
|
||||
{
|
||||
WeightBest = WeightCur;
|
||||
*ppVar1 = pVar1;
|
||||
*ppVar2 = pVar2;
|
||||
}
|
||||
}
|
||||
// unmark the vars
|
||||
Fxu_MatrixForEachVarInRingSafe( p, pVar2, pVarTemp )
|
||||
pVar2->pOrder = NULL;
|
||||
Fxu_MatrixRingVarsReset( p );
|
||||
}
|
||||
|
||||
// if ( WeightBest == WeightLimit )
|
||||
// return -1;
|
||||
return WeightBest;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [fxuSingle.c]
|
||||
|
||||
PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
|
||||
|
||||
Synopsis [Procedures to compute the set of single-cube divisors.]
|
||||
|
||||
Author [MVSIS Group]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - February 1, 2003.]
|
||||
|
||||
Revision [$Id: fxuSingle.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "fxuInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes and adds all single-cube divisors to storage.]
|
||||
|
||||
Description [This procedure should be called once when the matrix is
|
||||
already contructed before the process of logic extraction begins..]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_MatrixComputeSingles( Fxu_Matrix * p )
|
||||
{
|
||||
Fxu_Var * pVar;
|
||||
// iterate through the columns in the matrix
|
||||
Fxu_MatrixForEachVariable( p, pVar )
|
||||
Fxu_MatrixComputeSinglesOne( p, pVar );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds the single-cube divisors associated with a new column.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_MatrixComputeSinglesOne( Fxu_Matrix * p, Fxu_Var * pVar )
|
||||
{
|
||||
// int * pValue2Node = p->pValue2Node;
|
||||
Fxu_Lit * pLitV, * pLitH;
|
||||
Fxu_Var * pVar2;
|
||||
int Coin;
|
||||
// int CounterAll;
|
||||
// int CounterTest;
|
||||
int WeightCur;
|
||||
|
||||
// start collecting the affected vars
|
||||
Fxu_MatrixRingVarsStart( p );
|
||||
// go through all the literals of this variable
|
||||
for ( pLitV = pVar->lLits.pHead; pLitV; pLitV = pLitV->pVNext )
|
||||
// for this literal, go through all the horizontal literals
|
||||
for ( pLitH = pLitV->pHPrev; pLitH; pLitH = pLitH->pHPrev )
|
||||
{
|
||||
// get another variable
|
||||
pVar2 = pLitH->pVar;
|
||||
// CounterAll++;
|
||||
// skip the var if it is already used
|
||||
if ( pVar2->pOrder )
|
||||
continue;
|
||||
// skip the var if it belongs to the same node
|
||||
// if ( pValue2Node[pVar->iVar] == pValue2Node[pVar2->iVar] )
|
||||
// continue;
|
||||
// collect the var
|
||||
Fxu_MatrixRingVarsAdd( p, pVar2 );
|
||||
}
|
||||
// stop collecting the selected vars
|
||||
Fxu_MatrixRingVarsStop( p );
|
||||
|
||||
// iterate through the selected vars
|
||||
Fxu_MatrixForEachVarInRing( p, pVar2 )
|
||||
{
|
||||
// CounterTest++;
|
||||
// count the coincidence
|
||||
Coin = Fxu_SingleCountCoincidence( p, pVar2, pVar );
|
||||
assert( Coin > 0 );
|
||||
// get the new weight
|
||||
WeightCur = Coin - 2;
|
||||
if ( WeightCur >= 0 )
|
||||
Fxu_MatrixAddSingle( p, pVar2, pVar, WeightCur );
|
||||
}
|
||||
|
||||
// unmark the vars
|
||||
Fxu_MatrixRingVarsUnmark( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the coincidence count of two columns.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Fxu_SingleCountCoincidence( Fxu_Matrix * p, Fxu_Var * pVar1, Fxu_Var * pVar2 )
|
||||
{
|
||||
Fxu_Lit * pLit1, * pLit2;
|
||||
int Result;
|
||||
|
||||
// compute the coincidence count
|
||||
Result = 0;
|
||||
pLit1 = pVar1->lLits.pHead;
|
||||
pLit2 = pVar2->lLits.pHead;
|
||||
while ( 1 )
|
||||
{
|
||||
if ( pLit1 && pLit2 )
|
||||
{
|
||||
if ( pLit1->pCube->pVar->iVar == pLit2->pCube->pVar->iVar )
|
||||
{ // the variables are the same
|
||||
if ( pLit1->iCube == pLit2->iCube )
|
||||
{ // the literals are the same
|
||||
pLit1 = pLit1->pVNext;
|
||||
pLit2 = pLit2->pVNext;
|
||||
// add this literal to the coincidence
|
||||
Result++;
|
||||
}
|
||||
else if ( pLit1->iCube < pLit2->iCube )
|
||||
pLit1 = pLit1->pVNext;
|
||||
else
|
||||
pLit2 = pLit2->pVNext;
|
||||
}
|
||||
else if ( pLit1->pCube->pVar->iVar < pLit2->pCube->pVar->iVar )
|
||||
pLit1 = pLit1->pVNext;
|
||||
else
|
||||
pLit2 = pLit2->pVNext;
|
||||
}
|
||||
else if ( pLit1 && !pLit2 )
|
||||
pLit1 = pLit1->pVNext;
|
||||
else if ( !pLit1 && pLit2 )
|
||||
pLit2 = pLit2->pVNext;
|
||||
else
|
||||
break;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,802 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [fxuUpdate.c]
|
||||
|
||||
PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
|
||||
|
||||
Synopsis [Updating the sparse matrix when divisors are accepted.]
|
||||
|
||||
Author [MVSIS Group]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - February 1, 2003.]
|
||||
|
||||
Revision [$Id: fxuUpdate.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "fxuInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void Fxu_UpdateDoublePairs( Fxu_Matrix * p, Fxu_Double * pDouble, Fxu_Var * pVar );
|
||||
static void Fxu_UpdateMatrixDoubleCreateCubes( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2, Fxu_Double * pDiv );
|
||||
static void Fxu_UpdateMatrixDoubleClean( Fxu_Matrix * p, Fxu_Cube * pCubeUse, Fxu_Cube * pCubeRem );
|
||||
static void Fxu_UpdateMatrixSingleClean( Fxu_Matrix * p, Fxu_Var * pVar1, Fxu_Var * pVar2, Fxu_Var * pVarNew );
|
||||
|
||||
static void Fxu_UpdateCreateNewVars( Fxu_Matrix * p, Fxu_Var ** ppVarC, Fxu_Var ** ppVarD, int nCubes );
|
||||
static int Fxu_UpdatePairCompare( Fxu_Pair ** ppP1, Fxu_Pair ** ppP2 );
|
||||
static void Fxu_UpdatePairsSort( Fxu_Matrix * p, Fxu_Double * pDouble );
|
||||
|
||||
static void Fxu_UpdateCleanOldDoubles( Fxu_Matrix * p, Fxu_Double * pDiv, Fxu_Cube * pCube );
|
||||
static void Fxu_UpdateAddNewDoubles( Fxu_Matrix * p, Fxu_Cube * pCube );
|
||||
static void Fxu_UpdateCleanOldSingles( Fxu_Matrix * p );
|
||||
static void Fxu_UpdateAddNewSingles( Fxu_Matrix * p, Fxu_Var * pVar );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Updates the matrix after selecting two divisors.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_Update( Fxu_Matrix * p, Fxu_Single * pSingle, Fxu_Double * pDouble )
|
||||
{
|
||||
Fxu_Cube * pCube, * pCubeNew;
|
||||
Fxu_Var * pVarC, * pVarD;
|
||||
Fxu_Var * pVar1, * pVar2;
|
||||
|
||||
// consider trivial cases
|
||||
if ( pSingle == NULL )
|
||||
{
|
||||
assert( pDouble->Weight == Fxu_HeapDoubleReadMaxWeight( p->pHeapDouble ) );
|
||||
Fxu_UpdateDouble( p );
|
||||
return;
|
||||
}
|
||||
if ( pDouble == NULL )
|
||||
{
|
||||
assert( pSingle->Weight == Fxu_HeapSingleReadMaxWeight( p->pHeapSingle ) );
|
||||
Fxu_UpdateSingle( p );
|
||||
return;
|
||||
}
|
||||
|
||||
// get the variables of the single
|
||||
pVar1 = pSingle->pVar1;
|
||||
pVar2 = pSingle->pVar2;
|
||||
|
||||
// remove the best double from the heap
|
||||
Fxu_HeapDoubleDelete( p->pHeapDouble, pDouble );
|
||||
// remove the best divisor from the table
|
||||
Fxu_ListTableDelDivisor( p, pDouble );
|
||||
|
||||
// create two new columns (vars)
|
||||
Fxu_UpdateCreateNewVars( p, &pVarC, &pVarD, 1 );
|
||||
// create one new row (cube)
|
||||
pCubeNew = Fxu_MatrixAddCube( p, pVarD, 0 );
|
||||
pCubeNew->pFirst = pCubeNew;
|
||||
// set the first cube of the positive var
|
||||
pVarD->pFirst = pCubeNew;
|
||||
|
||||
// start collecting the affected vars and cubes
|
||||
Fxu_MatrixRingCubesStart( p );
|
||||
Fxu_MatrixRingVarsStart( p );
|
||||
// add the vars
|
||||
Fxu_MatrixRingVarsAdd( p, pVar1 );
|
||||
Fxu_MatrixRingVarsAdd( p, pVar2 );
|
||||
// remove the literals and collect the affected cubes
|
||||
// remove the divisors associated with this cube
|
||||
// add to the affected cube the literal corresponding to the new column
|
||||
Fxu_UpdateMatrixSingleClean( p, pVar1, pVar2, pVarD );
|
||||
// replace each two cubes of the pair by one new cube
|
||||
// the new cube contains the base and the new literal
|
||||
Fxu_UpdateDoublePairs( p, pDouble, pVarC );
|
||||
// stop collecting the affected vars and cubes
|
||||
Fxu_MatrixRingCubesStop( p );
|
||||
Fxu_MatrixRingVarsStop( p );
|
||||
|
||||
// add the literals to the new cube
|
||||
assert( pVar1->iVar < pVar2->iVar );
|
||||
assert( Fxu_SingleCountCoincidence( p, pVar1, pVar2 ) == 0 );
|
||||
Fxu_MatrixAddLiteral( p, pCubeNew, pVar1 );
|
||||
Fxu_MatrixAddLiteral( p, pCubeNew, pVar2 );
|
||||
|
||||
// create new doubles; we cannot add them in the same loop
|
||||
// because we first have to create *all* new cubes for each node
|
||||
Fxu_MatrixForEachCubeInRing( p, pCube )
|
||||
Fxu_UpdateAddNewDoubles( p, pCube );
|
||||
// update the singles after removing some literals
|
||||
Fxu_UpdateCleanOldSingles( p );
|
||||
|
||||
// undo the temporary rings with cubes and vars
|
||||
Fxu_MatrixRingCubesUnmark( p );
|
||||
Fxu_MatrixRingVarsUnmark( p );
|
||||
// we should undo the rings before creating new singles
|
||||
|
||||
// create new singles
|
||||
Fxu_UpdateAddNewSingles( p, pVarC );
|
||||
Fxu_UpdateAddNewSingles( p, pVarD );
|
||||
|
||||
// recycle the divisor
|
||||
MEM_FREE_FXU( p, Fxu_Double, 1, pDouble );
|
||||
p->nDivs3++;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Updates after accepting single cube divisor.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_UpdateSingle( Fxu_Matrix * p )
|
||||
{
|
||||
Fxu_Single * pSingle;
|
||||
Fxu_Cube * pCube, * pCubeNew;
|
||||
Fxu_Var * pVarC, * pVarD;
|
||||
Fxu_Var * pVar1, * pVar2;
|
||||
|
||||
// read the best divisor from the heap
|
||||
pSingle = Fxu_HeapSingleReadMax( p->pHeapSingle );
|
||||
// get the variables of this single-cube divisor
|
||||
pVar1 = pSingle->pVar1;
|
||||
pVar2 = pSingle->pVar2;
|
||||
|
||||
// create two new columns (vars)
|
||||
Fxu_UpdateCreateNewVars( p, &pVarC, &pVarD, 1 );
|
||||
// create one new row (cube)
|
||||
pCubeNew = Fxu_MatrixAddCube( p, pVarD, 0 );
|
||||
pCubeNew->pFirst = pCubeNew;
|
||||
// set the first cube
|
||||
pVarD->pFirst = pCubeNew;
|
||||
|
||||
// start collecting the affected vars and cubes
|
||||
Fxu_MatrixRingCubesStart( p );
|
||||
Fxu_MatrixRingVarsStart( p );
|
||||
// add the vars
|
||||
Fxu_MatrixRingVarsAdd( p, pVar1 );
|
||||
Fxu_MatrixRingVarsAdd( p, pVar2 );
|
||||
// remove the literals and collect the affected cubes
|
||||
// remove the divisors associated with this cube
|
||||
// add to the affected cube the literal corresponding to the new column
|
||||
Fxu_UpdateMatrixSingleClean( p, pVar1, pVar2, pVarD );
|
||||
// stop collecting the affected vars and cubes
|
||||
Fxu_MatrixRingCubesStop( p );
|
||||
Fxu_MatrixRingVarsStop( p );
|
||||
|
||||
// add the literals to the new cube
|
||||
assert( pVar1->iVar < pVar2->iVar );
|
||||
assert( Fxu_SingleCountCoincidence( p, pVar1, pVar2 ) == 0 );
|
||||
Fxu_MatrixAddLiteral( p, pCubeNew, pVar1 );
|
||||
Fxu_MatrixAddLiteral( p, pCubeNew, pVar2 );
|
||||
|
||||
// create new doubles; we cannot add them in the same loop
|
||||
// because we first have to create *all* new cubes for each node
|
||||
Fxu_MatrixForEachCubeInRing( p, pCube )
|
||||
Fxu_UpdateAddNewDoubles( p, pCube );
|
||||
// update the singles after removing some literals
|
||||
Fxu_UpdateCleanOldSingles( p );
|
||||
// we should undo the rings before creating new singles
|
||||
|
||||
// unmark the cubes
|
||||
Fxu_MatrixRingCubesUnmark( p );
|
||||
Fxu_MatrixRingVarsUnmark( p );
|
||||
|
||||
// create new singles
|
||||
Fxu_UpdateAddNewSingles( p, pVarC );
|
||||
Fxu_UpdateAddNewSingles( p, pVarD );
|
||||
p->nDivs1++;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Updates the matrix after accepting a double cube divisor.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_UpdateDouble( Fxu_Matrix * p )
|
||||
{
|
||||
Fxu_Double * pDiv;
|
||||
Fxu_Cube * pCube, * pCubeNew1, * pCubeNew2;
|
||||
Fxu_Var * pVarC, * pVarD;
|
||||
|
||||
// remove the best divisor from the heap
|
||||
pDiv = Fxu_HeapDoubleGetMax( p->pHeapDouble );
|
||||
// remove the best divisor from the table
|
||||
Fxu_ListTableDelDivisor( p, pDiv );
|
||||
|
||||
// create two new columns (vars)
|
||||
Fxu_UpdateCreateNewVars( p, &pVarC, &pVarD, 2 );
|
||||
// create two new rows (cubes)
|
||||
pCubeNew1 = Fxu_MatrixAddCube( p, pVarD, 0 );
|
||||
pCubeNew1->pFirst = pCubeNew1;
|
||||
pCubeNew2 = Fxu_MatrixAddCube( p, pVarD, 1 );
|
||||
pCubeNew2->pFirst = pCubeNew1;
|
||||
// set the first cube
|
||||
pVarD->pFirst = pCubeNew1;
|
||||
|
||||
// add the literals to the new cubes
|
||||
Fxu_UpdateMatrixDoubleCreateCubes( p, pCubeNew1, pCubeNew2, pDiv );
|
||||
|
||||
// start collecting the affected cubes and vars
|
||||
Fxu_MatrixRingCubesStart( p );
|
||||
Fxu_MatrixRingVarsStart( p );
|
||||
// replace each two cubes of the pair by one new cube
|
||||
// the new cube contains the base and the new literal
|
||||
Fxu_UpdateDoublePairs( p, pDiv, pVarD );
|
||||
// stop collecting the affected cubes and vars
|
||||
Fxu_MatrixRingCubesStop( p );
|
||||
Fxu_MatrixRingVarsStop( p );
|
||||
|
||||
// create new doubles; we cannot add them in the same loop
|
||||
// because we first have to create *all* new cubes for each node
|
||||
Fxu_MatrixForEachCubeInRing( p, pCube )
|
||||
Fxu_UpdateAddNewDoubles( p, pCube );
|
||||
// update the singles after removing some literals
|
||||
Fxu_UpdateCleanOldSingles( p );
|
||||
|
||||
// undo the temporary rings with cubes and vars
|
||||
Fxu_MatrixRingCubesUnmark( p );
|
||||
Fxu_MatrixRingVarsUnmark( p );
|
||||
// we should undo the rings before creating new singles
|
||||
|
||||
// create new singles
|
||||
Fxu_UpdateAddNewSingles( p, pVarC );
|
||||
Fxu_UpdateAddNewSingles( p, pVarD );
|
||||
|
||||
// recycle the divisor
|
||||
MEM_FREE_FXU( p, Fxu_Double, 1, pDiv );
|
||||
p->nDivs2++;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Update the pairs.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_UpdateDoublePairs( Fxu_Matrix * p, Fxu_Double * pDouble, Fxu_Var * pVar )
|
||||
{
|
||||
Fxu_Pair * pPair;
|
||||
Fxu_Cube * pCubeUse, * pCubeRem;
|
||||
int i;
|
||||
|
||||
// collect and sort the pairs
|
||||
Fxu_UpdatePairsSort( p, pDouble );
|
||||
for ( i = 0; i < p->nPairsTemp; i++ )
|
||||
{
|
||||
// get the pair
|
||||
pPair = p->pPairsTemp[i];
|
||||
// out of the two cubes, select the one which comes earlier
|
||||
pCubeUse = Fxu_PairMinCube( pPair );
|
||||
pCubeRem = Fxu_PairMaxCube( pPair );
|
||||
// collect the affected cube
|
||||
assert( pCubeUse->pOrder == NULL );
|
||||
Fxu_MatrixRingCubesAdd( p, pCubeUse );
|
||||
|
||||
// remove some literals from pCubeUse and all literals from pCubeRem
|
||||
Fxu_UpdateMatrixDoubleClean( p, pCubeUse, pCubeRem );
|
||||
// add a literal that depends on the new variable
|
||||
Fxu_MatrixAddLiteral( p, pCubeUse, pVar );
|
||||
// check the literal count
|
||||
assert( pCubeUse->lLits.nItems == pPair->nBase + 1 );
|
||||
assert( pCubeRem->lLits.nItems == 0 );
|
||||
|
||||
// update the divisors by removing useless pairs
|
||||
Fxu_UpdateCleanOldDoubles( p, pDouble, pCubeUse );
|
||||
Fxu_UpdateCleanOldDoubles( p, pDouble, pCubeRem );
|
||||
// remove the pair
|
||||
MEM_FREE_FXU( p, Fxu_Pair, 1, pPair );
|
||||
}
|
||||
p->nPairsTemp = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Add two cubes corresponding to the given double-cube divisor.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_UpdateMatrixDoubleCreateCubes( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2, Fxu_Double * pDiv )
|
||||
{
|
||||
Fxu_Lit * pLit1, * pLit2;
|
||||
Fxu_Pair * pPair;
|
||||
int nBase, nLits1, nLits2;
|
||||
|
||||
// fill in the SOP and copy the fanins
|
||||
nBase = nLits1 = nLits2 = 0;
|
||||
pPair = pDiv->lPairs.pHead;
|
||||
pLit1 = pPair->pCube1->lLits.pHead;
|
||||
pLit2 = pPair->pCube2->lLits.pHead;
|
||||
while ( 1 )
|
||||
{
|
||||
if ( pLit1 && pLit2 )
|
||||
{
|
||||
if ( pLit1->iVar == pLit2->iVar )
|
||||
{ // skip the cube free part
|
||||
pLit1 = pLit1->pHNext;
|
||||
pLit2 = pLit2->pHNext;
|
||||
nBase++;
|
||||
}
|
||||
else if ( pLit1->iVar < pLit2->iVar )
|
||||
{ // add literal to the first cube
|
||||
Fxu_MatrixAddLiteral( p, pCube1, pLit1->pVar );
|
||||
// move to the next literal in this cube
|
||||
pLit1 = pLit1->pHNext;
|
||||
nLits1++;
|
||||
}
|
||||
else
|
||||
{ // add literal to the second cube
|
||||
Fxu_MatrixAddLiteral( p, pCube2, pLit2->pVar );
|
||||
// move to the next literal in this cube
|
||||
pLit2 = pLit2->pHNext;
|
||||
nLits2++;
|
||||
}
|
||||
}
|
||||
else if ( pLit1 && !pLit2 )
|
||||
{ // add literal to the first cube
|
||||
Fxu_MatrixAddLiteral( p, pCube1, pLit1->pVar );
|
||||
// move to the next literal in this cube
|
||||
pLit1 = pLit1->pHNext;
|
||||
nLits1++;
|
||||
}
|
||||
else if ( !pLit1 && pLit2 )
|
||||
{ // add literal to the second cube
|
||||
Fxu_MatrixAddLiteral( p, pCube2, pLit2->pVar );
|
||||
// move to the next literal in this cube
|
||||
pLit2 = pLit2->pHNext;
|
||||
nLits2++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
assert( pPair->nLits1 == nLits1 );
|
||||
assert( pPair->nLits2 == nLits2 );
|
||||
assert( pPair->nBase == nBase );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Create the node equal to double-cube divisor.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_UpdateMatrixDoubleClean( Fxu_Matrix * p, Fxu_Cube * pCubeUse, Fxu_Cube * pCubeRem )
|
||||
{
|
||||
Fxu_Lit * pLit1, * bLit1Next;
|
||||
Fxu_Lit * pLit2, * bLit2Next;
|
||||
|
||||
// initialize the starting literals
|
||||
pLit1 = pCubeUse->lLits.pHead;
|
||||
pLit2 = pCubeRem->lLits.pHead;
|
||||
bLit1Next = pLit1? pLit1->pHNext: NULL;
|
||||
bLit2Next = pLit2? pLit2->pHNext: NULL;
|
||||
// go through the pair and remove the literals in the base
|
||||
// from the first cube and all literals from the second cube
|
||||
while ( 1 )
|
||||
{
|
||||
if ( pLit1 && pLit2 )
|
||||
{
|
||||
if ( pLit1->iVar == pLit2->iVar )
|
||||
{ // this literal is present in both cubes - it belongs to the base
|
||||
// mark the affected var
|
||||
if ( pLit1->pVar->pOrder == NULL )
|
||||
Fxu_MatrixRingVarsAdd( p, pLit1->pVar );
|
||||
// leave the base in pCubeUse; delete it from pCubeRem
|
||||
Fxu_MatrixDelLiteral( p, pLit2 );
|
||||
// step to the next literals
|
||||
pLit1 = bLit1Next;
|
||||
pLit2 = bLit2Next;
|
||||
bLit1Next = pLit1? pLit1->pHNext: NULL;
|
||||
bLit2Next = pLit2? pLit2->pHNext: NULL;
|
||||
}
|
||||
else if ( pLit1->iVar < pLit2->iVar )
|
||||
{ // this literal is present in pCubeUse - remove it
|
||||
// mark the affected var
|
||||
if ( pLit1->pVar->pOrder == NULL )
|
||||
Fxu_MatrixRingVarsAdd( p, pLit1->pVar );
|
||||
// delete this literal
|
||||
Fxu_MatrixDelLiteral( p, pLit1 );
|
||||
// step to the next literals
|
||||
pLit1 = bLit1Next;
|
||||
bLit1Next = pLit1? pLit1->pHNext: NULL;
|
||||
}
|
||||
else
|
||||
{ // this literal is present in pCubeRem - remove it
|
||||
// mark the affected var
|
||||
if ( pLit2->pVar->pOrder == NULL )
|
||||
Fxu_MatrixRingVarsAdd( p, pLit2->pVar );
|
||||
// delete this literal
|
||||
Fxu_MatrixDelLiteral( p, pLit2 );
|
||||
// step to the next literals
|
||||
pLit2 = bLit2Next;
|
||||
bLit2Next = pLit2? pLit2->pHNext: NULL;
|
||||
}
|
||||
}
|
||||
else if ( pLit1 && !pLit2 )
|
||||
{ // this literal is present in pCubeUse - leave it
|
||||
// mark the affected var
|
||||
if ( pLit1->pVar->pOrder == NULL )
|
||||
Fxu_MatrixRingVarsAdd( p, pLit1->pVar );
|
||||
// delete this literal
|
||||
Fxu_MatrixDelLiteral( p, pLit1 );
|
||||
// step to the next literals
|
||||
pLit1 = bLit1Next;
|
||||
bLit1Next = pLit1? pLit1->pHNext: NULL;
|
||||
}
|
||||
else if ( !pLit1 && pLit2 )
|
||||
{ // this literal is present in pCubeRem - remove it
|
||||
// mark the affected var
|
||||
if ( pLit2->pVar->pOrder == NULL )
|
||||
Fxu_MatrixRingVarsAdd( p, pLit2->pVar );
|
||||
// delete this literal
|
||||
Fxu_MatrixDelLiteral( p, pLit2 );
|
||||
// step to the next literals
|
||||
pLit2 = bLit2Next;
|
||||
bLit2Next = pLit2? pLit2->pHNext: NULL;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Updates the matrix after selecting a single cube divisor.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_UpdateMatrixSingleClean( Fxu_Matrix * p, Fxu_Var * pVar1, Fxu_Var * pVar2, Fxu_Var * pVarNew )
|
||||
{
|
||||
Fxu_Lit * pLit1, * bLit1Next;
|
||||
Fxu_Lit * pLit2, * bLit2Next;
|
||||
|
||||
// initialize the starting literals
|
||||
pLit1 = pVar1->lLits.pHead;
|
||||
pLit2 = pVar2->lLits.pHead;
|
||||
bLit1Next = pLit1? pLit1->pVNext: NULL;
|
||||
bLit2Next = pLit2? pLit2->pVNext: NULL;
|
||||
while ( 1 )
|
||||
{
|
||||
if ( pLit1 && pLit2 )
|
||||
{
|
||||
if ( pLit1->pCube->pVar->iVar == pLit2->pCube->pVar->iVar )
|
||||
{ // these literals coincide
|
||||
if ( pLit1->iCube == pLit2->iCube )
|
||||
{ // these literals coincide
|
||||
|
||||
// collect the affected cube
|
||||
assert( pLit1->pCube->pOrder == NULL );
|
||||
Fxu_MatrixRingCubesAdd( p, pLit1->pCube );
|
||||
|
||||
// add the literal to this cube corresponding to the new column
|
||||
Fxu_MatrixAddLiteral( p, pLit1->pCube, pVarNew );
|
||||
// clean the old cubes
|
||||
Fxu_UpdateCleanOldDoubles( p, NULL, pLit1->pCube );
|
||||
|
||||
// remove the literals
|
||||
Fxu_MatrixDelLiteral( p, pLit1 );
|
||||
Fxu_MatrixDelLiteral( p, pLit2 );
|
||||
|
||||
// go to the next literals
|
||||
pLit1 = bLit1Next;
|
||||
pLit2 = bLit2Next;
|
||||
bLit1Next = pLit1? pLit1->pVNext: NULL;
|
||||
bLit2Next = pLit2? pLit2->pVNext: NULL;
|
||||
}
|
||||
else if ( pLit1->iCube < pLit2->iCube )
|
||||
{
|
||||
pLit1 = bLit1Next;
|
||||
bLit1Next = pLit1? pLit1->pVNext: NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
pLit2 = bLit2Next;
|
||||
bLit2Next = pLit2? pLit2->pVNext: NULL;
|
||||
}
|
||||
}
|
||||
else if ( pLit1->pCube->pVar->iVar < pLit2->pCube->pVar->iVar )
|
||||
{
|
||||
pLit1 = bLit1Next;
|
||||
bLit1Next = pLit1? pLit1->pVNext: NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
pLit2 = bLit2Next;
|
||||
bLit2Next = pLit2? pLit2->pVNext: NULL;
|
||||
}
|
||||
}
|
||||
else if ( pLit1 && !pLit2 )
|
||||
{
|
||||
pLit1 = bLit1Next;
|
||||
bLit1Next = pLit1? pLit1->pVNext: NULL;
|
||||
}
|
||||
else if ( !pLit1 && pLit2 )
|
||||
{
|
||||
pLit2 = bLit2Next;
|
||||
bLit2Next = pLit2? pLit2->pVNext: NULL;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sort the pairs.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_UpdatePairsSort( Fxu_Matrix * p, Fxu_Double * pDouble )
|
||||
{
|
||||
Fxu_Pair * pPair;
|
||||
// order the pairs by the first cube to ensure that
|
||||
// new literals are added to the matrix from top to bottom
|
||||
// collect pairs into the array
|
||||
p->nPairsTemp = 0;
|
||||
Fxu_DoubleForEachPair( pDouble, pPair )
|
||||
p->pPairsTemp[ p->nPairsTemp++ ] = pPair;
|
||||
if ( p->nPairsTemp > 1 )
|
||||
{ // sort
|
||||
qsort( (void *)p->pPairsTemp, p->nPairsTemp, sizeof(Fxu_Pair *),
|
||||
(int (*)(const void *, const void *)) Fxu_UpdatePairCompare );
|
||||
assert( Fxu_UpdatePairCompare( p->pPairsTemp, p->pPairsTemp + p->nPairsTemp - 1 ) < 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Compares the vars by their number.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Fxu_UpdatePairCompare( Fxu_Pair ** ppP1, Fxu_Pair ** ppP2 )
|
||||
{
|
||||
Fxu_Cube * pC1 = (*ppP1)->pCube1;
|
||||
Fxu_Cube * pC2 = (*ppP2)->pCube1;
|
||||
int iP1CubeMin, iP2CubeMin;
|
||||
if ( pC1->pVar->iVar < pC2->pVar->iVar )
|
||||
return -1;
|
||||
if ( pC1->pVar->iVar > pC2->pVar->iVar )
|
||||
return 1;
|
||||
iP1CubeMin = Fxu_PairMinCubeInt( *ppP1 );
|
||||
iP2CubeMin = Fxu_PairMinCubeInt( *ppP2 );
|
||||
if ( iP1CubeMin < iP2CubeMin )
|
||||
return -1;
|
||||
if ( iP1CubeMin > iP2CubeMin )
|
||||
return 1;
|
||||
assert( 0 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Create new variables.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_UpdateCreateNewVars( Fxu_Matrix * p, Fxu_Var ** ppVarC, Fxu_Var ** ppVarD, int nCubes )
|
||||
{
|
||||
Fxu_Var * pVarC, * pVarD;
|
||||
|
||||
// add a new column for the complement
|
||||
pVarC = Fxu_MatrixAddVar( p );
|
||||
pVarC->nCubes = 0;
|
||||
// add a new column for the divisor
|
||||
pVarD = Fxu_MatrixAddVar( p );
|
||||
pVarD->nCubes = nCubes;
|
||||
|
||||
// mark this entry in the Value2Node array
|
||||
// assert( p->pValue2Node[pVarC->iVar] > 0 );
|
||||
// p->pValue2Node[pVarD->iVar ] = p->pValue2Node[pVarC->iVar];
|
||||
// p->pValue2Node[pVarD->iVar+1] = p->pValue2Node[pVarC->iVar]+1;
|
||||
|
||||
*ppVarC = pVarC;
|
||||
*ppVarD = pVarD;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_UpdateCleanOldDoubles( Fxu_Matrix * p, Fxu_Double * pDiv, Fxu_Cube * pCube )
|
||||
{
|
||||
Fxu_Double * pDivCur;
|
||||
Fxu_Pair * pPair;
|
||||
int i;
|
||||
|
||||
// if the cube is a recently introduced one
|
||||
// it does not have pairs allocated
|
||||
// in this case, there is nothing to update
|
||||
if ( pCube->pVar->ppPairs == NULL )
|
||||
return;
|
||||
|
||||
// go through all the pairs of this cube
|
||||
Fxu_CubeForEachPair( pCube, pPair, i )
|
||||
{
|
||||
// get the divisor of this pair
|
||||
pDivCur = pPair->pDiv;
|
||||
// skip the current divisor
|
||||
if ( pDivCur == pDiv )
|
||||
continue;
|
||||
// remove this pair
|
||||
Fxu_ListDoubleDelPair( pDivCur, pPair );
|
||||
// the divisor may have become useless by now
|
||||
if ( pDivCur->lPairs.nItems == 0 )
|
||||
{
|
||||
assert( pDivCur->Weight == pPair->nBase - 1 );
|
||||
Fxu_HeapDoubleDelete( p->pHeapDouble, pDivCur );
|
||||
Fxu_MatrixDelDivisor( p, pDivCur );
|
||||
}
|
||||
else
|
||||
{
|
||||
// update the divisor's weight
|
||||
pDivCur->Weight -= pPair->nLits1 + pPair->nLits2 - 1 + pPair->nBase;
|
||||
Fxu_HeapDoubleUpdate( p->pHeapDouble, pDivCur );
|
||||
}
|
||||
MEM_FREE_FXU( p, Fxu_Pair, 1, pPair );
|
||||
}
|
||||
// finally erase all the pair info associated with this cube
|
||||
Fxu_PairClearStorage( pCube );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds the new divisors that depend on the cube.]
|
||||
|
||||
Description [Go through all the non-empty cubes of this cover
|
||||
(except the given cube) and, for each of them, add the new divisor
|
||||
with the given cube.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_UpdateAddNewDoubles( Fxu_Matrix * p, Fxu_Cube * pCube )
|
||||
{
|
||||
Fxu_Cube * pTemp;
|
||||
assert( pCube->pOrder );
|
||||
|
||||
// if the cube is a recently introduced one
|
||||
// it does not have pairs allocated
|
||||
// in this case, there is nothing to update
|
||||
if ( pCube->pVar->ppPairs == NULL )
|
||||
return;
|
||||
|
||||
for ( pTemp = pCube->pFirst; pTemp->pVar == pCube->pVar; pTemp = pTemp->pNext )
|
||||
{
|
||||
// do not add pairs with the empty cubes
|
||||
if ( pTemp->lLits.nItems == 0 )
|
||||
continue;
|
||||
// to prevent adding duplicated pairs of the new cubes
|
||||
// do not add the pair, if the current cube is marked
|
||||
if ( pTemp->pOrder && pTemp >= pCube )
|
||||
continue;
|
||||
Fxu_MatrixAddDivisor( p, pTemp, pCube );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Removes old single cube divisors.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_UpdateCleanOldSingles( Fxu_Matrix * p )
|
||||
{
|
||||
Fxu_Single * pSingle, * pSingle2;
|
||||
int WeightNew;
|
||||
|
||||
Fxu_MatrixForEachSingleSafe( p, pSingle, pSingle2 )
|
||||
{
|
||||
// if at least one of the variables is marked, recalculate
|
||||
if ( pSingle->pVar1->pOrder || pSingle->pVar2->pOrder )
|
||||
{
|
||||
// get the new weight
|
||||
WeightNew = -2 + Fxu_SingleCountCoincidence( p, pSingle->pVar1, pSingle->pVar2 );
|
||||
if ( WeightNew >= 0 )
|
||||
{
|
||||
pSingle->Weight = WeightNew;
|
||||
Fxu_HeapSingleUpdate( p->pHeapSingle, pSingle );
|
||||
}
|
||||
else
|
||||
{
|
||||
Fxu_HeapSingleDelete( p->pHeapSingle, pSingle );
|
||||
Fxu_ListMatrixDelSingle( p, pSingle );
|
||||
MEM_FREE_FXU( p, Fxu_Single, 1, pSingle );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Updates the single cube divisors.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Fxu_UpdateAddNewSingles( Fxu_Matrix * p, Fxu_Var * pVar )
|
||||
{
|
||||
Fxu_MatrixComputeSinglesOne( p, pVar );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
SRC += fxu.c \
|
||||
fxuCreate.c \
|
||||
fxuHeapD.c \
|
||||
fxuHeapS.c \
|
||||
fxuList.c \
|
||||
fxuMatrix.c \
|
||||
fxuPair.c \
|
||||
fxuPrint.c \
|
||||
fxuReduce.c \
|
||||
fxuSelect.c \
|
||||
fxuSingle.c \
|
||||
fxuUpdate.c
|
||||
Loading…
Reference in New Issue