Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F27032982
exorLink.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Authored By
Unknown
Size
28 KB
Referenced Files
None
Subscribers
None
exorLink.cpp
View Options
/**CFile****************************************************************
FileName [exorLink.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Exclusive sum-of-product minimization.]
Synopsis [Cube iterators.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: exorLink.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> ///
/// ///
////////////////////////////////////////////////////////////////////////
/// ///
/// Generation of ExorLinked Cubes ///
/// ///
/// Ver. 1.0. Started - July 26, 2000. Last update - July 29, 2000 ///
/// Ver. 1.4. Started - Aug 10, 2000. Last update - Aug 12, 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"
namespace
abc
::
exorcism
{
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
#define LARGE_NUM 1000000
////////////////////////////////////////////////////////////////////////
/// EXTERNAL FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTIONS OF THIS MODULE ///
////////////////////////////////////////////////////////////////////////
int
ExorLinkCubeIteratorStart
(
Cube
**
pGroup
,
Cube
*
pC1
,
Cube
*
pC2
,
cubedist
Dist
);
// this function starts the Exor-Link iterator, which iterates
// through the cube groups starting from the group with min literals
// returns 1 on success, returns 0 if the cubes have wrong distance
int
ExorLinkCubeIteratorNext
(
Cube
**
pGroup
);
// give the next group in the decreasing order of sum of literals
// returns 1 on success, returns 0 if there are no more groups
int
ExorLinkCubeIteratorPick
(
Cube
**
pGroup
,
int
g
);
// gives the group #g in the order in which the groups were given
// during iteration
// returns 1 on success, returns 0 if something g is too large
void
ExorLinkCubeIteratorCleanUp
(
int
fTakeLastGroup
);
// removes the cubes from the store back into the list of free cubes
// if fTakeLastGroup is 0, removes all cubes
// if fTakeLastGroup is 1, does not store the last group
////////////////////////////////////////////////////////////////////////
/// EXTERNAL VARIABLES ///
////////////////////////////////////////////////////////////////////////
// information about the cube cover before
extern
cinfo
g_CoverInfo
;
// new IDs are assigned only when it is known that the cubes are useful
// this is done in ExorLinkCubeIteratorCleanUp();
// the head of the list of free cubes
extern
Cube
*
g_CubesFree
;
extern
byte
BitCount
[];
////////////////////////////////////////////////////////////////////////
/// EXORLINK INFO ///
////////////////////////////////////////////////////////////////////////
const
int
s_ELMax
=
4
;
// ExorLink-2: there are 4 cubes, 2 literals each, combined into 2 groups
// ExorLink-3: there are 12 cubes, 3 literals each, combined into 6 groups
// ExorLink-4: there are 32 cubes, 4 literals each, combined into 24 groups
// ExorLink-5: there are 80 cubes, 5 literals each, combined into 120 groups
// Exorlink-n: there are n*2^(n-1) cubes, n literals each, combined into n! groups
const
int
s_ELnCubes
[
4
]
=
{
4
,
12
,
32
,
80
};
const
int
s_ELnGroups
[
4
]
=
{
2
,
6
,
24
,
120
};
// value sets of cubes X{a0}Y{b0}Z{c0}U{d0} and X{a1}Y{b1}Z{c1}U{d1}
// used to represent the ExorLink cube generation rules
enum
{
vs0
,
vs1
,
vsX
};
// vs0 = 0, // the value set of the first cube
// vs1 = 1, // the value set of the second cube
// vsX = 2 // EXOR of the value sets of the first and second cubes
// representation of ExorLinked cubes
static
int
s_ELCubeRules
[
3
][
32
][
4
]
=
{
{
// ExorLink-2 Cube Generating Rules
// | 0 | 1 | - sections
// |-------|
{
vsX
,
vs0
},
// cube 0 | | |
{
vsX
,
vs1
},
// cube 1 | | 0 |
{
vs0
,
vsX
},
// cube 2 | | |
{
vs1
,
vsX
}
// cube 3 | 0 | |
},
{
// ExorLink-3 Cube Generating Rules
// | 0 | 1 | 2 | - sections
// |-----------|
{
vsX
,
vs0
,
vs0
},
// cube 0 | | | |
{
vsX
,
vs0
,
vs1
},
// cube 1 | | | 0 |
{
vsX
,
vs1
,
vs0
},
// cube 2 | | 0 | |
{
vsX
,
vs1
,
vs1
},
// cube 3 | | 1 | 1 |
{
vs0
,
vsX
,
vs0
},
// cube 4 | | | |
{
vs0
,
vsX
,
vs1
},
// cube 5 | | | 2 |
{
vs1
,
vsX
,
vs0
},
// cube 6 | 0 | | |
{
vs1
,
vsX
,
vs1
},
// cube 7 | 1 | | 3 |
{
vs0
,
vs0
,
vsX
},
// cube 8 | | | |
{
vs0
,
vs1
,
vsX
},
// cube 9 | | 2 | |
{
vs1
,
vs0
,
vsX
},
// cube 10 | 2 | | |
{
vs1
,
vs1
,
vsX
}
// cube 11 | 3 | 3 | |
},
{
// ExorLink-4 Rules Generating Rules
// | 0 | 1 | 2 | 4 | - sections
// |---------------|
{
vsX
,
vs0
,
vs0
,
vs0
},
// cube 0 | | | | |
{
vsX
,
vs0
,
vs0
,
vs1
},
// cube 1 | | | | 0 |
{
vsX
,
vs0
,
vs1
,
vs0
},
// cube 2 | | | 0 | |
{
vsX
,
vs0
,
vs1
,
vs1
},
// cube 3 | | | 1 | 1 |
{
vsX
,
vs1
,
vs0
,
vs0
},
// cube 4 | | 0 | | |
{
vsX
,
vs1
,
vs0
,
vs1
},
// cube 5 | | 1 | | 2 |
{
vsX
,
vs1
,
vs1
,
vs0
},
// cube 6 | | 2 | 2 | |
{
vsX
,
vs1
,
vs1
,
vs1
},
// cube 7 | | 3 | 3 | 3 |
{
vs0
,
vsX
,
vs0
,
vs0
},
// cube 8 | | | | |
{
vs0
,
vsX
,
vs0
,
vs1
},
// cube 9 | | | | 4 |
{
vs0
,
vsX
,
vs1
,
vs0
},
// cube 10 | | | 4 | |
{
vs0
,
vsX
,
vs1
,
vs1
},
// cube 11 | | | 5 | 5 |
{
vs1
,
vsX
,
vs0
,
vs0
},
// cube 12 | 0 | | | |
{
vs1
,
vsX
,
vs0
,
vs1
},
// cube 13 | 1 | | | 6 |
{
vs1
,
vsX
,
vs1
,
vs0
},
// cube 14 | 2 | | 6 | |
{
vs1
,
vsX
,
vs1
,
vs1
},
// cube 15 | 3 | | 7 | 7 |
{
vs0
,
vs0
,
vsX
,
vs0
},
// cube 16 | | | | |
{
vs0
,
vs0
,
vsX
,
vs1
},
// cube 17 | | | | 8 |
{
vs0
,
vs1
,
vsX
,
vs0
},
// cube 18 | | 4 | | |
{
vs0
,
vs1
,
vsX
,
vs1
},
// cube 19 | | 5 | | 9 |
{
vs1
,
vs0
,
vsX
,
vs0
},
// cube 20 | 4 | | | |
{
vs1
,
vs0
,
vsX
,
vs1
},
// cube 21 | 5 | | | 10|
{
vs1
,
vs1
,
vsX
,
vs0
},
// cube 22 | 6 | 6 | | |
{
vs1
,
vs1
,
vsX
,
vs1
},
// cube 23 | 7 | 7 | | 11|
{
vs0
,
vs0
,
vs0
,
vsX
},
// cube 24 | | | | |
{
vs0
,
vs0
,
vs1
,
vsX
},
// cube 25 | | | 8 | |
{
vs0
,
vs1
,
vs0
,
vsX
},
// cube 26 | | 8 | | |
{
vs0
,
vs1
,
vs1
,
vsX
},
// cube 27 | | 9 | 9 | |
{
vs1
,
vs0
,
vs0
,
vsX
},
// cube 28 | 8 | | | |
{
vs1
,
vs0
,
vs1
,
vsX
},
// cube 29 | 9 | | 10| |
{
vs1
,
vs1
,
vs0
,
vsX
},
// cube 30 | 10| 10| | |
{
vs1
,
vs1
,
vs1
,
vsX
}
// cube 31 | 11| 11| 11| |
}
};
// these cubes are combined into groups
static
int
s_ELGroupRules
[
3
][
24
][
4
]
=
{
{
// ExorLink-2 Group Forming Rules
{
0
,
3
},
// group 0 - section 0
{
2
,
1
}
// group 1 - section 1
},
{
// ExorLink-3 Group Forming Rules
{
0
,
6
,
11
},
// group 0 - section 0
{
0
,
7
,
10
},
// group 1
{
4
,
2
,
11
},
// group 2 - section 1
{
4
,
3
,
9
},
// group 3
{
8
,
1
,
7
},
// group 4 - section 2
{
8
,
3
,
5
}
// group 5
},
{
// ExorLink-4 Group Forming Rules
// section 0: (0-12)(1-13)(2-14)(3-15)(4-20)(5-21)(6-22)(7-23)(8-28)(9-29)(10-30)(11-31)
{
0
,
12
,
22
,
31
},
// group 0 // {0,6,11}, // group 0 - section 0
{
0
,
12
,
23
,
30
},
// group 1 // {0,7,10}, // group 1
{
0
,
20
,
14
,
31
},
// group 2 // {4,2,11}, // group 2
{
0
,
20
,
15
,
29
},
// group 3 // {4,3,9}, // group 3
{
0
,
28
,
13
,
23
},
// group 4 // {8,1,7}, // group 4
{
0
,
28
,
15
,
21
},
// group 5 // {8,3,5} // group 5
// section 1: (0-4)(1-5)(2-6)(3-7)(4-18)(5-19)(6-22)(7-23)(8-26)(9-27)(10-30)(11-31)
{
8
,
4
,
22
,
31
},
// group 6
{
8
,
4
,
23
,
30
},
// group 7
{
8
,
18
,
6
,
31
},
// group 8
{
8
,
18
,
7
,
27
},
// group 9
{
8
,
26
,
5
,
23
},
// group 10
{
8
,
26
,
7
,
19
},
// group 11
// section 2: (0-2)(1-3)(2-6)(3-7)(4-10)(5-11)(6-14)(7-15)(8-25)(9-27)(10-29)(11-31)
{
16
,
2
,
14
,
31
},
// group 12
{
16
,
2
,
15
,
29
},
// group 13
{
16
,
10
,
6
,
31
},
// group 14
{
16
,
10
,
7
,
27
},
// group 15
{
16
,
25
,
3
,
15
},
// group 16
{
16
,
25
,
7
,
11
},
// group 17
// section 3: (0-1)(1-3)(2-5)(3-7)(4-9)(5-11)(6-13)(7-15)(8-17)(9-19)(10-21)(11-23)
{
24
,
1
,
13
,
23
},
// group 18
{
24
,
1
,
15
,
21
},
// group 19
{
24
,
9
,
5
,
23
},
// group 20
{
24
,
9
,
7
,
19
},
// group 21
{
24
,
17
,
3
,
15
},
// group 22
{
24
,
17
,
7
,
11
}
// group 23
}
};
// it is assumed that if literals in the first cube, second cube
// and their EXOR are 0 or 1 (as opposed to -), they are written
// into a mask, which is used to count the number of literals in
// the cube groups cubes
//
// below is the set of masks selecting literals belonging
// to the given cube of the group
static
drow
s_CubeLitMasks
[
3
][
32
]
=
{
{
// ExorLink-2 Literal Counting Masks
// v3 v2 v1 v0
// -xBA -xBA -xBA -xBA
// -------------------
0x14
,
// cube 0 <0000 0000 0001 0100> {vsX,vs0}
0x24
,
// cube 1 <0000 0000 0010 0100> {vsX,vs1}
0x41
,
// cube 2 <0000 0000 0100 0001> {vs0,vsX}
0x42
,
// cube 3 <0000 0000 0100 0010> {vs1,vsX}
},
{
// ExorLink-3 Literal Counting Masks
0x114
,
// cube 0 <0000 0001 0001 0100> {vsX,vs0,vs0}
0x214
,
// cube 1 <0000 0010 0001 0100> {vsX,vs0,vs1}
0x124
,
// cube 2 <0000 0001 0010 0100> {vsX,vs1,vs0}
0x224
,
// cube 3 <0000 0010 0010 0100> {vsX,vs1,vs1}
0x141
,
// cube 4 <0000 0001 0100 0001> {vs0,vsX,vs0}
0x241
,
// cube 5 <0000 0010 0100 0001> {vs0,vsX,vs1}
0x142
,
// cube 6 <0000 0001 0100 0010> {vs1,vsX,vs0}
0x242
,
// cube 7 <0000 0010 0100 0010> {vs1,vsX,vs1}
0x411
,
// cube 8 <0000 0100 0001 0001> {vs0,vs0,vsX}
0x421
,
// cube 9 <0000 0100 0010 0001> {vs0,vs1,vsX}
0x412
,
// cube 10 <0000 0100 0001 0010> {vs1,vs0,vsX}
0x422
,
// cube 11 <0000 0100 0010 0010> {vs1,vs1,vsX}
},
{
// ExorLink-4 Literal Counting Masks
0x1114
,
// cube 0 <0001 0001 0001 0100> {vsX,vs0,vs0,vs0}
0x2114
,
// cube 1 <0010 0001 0001 0100> {vsX,vs0,vs0,vs1}
0x1214
,
// cube 2 <0001 0010 0001 0100> {vsX,vs0,vs1,vs0}
0x2214
,
// cube 3 <0010 0010 0001 0100> {vsX,vs0,vs1,vs1}
0x1124
,
// cube 4 <0001 0001 0010 0100> {vsX,vs1,vs0,vs0}
0x2124
,
// cube 5 <0010 0001 0010 0100> {vsX,vs1,vs0,vs1}
0x1224
,
// cube 6 <0001 0010 0010 0100> {vsX,vs1,vs1,vs0}
0x2224
,
// cube 7 <0010 0010 0010 0100> {vsX,vs1,vs1,vs1}
0x1141
,
// cube 8 <0001 0001 0100 0001> {vs0,vsX,vs0,vs0}
0x2141
,
// cube 9 <0010 0001 0100 0001> {vs0,vsX,vs0,vs1}
0x1241
,
// cube 10 <0001 0010 0100 0001> {vs0,vsX,vs1,vs0}
0x2241
,
// cube 11 <0010 0010 0100 0001> {vs0,vsX,vs1,vs1}
0x1142
,
// cube 12 <0001 0001 0100 0010> {vs1,vsX,vs0,vs0}
0x2142
,
// cube 13 <0010 0001 0100 0010> {vs1,vsX,vs0,vs1}
0x1242
,
// cube 14 <0001 0010 0100 0010> {vs1,vsX,vs1,vs0}
0x2242
,
// cube 15 <0010 0010 0100 0010> {vs1,vsX,vs1,vs1}
0x1411
,
// cube 16 <0001 0100 0001 0001> {vs0,vs0,vsX,vs0}
0x2411
,
// cube 17 <0010 0100 0001 0001> {vs0,vs0,vsX,vs1}
0x1421
,
// cube 18 <0001 0100 0010 0001> {vs0,vs1,vsX,vs0}
0x2421
,
// cube 19 <0010 0100 0010 0001> {vs0,vs1,vsX,vs1}
0x1412
,
// cube 20 <0001 0100 0001 0010> {vs1,vs0,vsX,vs0}
0x2412
,
// cube 21 <0010 0100 0001 0010> {vs1,vs0,vsX,vs1}
0x1422
,
// cube 22 <0001 0100 0010 0010> {vs1,vs1,vsX,vs0}
0x2422
,
// cube 23 <0010 0100 0010 0010> {vs1,vs1,vsX,vs1}
0x4111
,
// cube 24 <0100 0001 0001 0001> {vs0,vs0,vs0,vsX}
0x4211
,
// cube 25 <0100 0010 0001 0001> {vs0,vs0,vs1,vsX}
0x4121
,
// cube 26 <0100 0001 0010 0001> {vs0,vs1,vs0,vsX}
0x4221
,
// cube 27 <0100 0010 0010 0001> {vs0,vs1,vs1,vsX}
0x4112
,
// cube 28 <0100 0001 0001 0010> {vs1,vs0,vs0,vsX}
0x4212
,
// cube 29 <0100 0010 0001 0010> {vs1,vs0,vs1,vsX}
0x4122
,
// cube 30 <0100 0001 0010 0010> {vs1,vs1,vs0,vsX}
0x4222
,
// cube 31 <0100 0010 0010 0010> {vs1,vs1,vs1,vsX}
}
};
static
drow
s_BitMasks
[
32
]
=
{
0x00000001
,
0x00000002
,
0x00000004
,
0x00000008
,
0x00000010
,
0x00000020
,
0x00000040
,
0x00000080
,
0x00000100
,
0x00000200
,
0x00000400
,
0x00000800
,
0x00001000
,
0x00002000
,
0x00004000
,
0x00008000
,
0x00010000
,
0x00020000
,
0x00040000
,
0x00080000
,
0x00100000
,
0x00200000
,
0x00400000
,
0x00800000
,
0x01000000
,
0x02000000
,
0x04000000
,
0x08000000
,
0x10000000
,
0x20000000
,
0x40000000
,
0x80000000
};
////////////////////////////////////////////////////////////////////////
/// STATIC VARIABLES ///
////////////////////////////////////////////////////////////////////////
// this flag is TRUE as long as the storage is allocated
static
int
fWorking
;
// set these flags to have minimum literal groups generated first
static
int
fMinLitGroupsFirst
[
4
]
=
{
0
/*dist2*/
,
0
/*dist3*/
,
0
/*dist4*/
};
static
int
nDist
;
static
int
nCubes
;
static
int
nCubesInGroup
;
static
int
nGroups
;
static
Cube
*
pCA
,
*
pCB
;
// storage for variable numbers that are different in the cubes
static
int
DiffVars
[
5
];
static
int
*
pDiffVars
;
static
int
nDifferentVars
;
// storage for the bits and words of different input variables
static
int
nDiffVarsIn
;
static
int
DiffVarWords
[
5
];
static
int
DiffVarBits
[
5
];
// literal mask used to count the number of literals in the cubes
static
drow
MaskLiterals
;
// the base for counting literals
static
int
StartingLiterals
;
// the number of literals in each cube
static
int
CubeLiterals
[
32
];
static
int
BitShift
;
static
int
DiffVarValues
[
4
][
3
];
static
int
Value
;
// the sorted array of groups in the increasing order of costs
static
int
GroupCosts
[
32
];
static
int
GroupCostBest
;
static
int
GroupCostBestNum
;
static
int
CubeNum
;
static
int
NewZ
;
static
drow
Temp
;
// the cubes currently created
static
Cube
*
ELCubes
[
32
];
// the bit string with 1's corresponding to cubes in ELCubes[]
// that constitute the last group
static
drow
LastGroup
;
static
int
GroupOrder
[
24
];
static
drow
VisitedGroups
;
static
int
nVisitedGroups
;
//int RemainderBits = (nVars*2)%(sizeof(drow)*8);
//int TotalWords = (nVars*2)/(sizeof(drow)*8) + (RemainderBits > 0);
static
drow
DammyBitData
[(
MAXVARS
*
2
)
/
(
sizeof
(
drow
)
*
8
)
+
(
MAXVARS
*
2
)
%
(
sizeof
(
drow
)
*
8
)];
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINTIONS ///
////////////////////////////////////////////////////////////////////////
// IDEA! if we already used a cube to count distances and it did not improve
// there is no need to try it again with other group
// (this idea works only for ExorLink-2 and -3)
int
ExorLinkCubeIteratorStart
(
Cube
**
pGroup
,
Cube
*
pC1
,
Cube
*
pC2
,
cubedist
Dist
)
// this function starts the Exor-Link iterator, which iterates
// through the cube groups starting from the group with min literals
// returns 1 on success, returns 0 if the cubes have wrong distance
{
int
i
,
c
;
// check that everything is okey
assert
(
pC1
!=
NULL
);
assert
(
pC2
!=
NULL
);
assert
(
!
fWorking
);
nDist
=
Dist
;
nCubes
=
Dist
+
2
;
nCubesInGroup
=
s_ELnCubes
[
nDist
];
nGroups
=
s_ELnGroups
[
Dist
];
pCA
=
pC1
;
pCB
=
pC2
;
// find what variables are different in these two cubes
// FindDiffVars returns DiffVars[0] < 0, if the output is different
nDifferentVars
=
FindDiffVars
(
DiffVars
,
pCA
,
pCB
);
if
(
nCubes
!=
nDifferentVars
)
{
// cout << "ExorLinkCubeIterator(): Distance mismatch";
// cout << " nCubes = " << nCubes << " nDiffVars = " << nDifferentVars << endl;
fWorking
=
0
;
return
0
;
}
// copy the input variable cube data into DammyBitData[]
for
(
i
=
0
;
i
<
g_CoverInfo
.
nWordsIn
;
i
++
)
DammyBitData
[
i
]
=
pCA
->
pCubeDataIn
[
i
];
// find the number of different input variables
nDiffVarsIn
=
(
DiffVars
[
0
]
>=
0
)
?
nCubes
:
nCubes
-1
;
// assign the pointer to the place where the number of diff input vars is stored
pDiffVars
=
(
DiffVars
[
0
]
>=
0
)
?
DiffVars
:
DiffVars
+
1
;
// find the bit offsets and remove different variables
for
(
i
=
0
;
i
<
nDiffVarsIn
;
i
++
)
{
DiffVarWords
[
i
]
=
((
2
*
pDiffVars
[
i
])
>>
LOGBPI
)
;
DiffVarBits
[
i
]
=
((
2
*
pDiffVars
[
i
])
&
BPIMASK
);
// clear this position
DammyBitData
[
DiffVarWords
[
i
]
]
&=
~
(
3
<<
DiffVarBits
[
i
]
);
}
// extract the values from the cubes and create the mask of literals
MaskLiterals
=
0
;
// initialize the base for literal counts
StartingLiterals
=
pCA
->
a
;
for
(
i
=
0
,
BitShift
=
0
;
i
<
nDiffVarsIn
;
i
++
,
BitShift
++
)
{
DiffVarValues
[
i
][
0
]
=
(
pCA
->
pCubeDataIn
[
DiffVarWords
[
i
]]
>>
DiffVarBits
[
i
]
)
&
3
;
if
(
DiffVarValues
[
i
][
0
]
!=
VAR_ABS
)
{
MaskLiterals
|=
(
1
<<
BitShift
);
// update the base for literal counts
StartingLiterals
--
;
}
BitShift
++
;
DiffVarValues
[
i
][
1
]
=
(
pCB
->
pCubeDataIn
[
DiffVarWords
[
i
]]
>>
DiffVarBits
[
i
]
)
&
3
;
if
(
DiffVarValues
[
i
][
1
]
!=
VAR_ABS
)
MaskLiterals
|=
(
1
<<
BitShift
);
BitShift
++
;
DiffVarValues
[
i
][
2
]
=
DiffVarValues
[
i
][
0
]
^
DiffVarValues
[
i
][
1
];
if
(
DiffVarValues
[
i
][
2
]
!=
VAR_ABS
)
MaskLiterals
|=
(
1
<<
BitShift
);
BitShift
++
;
}
// count the number of additional literals in each cube of the group
for
(
i
=
0
;
i
<
nCubesInGroup
;
i
++
)
CubeLiterals
[
i
]
=
BitCount
[
MaskLiterals
&
s_CubeLitMasks
[
Dist
][
i
]
];
// compute the costs of all groups
for
(
i
=
0
;
i
<
nGroups
;
i
++
)
// go over all cubes in the group
for
(
GroupCosts
[
i
]
=
0
,
c
=
0
;
c
<
nCubes
;
c
++
)
GroupCosts
[
i
]
+=
CubeLiterals
[
s_ELGroupRules
[
Dist
][
i
][
c
]
];
// find the best cost group
if
(
fMinLitGroupsFirst
[
Dist
]
)
{
// find the minimum cost group
GroupCostBest
=
LARGE_NUM
;
for
(
i
=
0
;
i
<
nGroups
;
i
++
)
if
(
GroupCostBest
>
GroupCosts
[
i
]
)
{
GroupCostBest
=
GroupCosts
[
i
];
GroupCostBestNum
=
i
;
}
}
else
{
// find the maximum cost group
GroupCostBest
=
-1
;
for
(
i
=
0
;
i
<
nGroups
;
i
++
)
if
(
GroupCostBest
<
GroupCosts
[
i
]
)
{
GroupCostBest
=
GroupCosts
[
i
];
GroupCostBestNum
=
i
;
}
}
// create the cubes with min number of literals needed for the group
LastGroup
=
0
;
for
(
c
=
0
;
c
<
nCubes
;
c
++
)
{
CubeNum
=
s_ELGroupRules
[
Dist
][
GroupCostBestNum
][
c
];
LastGroup
|=
s_BitMasks
[
CubeNum
];
// bring a cube from the free cube list
ELCubes
[
CubeNum
]
=
GetFreeCube
();
// copy the input bit data into the cube
for
(
i
=
0
;
i
<
g_CoverInfo
.
nWordsIn
;
i
++
)
ELCubes
[
CubeNum
]
->
pCubeDataIn
[
i
]
=
DammyBitData
[
i
];
// copy the output bit data into the cube
NewZ
=
0
;
if
(
DiffVars
[
0
]
>=
0
)
// the output is not involved in ExorLink
{
for
(
i
=
0
;
i
<
g_CoverInfo
.
nWordsOut
;
i
++
)
ELCubes
[
CubeNum
]
->
pCubeDataOut
[
i
]
=
pCA
->
pCubeDataOut
[
i
];
NewZ
=
pCA
->
z
;
}
else
// the output is involved
{
// determine where the output information comes from
Value
=
s_ELCubeRules
[
Dist
][
CubeNum
][
nDiffVarsIn
];
if
(
Value
==
vs0
)
for
(
i
=
0
;
i
<
g_CoverInfo
.
nWordsOut
;
i
++
)
{
Temp
=
pCA
->
pCubeDataOut
[
i
];
ELCubes
[
CubeNum
]
->
pCubeDataOut
[
i
]
=
Temp
;
NewZ
+=
BIT_COUNT
(
Temp
);
}
else
if
(
Value
==
vs1
)
for
(
i
=
0
;
i
<
g_CoverInfo
.
nWordsOut
;
i
++
)
{
Temp
=
pCB
->
pCubeDataOut
[
i
];
ELCubes
[
CubeNum
]
->
pCubeDataOut
[
i
]
=
Temp
;
NewZ
+=
BIT_COUNT
(
Temp
);
}
else
if
(
Value
==
vsX
)
for
(
i
=
0
;
i
<
g_CoverInfo
.
nWordsOut
;
i
++
)
{
Temp
=
pCA
->
pCubeDataOut
[
i
]
^
pCB
->
pCubeDataOut
[
i
];
ELCubes
[
CubeNum
]
->
pCubeDataOut
[
i
]
=
Temp
;
NewZ
+=
BIT_COUNT
(
Temp
);
}
}
// set the variables that should be there
for
(
i
=
0
;
i
<
nDiffVarsIn
;
i
++
)
{
Value
=
DiffVarValues
[
i
][
s_ELCubeRules
[
Dist
][
CubeNum
][
i
]
];
ELCubes
[
CubeNum
]
->
pCubeDataIn
[
DiffVarWords
[
i
]
]
|=
(
Value
<<
DiffVarBits
[
i
]
);
}
// set the number of literals
ELCubes
[
CubeNum
]
->
a
=
StartingLiterals
+
CubeLiterals
[
CubeNum
];
ELCubes
[
CubeNum
]
->
z
=
NewZ
;
ELCubes
[
CubeNum
]
->
q
=
ComputeQCostBits
(
ELCubes
[
CubeNum
]
);
// assign the ID
ELCubes
[
CubeNum
]
->
ID
=
g_CoverInfo
.
cIDs
++
;
// skip through zero-ID
if
(
g_CoverInfo
.
cIDs
==
256
)
g_CoverInfo
.
cIDs
=
1
;
// prepare the return array
pGroup
[
c
]
=
ELCubes
[
CubeNum
];
}
// mark this group as visited
VisitedGroups
|=
s_BitMasks
[
GroupCostBestNum
];
// set the first visited group number
GroupOrder
[
0
]
=
GroupCostBestNum
;
// increment the counter of visited groups
nVisitedGroups
=
1
;
fWorking
=
1
;
return
1
;
}
int
ExorLinkCubeIteratorNext
(
Cube
**
pGroup
)
// give the next group in the decreasing order of sum of literals
// returns 1 on success, returns 0 if there are no more groups
{
int
i
,
c
;
// check that everything is okey
assert
(
fWorking
);
if
(
nVisitedGroups
==
nGroups
)
// we have iterated through all groups
return
0
;
// find the min/max cost group
if
(
fMinLitGroupsFirst
[
nDist
]
)
// if ( nCubes == 4 )
{
// find the minimum cost
// go through all groups
GroupCostBest
=
LARGE_NUM
;
for
(
i
=
0
;
i
<
nGroups
;
i
++
)
if
(
!
(
VisitedGroups
&
s_BitMasks
[
i
])
&&
GroupCostBest
>
GroupCosts
[
i
]
)
{
GroupCostBest
=
GroupCosts
[
i
];
GroupCostBestNum
=
i
;
}
assert
(
GroupCostBest
!=
LARGE_NUM
);
}
else
{
// find the maximum cost
// go through all groups
GroupCostBest
=
-1
;
for
(
i
=
0
;
i
<
nGroups
;
i
++
)
if
(
!
(
VisitedGroups
&
s_BitMasks
[
i
])
&&
GroupCostBest
<
GroupCosts
[
i
]
)
{
GroupCostBest
=
GroupCosts
[
i
];
GroupCostBestNum
=
i
;
}
assert
(
GroupCostBest
!=
-1
);
}
// create the cubes needed for the group, if they are not created already
LastGroup
=
0
;
for
(
c
=
0
;
c
<
nCubes
;
c
++
)
{
CubeNum
=
s_ELGroupRules
[
nDist
][
GroupCostBestNum
][
c
];
LastGroup
|=
s_BitMasks
[
CubeNum
];
if
(
ELCubes
[
CubeNum
]
==
NULL
)
// this cube does not exist
{
// bring a cube from the free cube list
ELCubes
[
CubeNum
]
=
GetFreeCube
();
// copy the input bit data into the cube
for
(
i
=
0
;
i
<
g_CoverInfo
.
nWordsIn
;
i
++
)
ELCubes
[
CubeNum
]
->
pCubeDataIn
[
i
]
=
DammyBitData
[
i
];
// copy the output bit data into the cube
NewZ
=
0
;
if
(
DiffVars
[
0
]
>=
0
)
// the output is not involved in ExorLink
{
for
(
i
=
0
;
i
<
g_CoverInfo
.
nWordsOut
;
i
++
)
ELCubes
[
CubeNum
]
->
pCubeDataOut
[
i
]
=
pCA
->
pCubeDataOut
[
i
];
NewZ
=
pCA
->
z
;
}
else
// the output is involved
{
// determine where the output information comes from
Value
=
s_ELCubeRules
[
nDist
][
CubeNum
][
nDiffVarsIn
];
if
(
Value
==
vs0
)
for
(
i
=
0
;
i
<
g_CoverInfo
.
nWordsOut
;
i
++
)
{
Temp
=
pCA
->
pCubeDataOut
[
i
];
ELCubes
[
CubeNum
]
->
pCubeDataOut
[
i
]
=
Temp
;
NewZ
+=
BIT_COUNT
(
Temp
);
}
else
if
(
Value
==
vs1
)
for
(
i
=
0
;
i
<
g_CoverInfo
.
nWordsOut
;
i
++
)
{
Temp
=
pCB
->
pCubeDataOut
[
i
];
ELCubes
[
CubeNum
]
->
pCubeDataOut
[
i
]
=
Temp
;
NewZ
+=
BIT_COUNT
(
Temp
);
}
else
if
(
Value
==
vsX
)
for
(
i
=
0
;
i
<
g_CoverInfo
.
nWordsOut
;
i
++
)
{
Temp
=
pCA
->
pCubeDataOut
[
i
]
^
pCB
->
pCubeDataOut
[
i
];
ELCubes
[
CubeNum
]
->
pCubeDataOut
[
i
]
=
Temp
;
NewZ
+=
BIT_COUNT
(
Temp
);
}
}
// set the variables that should be there
for
(
i
=
0
;
i
<
nDiffVarsIn
;
i
++
)
{
Value
=
DiffVarValues
[
i
][
s_ELCubeRules
[
nDist
][
CubeNum
][
i
]
];
ELCubes
[
CubeNum
]
->
pCubeDataIn
[
DiffVarWords
[
i
]
]
|=
(
Value
<<
DiffVarBits
[
i
]
);
}
// set the number of literals and output ones
ELCubes
[
CubeNum
]
->
a
=
StartingLiterals
+
CubeLiterals
[
CubeNum
];
ELCubes
[
CubeNum
]
->
z
=
NewZ
;
ELCubes
[
CubeNum
]
->
q
=
ComputeQCostBits
(
ELCubes
[
CubeNum
]
);
assert
(
NewZ
!=
255
);
// assign the ID
ELCubes
[
CubeNum
]
->
ID
=
g_CoverInfo
.
cIDs
++
;
// skip through zero-ID
if
(
g_CoverInfo
.
cIDs
==
256
)
g_CoverInfo
.
cIDs
=
1
;
}
// prepare the return array
pGroup
[
c
]
=
ELCubes
[
CubeNum
];
}
// mark this group as visited
VisitedGroups
|=
s_BitMasks
[
GroupCostBestNum
];
// set the next visited group number and
// increment the counter of visited groups
GroupOrder
[
nVisitedGroups
++
]
=
GroupCostBestNum
;
return
1
;
}
int
ExorLinkCubeIteratorPick
(
Cube
**
pGroup
,
int
g
)
// gives the group #g in the order in which the groups were given
// during iteration
// returns 1 on success, returns 0 if something is wrong (g is too large)
{
int
GroupNum
,
c
;
assert
(
fWorking
);
assert
(
g
>=
0
&&
g
<
nGroups
);
assert
(
VisitedGroups
&
s_BitMasks
[
g
]
);
GroupNum
=
GroupOrder
[
g
];
// form the group
LastGroup
=
0
;
for
(
c
=
0
;
c
<
nCubes
;
c
++
)
{
CubeNum
=
s_ELGroupRules
[
nDist
][
GroupNum
][
c
];
// remember this group as the last one
LastGroup
|=
s_BitMasks
[
CubeNum
];
assert
(
ELCubes
[
CubeNum
]
!=
NULL
);
// this cube should exist
// prepare the return array
pGroup
[
c
]
=
ELCubes
[
CubeNum
];
}
return
1
;
}
void
ExorLinkCubeIteratorCleanUp
(
int
fTakeLastGroup
)
// removes the cubes from the store back into the list of free cubes
// if fTakeLastGroup is 0, removes all cubes
// if fTakeLastGroup is 1, does not store the last group
{
int
c
;
assert
(
fWorking
);
// put cubes back
// set the cube pointers to zero
if
(
fTakeLastGroup
==
0
)
for
(
c
=
0
;
c
<
nCubesInGroup
;
c
++
)
{
ELCubes
[
c
]
->
fMark
=
0
;
AddToFreeCubes
(
ELCubes
[
c
]
);
ELCubes
[
c
]
=
NULL
;
}
else
for
(
c
=
0
;
c
<
nCubesInGroup
;
c
++
)
if
(
ELCubes
[
c
]
)
{
ELCubes
[
c
]
->
fMark
=
0
;
if
(
(
LastGroup
&
s_BitMasks
[
c
])
==
0
)
// does not belong to the last group
AddToFreeCubes
(
ELCubes
[
c
]
);
ELCubes
[
c
]
=
NULL
;
}
// set the cube groups to zero
VisitedGroups
=
0
;
// shut down the iterator
fWorking
=
0
;
}
///////////////////////////////////////////////////////////////////
//////////// End of File /////////////////
///////////////////////////////////////////////////////////////////
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Tue, Oct 27, 3:34 PM (22 h, 11 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
406774
Default Alt Text
exorLink.cpp (28 KB)
Attached To
Mode
R272 SoC_NEM_Synthesis
Attached
Detach File
Event Timeline