Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F27032846
exor.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Authored By
Unknown
Size
33 KB
Referenced Files
None
Subscribers
None
exor.cpp
View Options
/**CFile****************************************************************
FileName [exor.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Exclusive sum-of-product minimization.]
Synopsis [Main procedure.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: exor.c,v 1.0 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
////////////////////////////////////////////////////////////////////////
/// ///
/// Implementation of EXORCISM - 4 ///
/// An Exclusive Sum-of-Product Minimizer ///
/// Alan Mishchenko <alanmi@ee.pdx.edu> ///
/// ///
////////////////////////////////////////////////////////////////////////
/// ///
/// Main Module ///
/// ESOP Minimization Task Coordinator ///
/// ///
/// 1) interprets command line ///
/// 2) calls the approapriate reading procedure ///
/// 3) calls the minimization module ///
/// ///
/// Ver. 1.0. Started - July 18, 2000. Last update - July 20, 2000 ///
/// Ver. 1.1. Started - July 24, 2000. Last update - July 29, 2000 ///
/// Ver. 1.4. Started - Aug 10, 2000. Last update - Aug 26, 2000 ///
/// Ver. 1.6. Started - Sep 11, 2000. Last update - Sep 15, 2000 ///
/// Ver. 1.7. Started - Sep 20, 2000. Last update - Sep 23, 2000 ///
/// ///
////////////////////////////////////////////////////////////////////////
/// This software was tested with the BDD package "CUDD", v.2.3.0 ///
/// by Fabio Somenzi ///
/// http://vlsi.colorado.edu/~fabio/ ///
////////////////////////////////////////////////////////////////////////
#include
"eabc/exor.h"
#include
<cstdint>
#include
<functional>
#include
<cstdint>
namespace
abc
::
exorcism
{
///////////////////////////////////////////////////////////////////////
/// GLOBAL VARIABLES ///
////////////////////////////////////////////////////////////////////////
// information about the cube cover
cinfo
g_CoverInfo
;
extern
int
s_fDecreaseLiterals
;
////////////////////////////////////////////////////////////////////////
/// EXTERNAL FUNCTIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION main() ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Number of negative literals.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
/*
static int QCost[16][16] =
{
{ 1}, // 0
{ 1, 2}, // 1
{ 5, 5, 6}, // 2
{ 14, 14, 16, 18}, // 3
{ 20, 20, 20, 22, 24}, // 4
{ 32, 32, 32, 34, 36, 38}, // 5
{ 44, 44, 44, 44, 46, 48, 50}, // 6
{ 56, 56, 56, 56, 58, 60, 62, 64}, // 7
{ 0 }
};
*/
int
GetQCost
(
int
nVars
,
int
nNegs
)
{
int
Extra
;
assert
(
nVars
>=
nNegs
);
if
(
nVars
==
0
)
return
1
;
if
(
nVars
==
1
)
{
if
(
nNegs
==
0
)
return
1
;
if
(
nNegs
==
1
)
return
2
;
}
if
(
nVars
==
2
)
{
if
(
nNegs
<=
1
)
return
5
;
if
(
nNegs
==
2
)
return
6
;
}
if
(
nVars
==
3
)
{
if
(
nNegs
<=
1
)
return
14
;
if
(
nNegs
==
2
)
return
16
;
if
(
nNegs
==
3
)
return
18
;
}
Extra
=
nNegs
-
nVars
/
2
;
return
20
+
12
*
(
nVars
-
4
)
+
(
Extra
>
0
?
2
*
Extra
:
0
);
}
void
GetQCostTest
()
{
int
i
,
k
,
Limit
=
10
;
for
(
i
=
0
;
i
<
Limit
;
i
++
)
{
for
(
k
=
0
;
k
<=
i
;
k
++
)
printf
(
"%4d "
,
GetQCost
(
i
,
k
)
);
printf
(
"
\n
"
);
}
}
int
ComputeQCost
(
Vec_Int_t
*
vCube
)
{
int
i
,
Entry
,
nLitsN
=
0
;
Vec_IntForEachEntry
(
vCube
,
Entry
,
i
)
nLitsN
+=
Abc_LitIsCompl
(
Entry
);
return
GetQCost
(
Vec_IntSize
(
vCube
),
nLitsN
);
}
int
ComputeQCostBits
(
Cube
*
p
)
{
extern
varvalue
GetVar
(
Cube
*
pC
,
int
Var
);
int
v
,
nLits
=
0
,
nLitsN
=
0
;
for
(
v
=
0
;
v
<
g_CoverInfo
.
nVarsIn
;
v
++
)
{
int
Value
=
GetVar
(
p
,
v
);
if
(
Value
==
VAR_NEG
)
nLitsN
++
;
else
if
(
Value
==
VAR_POS
)
nLits
++
;
}
nLits
+=
nLitsN
;
return
GetQCost
(
nLits
,
nLitsN
);
}
int
ToffoliGateCount
(
int
controls
,
int
lines
)
{
switch
(
controls
)
{
case
0u
:
case
1u
:
return
0
;
break
;
case
2u
:
return
1
;
break
;
case
3u
:
return
4
;
break
;
case
4u
:
return
(
(
(
lines
+
1
)
/
2
)
>=
controls
)
?
8
:
10
;
break
;
default
:
return
(
(
(
lines
+
1
)
/
2
)
>=
controls
)
?
4
*
(
controls
-
2
)
:
8
*
(
controls
-
3
);
}
}
int
ComputeQCostTcount
(
Vec_Int_t
*
vCube
)
{
return
7
*
ToffoliGateCount
(
Vec_IntSize
(
vCube
),
g_CoverInfo
.
nVarsIn
+
1
);
}
int
ComputeQCostTcountBits
(
Cube
*
p
)
{
extern
varvalue
GetVar
(
Cube
*
pC
,
int
Var
);
int
v
,
nLits
=
0
;
for
(
v
=
0
;
v
<
g_CoverInfo
.
nVarsIn
;
v
++
)
if
(
GetVar
(
p
,
v
)
!=
VAR_ABS
)
nLits
++
;
return
7
*
ToffoliGateCount
(
nLits
,
g_CoverInfo
.
nVarsIn
+
1
);
/* maybe just: 7 * ToffoliGateCount( p->a, g_CoverInfo.nVarsIn + 1 ); */
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
ReduceEsopCover
()
{
///////////////////////////////////////////////////////////////
// SIMPLIFICATION
////////////////////////////////////////////////////////////////////
int
nIterWithoutImprovement
=
0
;
int
nIterCount
=
0
;
int
GainTotal
;
int
z
;
do
{
//START:
if
(
g_CoverInfo
.
Verbosity
==
2
)
printf
(
"
\n
ITERATION #%d
\n\n
"
,
++
nIterCount
);
else
if
(
g_CoverInfo
.
Verbosity
==
1
)
printf
(
"."
);
GainTotal
=
0
;
GainTotal
+=
IterativelyApplyExorLink2
(
1
|
2
|
0
);
GainTotal
+=
IterativelyApplyExorLink3
(
1
|
2
|
0
);
GainTotal
+=
IterativelyApplyExorLink2
(
1
|
2
|
0
);
GainTotal
+=
IterativelyApplyExorLink3
(
1
|
2
|
0
);
GainTotal
+=
IterativelyApplyExorLink2
(
1
|
2
|
0
);
GainTotal
+=
IterativelyApplyExorLink3
(
1
|
2
|
0
);
GainTotal
+=
IterativelyApplyExorLink2
(
1
|
2
|
0
);
GainTotal
+=
IterativelyApplyExorLink3
(
1
|
2
|
0
);
GainTotal
+=
IterativelyApplyExorLink2
(
1
|
2
|
0
);
GainTotal
+=
IterativelyApplyExorLink3
(
1
|
2
|
0
);
GainTotal
+=
IterativelyApplyExorLink2
(
1
|
2
|
0
);
GainTotal
+=
IterativelyApplyExorLink3
(
1
|
2
|
0
);
if
(
nIterWithoutImprovement
>
(
int
)(
g_CoverInfo
.
Quality
>
0
)
)
{
GainTotal
+=
IterativelyApplyExorLink2
(
1
|
2
|
0
);
GainTotal
+=
IterativelyApplyExorLink3
(
1
|
2
|
0
);
GainTotal
+=
IterativelyApplyExorLink2
(
1
|
2
|
4
);
GainTotal
+=
IterativelyApplyExorLink3
(
1
|
2
|
4
);
GainTotal
+=
IterativelyApplyExorLink2
(
1
|
2
|
4
);
GainTotal
+=
IterativelyApplyExorLink4
(
1
|
2
|
4
);
GainTotal
+=
IterativelyApplyExorLink2
(
1
|
2
|
4
);
GainTotal
+=
IterativelyApplyExorLink4
(
1
|
2
|
0
);
GainTotal
+=
IterativelyApplyExorLink2
(
1
|
2
|
0
);
GainTotal
+=
IterativelyApplyExorLink3
(
1
|
2
|
0
);
GainTotal
+=
IterativelyApplyExorLink2
(
1
|
2
|
4
);
GainTotal
+=
IterativelyApplyExorLink3
(
1
|
2
|
4
);
GainTotal
+=
IterativelyApplyExorLink2
(
1
|
2
|
4
);
GainTotal
+=
IterativelyApplyExorLink4
(
1
|
2
|
4
);
GainTotal
+=
IterativelyApplyExorLink2
(
1
|
2
|
4
);
GainTotal
+=
IterativelyApplyExorLink4
(
1
|
2
|
0
);
}
if
(
GainTotal
)
nIterWithoutImprovement
=
0
;
else
nIterWithoutImprovement
++
;
// if ( g_CoverInfo.Quality >= 2 && nIterWithoutImprovement == 2 )
// s_fDecreaseLiterals = 1;
}
while
(
nIterWithoutImprovement
<
1
+
g_CoverInfo
.
Quality
);
// improve the literal count
s_fDecreaseLiterals
=
1
;
for
(
z
=
0
;
z
<
1
;
z
++
)
{
if
(
g_CoverInfo
.
Verbosity
==
2
)
printf
(
"
\n
ITERATION #%d
\n\n
"
,
++
nIterCount
);
else
if
(
g_CoverInfo
.
Verbosity
==
1
)
printf
(
"."
);
GainTotal
=
0
;
GainTotal
+=
IterativelyApplyExorLink2
(
1
|
2
|
0
);
GainTotal
+=
IterativelyApplyExorLink3
(
1
|
2
|
0
);
GainTotal
+=
IterativelyApplyExorLink2
(
1
|
2
|
0
);
GainTotal
+=
IterativelyApplyExorLink3
(
1
|
2
|
0
);
GainTotal
+=
IterativelyApplyExorLink2
(
1
|
2
|
0
);
GainTotal
+=
IterativelyApplyExorLink3
(
1
|
2
|
0
);
GainTotal
+=
IterativelyApplyExorLink2
(
1
|
2
|
0
);
GainTotal
+=
IterativelyApplyExorLink3
(
1
|
2
|
0
);
GainTotal
+=
IterativelyApplyExorLink2
(
1
|
2
|
0
);
GainTotal
+=
IterativelyApplyExorLink3
(
1
|
2
|
0
);
// if ( GainTotal )
// {
// nIterWithoutImprovement = 0;
// goto START;
// }
}
/* ////////////////////////////////////////////////////////////////////
// Print statistics
printf( "\nShallow simplification time is ";
cout << (float)(clk2 - clk1)/(float)(CLOCKS_PER_SEC) << " sec\n" );
printf( "Deep simplification time is ";
cout << (float)(Abc_Clock() - clk2)/(float)(CLOCKS_PER_SEC) << " sec\n" );
printf( "Cover after iterative simplification = " << s_nCubesInUse << endl;
printf( "Reduced by initial cube writing = " << g_CoverInfo.nCubesBefore-nCubesAfterWriting << endl;
printf( "Reduced by shallow simplification = " << nCubesAfterWriting-nCubesAfterShallow << endl;
printf( "Reduced by deep simplification = " << nCubesAfterWriting-s_nCubesInUse << endl;
// printf( "\nThe total number of cubes created = " << g_CoverInfo.cIDs << endl;
// printf( "Total number of places in a queque = " << s_nPosAlloc << endl;
// printf( "Minimum free places in queque-2 = " << s_nPosMax[0] << endl;
// printf( "Minimum free places in queque-3 = " << s_nPosMax[1] << endl;
// printf( "Minimum free places in queque-4 = " << s_nPosMax[2] << endl;
*/
////////////////////////////////////////////////////////////////////
// write the number of cubes into cover information
assert
(
g_CoverInfo
.
nCubesInUse
+
g_CoverInfo
.
nCubesFree
==
g_CoverInfo
.
nCubesAlloc
);
// printf( "\nThe output cover is\n" );
// PrintCoverDebug( cout );
return
0
;
}
//////////////////////////////////////////////////////////////////
// quite a good script
//////////////////////////////////////////////////////////////////
/*
long clk1 = Abc_Clock();
int nIterWithoutImprovement = 0;
do
{
PrintQuequeStats();
GainTotal = 0;
GainTotal += IterativelyApplyExorLink( DIST2, 0|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 0|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
if ( nIterWithoutImprovement > 2 )
{
GainTotal += IterativelyApplyExorLink( DIST2, 0|0|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 0|2|4 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|0 );
}
if ( nIterWithoutImprovement > 6 )
{
GainTotal += IterativelyApplyExorLink( DIST2, 0|0|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 0|0|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 0|0|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|0 );
}
if ( GainTotal )
nIterWithoutImprovement = 0;
else
nIterWithoutImprovement++;
}
while ( nIterWithoutImprovement < 12 );
nCubesAfterShallow = s_nCubesInUse;
*/
/*
// alu4 - 439
long clk1 = Abc_Clock();
int nIterWithoutImprovement = 0;
do
{
PrintQuequeStats();
GainTotal = 0;
GainTotal += IterativelyApplyExorLink( DIST2, 1|0|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
if ( nIterWithoutImprovement > 2 )
{
GainTotal += IterativelyApplyExorLink( DIST2, 0|0|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 0|2|4 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|0 );
}
if ( nIterWithoutImprovement > 6 )
{
GainTotal += IterativelyApplyExorLink( DIST2, 0|0|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 0|0|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 0|0|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|0 );
}
if ( GainTotal )
nIterWithoutImprovement = 0;
else
nIterWithoutImprovement++;
}
while ( nIterWithoutImprovement < 12 );
*/
/*
// alu4 - 412 cubes, 700 sec
long clk1 = Abc_Clock();
int nIterWithoutImprovement = 0;
int nIterCount = 0;
do
{
printf( "\nITERATION #" << ++nIterCount << endl << endl;
GainTotal = 0;
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
if ( nIterWithoutImprovement > 3 )
{
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|4 );
GainTotal += IterativelyApplyExorLink2( 1|2|4 );
GainTotal += IterativelyApplyExorLink3( 1|2|4 );
GainTotal += IterativelyApplyExorLink4( 1|2|4 );
GainTotal += IterativelyApplyExorLink3( 1|2|4 );
GainTotal += IterativelyApplyExorLink4( 1|2|4 );
}
if ( nIterWithoutImprovement > 7 )
{
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
GainTotal += IterativelyApplyExorLink2( 1|2|4 );
GainTotal += IterativelyApplyExorLink3( 1|2|4 );
GainTotal += IterativelyApplyExorLink3( 1|2|4 );
GainTotal += IterativelyApplyExorLink4( 1|2|4 );
GainTotal += IterativelyApplyExorLink4( 1|2|4 );
GainTotal += IterativelyApplyExorLink4( 1|2|4 );
GainTotal += IterativelyApplyExorLink3( 1|2|4 );
GainTotal += IterativelyApplyExorLink4( 1|2|4 );
GainTotal += IterativelyApplyExorLink4( 1|2|4 );
GainTotal += IterativelyApplyExorLink4( 1|2|4 );
}
if ( GainTotal )
nIterWithoutImprovement = 0;
else
nIterWithoutImprovement++;
}
while ( nIterWithoutImprovement < 12 );
*/
/*
// pretty good script
// alu4 = 424 in 250 sec
long clk1 = Abc_Clock();
int nIterWithoutImprovement = 0;
int nIterCount = 0;
do
{
printf( "\nITERATION #" << ++nIterCount << " |";
for ( int k = 0; k < nIterWithoutImprovement; k++ )
printf( "*";
for ( ; k < 11; k++ )
printf( "_";
printf( "|" << endl << endl;
GainTotal = 0;
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
if ( nIterWithoutImprovement > 2 )
{
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|4 );
}
if ( nIterWithoutImprovement > 4 )
{
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|4 );
}
if ( GainTotal )
nIterWithoutImprovement = 0;
else
nIterWithoutImprovement++;
}
while ( nIterWithoutImprovement < 7 );
*/
/*
alu4 = 435 70 secs
long clk1 = Abc_Clock();
int nIterWithoutImprovement = 0;
int nIterCount = 0;
do
{
printf( "\nITERATION #" << ++nIterCount << endl << endl;
GainTotal = 0;
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
if ( GainTotal )
nIterWithoutImprovement = 0;
else
nIterWithoutImprovement++;
}
while ( nIterWithoutImprovement < 4 );
*/
/*
// the best previous
long clk1 = Abc_Clock();
int nIterWithoutImprovement = 0;
int nIterCount = 0;
int GainTotal;
do
{
if ( g_CoverInfo.Verbosity == 2 )
printf( "\nITERATION #" << ++nIterCount << endl << endl;
else if ( g_CoverInfo.Verbosity == 1 )
cout << '.';
GainTotal = 0;
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
if ( nIterWithoutImprovement > 1 )
{
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|0 );
}
if ( GainTotal )
nIterWithoutImprovement = 0;
else
nIterWithoutImprovement++;
}
// while ( nIterWithoutImprovement < 20 );
// while ( nIterWithoutImprovement < 7 );
while ( nIterWithoutImprovement < 1 + g_CoverInfo.Quality );
*/
/*
// the last tried
long clk1 = Abc_Clock();
int nIterWithoutImprovement = 0;
int nIterCount = 0;
int GainTotal;
do
{
if ( g_CoverInfo.Verbosity == 2 )
printf( "\nITERATION #" << ++nIterCount << endl << endl;
else if ( g_CoverInfo.Verbosity == 1 )
cout << '.';
GainTotal = 0;
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
if ( nIterWithoutImprovement > (int)(g_CoverInfo.Quality>0) )
{
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|4 );
GainTotal += IterativelyApplyExorLink2( 1|2|4 );
GainTotal += IterativelyApplyExorLink4( 1|2|4 );
GainTotal += IterativelyApplyExorLink2( 1|2|4 );
GainTotal += IterativelyApplyExorLink4( 1|2|0 );
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|4 );
GainTotal += IterativelyApplyExorLink2( 1|2|4 );
GainTotal += IterativelyApplyExorLink4( 1|2|4 );
GainTotal += IterativelyApplyExorLink2( 1|2|4 );
GainTotal += IterativelyApplyExorLink4( 1|2|0 );
}
if ( GainTotal )
nIterWithoutImprovement = 0;
else
nIterWithoutImprovement++;
}
while ( nIterWithoutImprovement < 1 + g_CoverInfo.Quality );
*/
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void
AddCubesToStartingCover
(
Vec_Wec_t
*
vEsop
)
{
Vec_Int_t
*
vCube
;
Cube
*
pNew
;
int
*
s_Level2Var
;
int
*
s_LevelValues
;
int
c
,
i
,
k
,
Lit
,
Out
;
s_Level2Var
=
ABC_ALLOC
(
int
,
g_CoverInfo
.
nVarsIn
);
s_LevelValues
=
ABC_ALLOC
(
int
,
g_CoverInfo
.
nVarsIn
);
for
(
i
=
0
;
i
<
g_CoverInfo
.
nVarsIn
;
i
++
)
s_Level2Var
[
i
]
=
i
;
g_CoverInfo
.
nLiteralsBefore
=
0
;
g_CoverInfo
.
QCostBefore
=
0
;
Vec_WecForEachLevel
(
vEsop
,
vCube
,
c
)
{
// get the output of this cube
Out
=
-
Vec_IntPop
(
vCube
)
-
1
;
// fill in the cube with blanks
for
(
i
=
0
;
i
<
g_CoverInfo
.
nVarsIn
;
i
++
)
s_LevelValues
[
i
]
=
VAR_ABS
;
Vec_IntForEachEntry
(
vCube
,
Lit
,
k
)
{
if
(
Abc_LitIsCompl
(
Lit
)
)
s_LevelValues
[
Abc_Lit2Var
(
Lit
)]
=
VAR_NEG
;
else
s_LevelValues
[
Abc_Lit2Var
(
Lit
)]
=
VAR_POS
;
}
// get the new cube
pNew
=
GetFreeCube
();
// consider the need to clear the cube
if
(
pNew
->
pCubeDataIn
[
0
]
)
// this is a recycled cube
{
for
(
i
=
0
;
i
<
g_CoverInfo
.
nWordsIn
;
i
++
)
pNew
->
pCubeDataIn
[
i
]
=
0
;
for
(
i
=
0
;
i
<
g_CoverInfo
.
nWordsOut
;
i
++
)
pNew
->
pCubeDataOut
[
i
]
=
0
;
}
InsertVarsWithoutClearing
(
pNew
,
s_Level2Var
,
g_CoverInfo
.
nVarsIn
,
s_LevelValues
,
Out
);
// set literal counts
pNew
->
a
=
Vec_IntSize
(
vCube
);
pNew
->
z
=
1
;
pNew
->
q
=
ComputeQCost
(
vCube
);
// set the ID
pNew
->
ID
=
g_CoverInfo
.
cIDs
++
;
// skip through zero-ID
if
(
g_CoverInfo
.
cIDs
==
256
)
g_CoverInfo
.
cIDs
=
1
;
// add this cube to storage
CheckForCloseCubes
(
pNew
,
1
);
g_CoverInfo
.
nLiteralsBefore
+=
Vec_IntSize
(
vCube
);
g_CoverInfo
.
QCostBefore
+=
ComputeQCost
(
vCube
);
}
ABC_FREE
(
s_Level2Var
);
ABC_FREE
(
s_LevelValues
);
assert
(
g_CoverInfo
.
nCubesInUse
+
g_CoverInfo
.
nCubesFree
==
g_CoverInfo
.
nCubesAlloc
);
}
/**Function*************************************************************
Synopsis [Performs heuristic minimization of ESOPs.]
Description [Returns 1 on success, 0 on failure.]
SideEffects []
SeeAlso []
***********************************************************************/
int
Exorcism
(
Vec_Wec_t
*
vEsop
,
int
nIns
,
int
nOuts
,
std
::
function
<
void
(
uint32_t
,
uint32_t
)
>
const
&
onCube
)
{
abctime
clk1
;
int
RemainderBits
;
int
TotalWords
;
int
MemTemp
,
MemTotal
;
///////////////////////////////////////////////////////////////////////
// STEPS of HEURISTIC ESOP MINIMIZATION
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
// STEP 1: determine the size of the starting cover
///////////////////////////////////////////////////////////////////////
assert
(
nIns
>
0
);
// inputs
RemainderBits
=
(
nIns
*
2
)
%
(
sizeof
(
unsigned
)
*
8
);
TotalWords
=
(
nIns
*
2
)
/
(
sizeof
(
unsigned
)
*
8
)
+
(
RemainderBits
>
0
);
g_CoverInfo
.
nVarsIn
=
nIns
;
g_CoverInfo
.
nWordsIn
=
TotalWords
;
// outputs
RemainderBits
=
(
nOuts
)
%
(
sizeof
(
unsigned
)
*
8
);
TotalWords
=
(
nOuts
)
/
(
sizeof
(
unsigned
)
*
8
)
+
(
RemainderBits
>
0
);
g_CoverInfo
.
nVarsOut
=
nOuts
;
g_CoverInfo
.
nWordsOut
=
TotalWords
;
g_CoverInfo
.
cIDs
=
1
;
// cubes
clk1
=
Abc_Clock
();
// g_CoverInfo.nCubesBefore = CountTermsInPseudoKroneckerCover( g_Func.dd, nOuts );
g_CoverInfo
.
nCubesBefore
=
Vec_WecSize
(
vEsop
);
g_CoverInfo
.
TimeStart
=
Abc_Clock
()
-
clk1
;
if
(
g_CoverInfo
.
Verbosity
)
{
printf
(
"Starting cover generation time is %.2f sec
\n
"
,
TICKS_TO_SECONDS
(
g_CoverInfo
.
TimeStart
)
);
printf
(
"The number of cubes in the starting cover is %d
\n
"
,
g_CoverInfo
.
nCubesBefore
);
}
if
(
g_CoverInfo
.
nCubesBefore
>
g_CoverInfo
.
nCubesMax
)
{
printf
(
"
\n
The size of the starting cover is more than %d cubes. Quitting...
\n
"
,
g_CoverInfo
.
nCubesMax
);
return
0
;
}
///////////////////////////////////////////////////////////////////////
// STEP 2: prepare internal data structures
///////////////////////////////////////////////////////////////////////
g_CoverInfo
.
nCubesAlloc
=
g_CoverInfo
.
nCubesBefore
+
ADDITIONAL_CUBES
;
// allocate cube cover
MemTotal
=
0
;
MemTemp
=
AllocateCover
(
g_CoverInfo
.
nCubesAlloc
,
g_CoverInfo
.
nWordsIn
,
g_CoverInfo
.
nWordsOut
);
if
(
MemTemp
==
0
)
{
printf
(
"Unexpected memory allocation problem. Quitting...
\n
"
);
return
0
;
}
else
MemTotal
+=
MemTemp
;
// allocate cube sets
MemTemp
=
AllocateCubeSets
(
g_CoverInfo
.
nVarsIn
,
g_CoverInfo
.
nVarsOut
);
if
(
MemTemp
==
0
)
{
printf
(
"Unexpected memory allocation problem. Quitting...
\n
"
);
return
0
;
}
else
MemTotal
+=
MemTemp
;
// allocate adjacency queques
MemTemp
=
AllocateQueques
(
g_CoverInfo
.
nCubesAlloc
*
g_CoverInfo
.
nCubesAlloc
/
CUBE_PAIR_FACTOR
);
if
(
MemTemp
==
0
)
{
printf
(
"Unexpected memory allocation problem. Quitting...
\n
"
);
return
0
;
}
else
MemTotal
+=
MemTemp
;
if
(
g_CoverInfo
.
Verbosity
)
printf
(
"Dynamically allocated memory is %dK
\n
"
,
MemTotal
/
1000
);
///////////////////////////////////////////////////////////////////////
// STEP 3: write the cube cover into the allocated storage
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
clk1
=
Abc_Clock
();
if
(
g_CoverInfo
.
Verbosity
)
printf
(
"Generating the starting cover...
\n
"
);
AddCubesToStartingCover
(
vEsop
);
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
// STEP 4: iteratively improve the cover
///////////////////////////////////////////////////////////////////////
if
(
g_CoverInfo
.
Verbosity
)
printf
(
"Performing minimization...
\n
"
);
clk1
=
Abc_Clock
();
ReduceEsopCover
();
g_CoverInfo
.
TimeMin
=
Abc_Clock
()
-
clk1
;
// g_Func.TimeMin = (float)(Abc_Clock() - clk1)/(float)(CLOCKS_PER_SEC);
if
(
g_CoverInfo
.
Verbosity
)
{
printf
(
"
\n
Minimization time is %.2f sec
\n
"
,
TICKS_TO_SECONDS
(
g_CoverInfo
.
TimeMin
)
);
printf
(
"
\n
The number of cubes after minimization is %d
\n
"
,
g_CoverInfo
.
nCubesInUse
);
}
///////////////////////////////////////////////////////////////////////
// STEP 5: save the cover into file
///////////////////////////////////////////////////////////////////////
// if option is MULTI_OUTPUT, the output is written into the output file;
// if option is SINGLE_NODE, the output is added to the input file
// and written into the output file; in this case, the minimized nodes is
// also stored in the temporary file "temp.blif" for verification
// create the file name and write the output
extern
Cube
*
IterCubeSetStart
();
extern
Cube
*
IterCubeSetNext
();
extern
varvalue
GetVar
(
Cube
*
pC
,
int
Var
);
{
int
v
;
Cube
*
p
;
for
(
p
=
IterCubeSetStart
();
p
;
p
=
IterCubeSetNext
()
)
{
assert
(
p
->
fMark
==
0
);
// write the input variables
uint32_t
mask
{},
bits
{};
for
(
v
=
0
;
v
<
g_CoverInfo
.
nVarsIn
;
v
++
)
{
int
Value
=
GetVar
(
p
,
v
);
if
(
Value
==
VAR_NEG
)
{
mask
|=
1
<<
v
;
}
else
if
(
Value
==
VAR_POS
)
{
mask
|=
1
<<
v
;
bits
|=
1
<<
v
;
}
else
if
(
Value
==
VAR_ABS
)
{
// do nothing
}
else
assert
(
0
);
}
onCube
(
bits
,
mask
);
}
}
///////////////////////////////////////////////////////////////////////
// STEP 6: delocate memory
///////////////////////////////////////////////////////////////////////
DelocateCubeSets
();
DelocateCover
();
DelocateQueques
();
// return success
return
1
;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int
Abc_ExorcismMain
(
Vec_Wec_t
*
vEsop
,
int
nIns
,
int
nOuts
,
std
::
function
<
void
(
uint32_t
,
uint32_t
)
>
const
&
onCube
,
int
Quality
,
int
Verbosity
,
int
nCubesMax
,
int
fUseQCost
)
{
memset
(
&
g_CoverInfo
,
0
,
sizeof
(
cinfo
)
);
g_CoverInfo
.
Quality
=
Quality
;
g_CoverInfo
.
Verbosity
=
Verbosity
;
g_CoverInfo
.
nCubesMax
=
nCubesMax
;
g_CoverInfo
.
fUseQCost
=
fUseQCost
;
if
(
fUseQCost
)
s_fDecreaseLiterals
=
1
;
if
(
g_CoverInfo
.
Verbosity
)
{
printf
(
"
\n
EXORCISM, Ver.4.7: Exclusive Sum-of-Product Minimizer
\n
"
);
printf
(
"by Alan Mishchenko, Portland State University, July-September 2000
\n\n
"
);
printf
(
"Incoming ESOP has %d inputs, %d outputs, and %d cubes.
\n
"
,
nIns
,
nOuts
,
Vec_WecSize
(
vEsop
)
);
}
PrepareBitSetModule
();
if
(
Exorcism
(
vEsop
,
nIns
,
nOuts
,
onCube
)
==
0
)
{
printf
(
"Something went wrong when minimizing the cover
\n
"
);
return
0
;
}
return
1
;
}
///////////////////////////////////////////////////////////////////
//////////// End of File /////////////////
///////////////////////////////////////////////////////////////////
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Tue, Oct 27, 3:20 PM (15 h, 3 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
405779
Default Alt Text
exor.cpp (33 KB)
Attached To
Mode
R272 SoC_NEM_Synthesis
Attached
Detach File
Event Timeline