mirror of
https://github.com/YosysHQ/abc.git
synced 2026-09-03 16:29:14 +02:00
253 lines
5.3 KiB
C
253 lines
5.3 KiB
C
/*
|
|
* Revision Control Information
|
|
*
|
|
* $Source$
|
|
* $Author$
|
|
* $Revision$
|
|
* $Date$
|
|
*
|
|
*/
|
|
/*
|
|
sharp.c -- perform sharp, disjoint sharp, and intersection
|
|
*/
|
|
|
|
#include "espresso.h"
|
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
|
|
long start_time;
|
|
|
|
|
|
/* cv_sharp -- form the sharp product between two covers */
|
|
pcover cv_sharp(A, B)
|
|
pcover A, B;
|
|
{
|
|
pcube last, p;
|
|
pcover T;
|
|
|
|
T = new_cover(0);
|
|
foreach_set(A, last, p)
|
|
T = sf_union(T, cb_sharp(p, B));
|
|
return T;
|
|
}
|
|
|
|
|
|
/* cb_sharp -- form the sharp product between a cube and a cover */
|
|
pcover cb_sharp(c, T)
|
|
pcube c;
|
|
pcover T;
|
|
{
|
|
if (T->count == 0) {
|
|
T = sf_addset(new_cover(1), c);
|
|
} else {
|
|
start_time = ptime();
|
|
T = cb_recur_sharp(c, T, 0, T->count-1, 0);
|
|
}
|
|
return T;
|
|
}
|
|
|
|
|
|
/* recursive formulation to provide balanced merging */
|
|
pcover cb_recur_sharp(c, T, first, last, level)
|
|
pcube c;
|
|
pcover T;
|
|
int first, last, level;
|
|
{
|
|
pcover temp, left, right;
|
|
int middle;
|
|
|
|
if (first == last) {
|
|
temp = sharp(c, GETSET(T, first));
|
|
} else {
|
|
middle = (first + last) / 2;
|
|
left = cb_recur_sharp(c, T, first, middle, level+1);
|
|
right = cb_recur_sharp(c, T, middle+1, last, level+1);
|
|
temp = cv_intersect(left, right);
|
|
if ((debug & SHARP) && level < 4) {
|
|
printf("# SHARP[%d]: %4d = %4d x %4d, time = %s\n",
|
|
level, temp->count, left->count, right->count,
|
|
print_time(ptime() - start_time));
|
|
(void) fflush(stdout);
|
|
}
|
|
free_cover(left);
|
|
free_cover(right);
|
|
}
|
|
return temp;
|
|
}
|
|
|
|
|
|
/* sharp -- form the sharp product between two cubes */
|
|
pcover sharp(a, b)
|
|
pcube a, b;
|
|
{
|
|
register int var;
|
|
register pcube d=cube.temp[0], temp=cube.temp[1], temp1=cube.temp[2];
|
|
pcover r = new_cover(cube.num_vars);
|
|
|
|
if (cdist0(a, b)) {
|
|
set_diff(d, a, b);
|
|
for(var = 0; var < cube.num_vars; var++) {
|
|
if (! setp_empty(set_and(temp, d, cube.var_mask[var]))) {
|
|
set_diff(temp1, a, cube.var_mask[var]);
|
|
set_or(GETSET(r, r->count++), temp, temp1);
|
|
}
|
|
}
|
|
} else {
|
|
r = sf_addset(r, a);
|
|
}
|
|
return r;
|
|
}
|
|
|
|
pcover make_disjoint(A)
|
|
pcover A;
|
|
{
|
|
pcover R, new;
|
|
register pset last, p;
|
|
|
|
R = new_cover(0);
|
|
foreach_set(A, last, p) {
|
|
new = cb_dsharp(p, R);
|
|
R = sf_append(R, new);
|
|
}
|
|
return R;
|
|
}
|
|
|
|
|
|
/* cv_dsharp -- disjoint-sharp product between two covers */
|
|
pcover cv_dsharp(A, B)
|
|
pcover A, B;
|
|
{
|
|
register pcube last, p;
|
|
pcover T;
|
|
|
|
T = new_cover(0);
|
|
foreach_set(A, last, p) {
|
|
T = sf_union(T, cb_dsharp(p, B));
|
|
}
|
|
return T;
|
|
}
|
|
|
|
|
|
/* cb1_dsharp -- disjoint-sharp product between a cover and a cube */
|
|
pcover cb1_dsharp(T, c)
|
|
pcover T;
|
|
pcube c;
|
|
{
|
|
pcube last, p;
|
|
pcover R;
|
|
|
|
R = new_cover(T->count);
|
|
foreach_set(T, last, p) {
|
|
R = sf_union(R, dsharp(p, c));
|
|
}
|
|
return R;
|
|
}
|
|
|
|
|
|
/* cb_dsharp -- disjoint-sharp product between a cube and a cover */
|
|
pcover cb_dsharp(c, T)
|
|
pcube c;
|
|
pcover T;
|
|
{
|
|
pcube last, p;
|
|
pcover Y, Y1;
|
|
|
|
if (T->count == 0) {
|
|
Y = sf_addset(new_cover(1), c);
|
|
} else {
|
|
Y = new_cover(T->count);
|
|
set_copy(GETSET(Y,Y->count++), c);
|
|
foreach_set(T, last, p) {
|
|
Y1 = cb1_dsharp(Y, p);
|
|
free_cover(Y);
|
|
Y = Y1;
|
|
}
|
|
}
|
|
return Y;
|
|
}
|
|
|
|
|
|
/* dsharp -- form the disjoint-sharp product between two cubes */
|
|
pcover dsharp(a, b)
|
|
pcube a, b;
|
|
{
|
|
register pcube mask, diff, and, temp, temp1 = cube.temp[0];
|
|
int var;
|
|
pcover r;
|
|
|
|
r = new_cover(cube.num_vars);
|
|
|
|
if (cdist0(a, b)) {
|
|
diff = set_diff(new_cube(), a, b);
|
|
and = set_and(new_cube(), a, b);
|
|
mask = new_cube();
|
|
for(var = 0; var < cube.num_vars; var++) {
|
|
/* check if position var of "a and not b" is not empty */
|
|
if (! setp_disjoint(diff, cube.var_mask[var])) {
|
|
|
|
/* coordinate var equals the difference between a and b */
|
|
temp = GETSET(r, r->count++);
|
|
(void) set_and(temp, diff, cube.var_mask[var]);
|
|
|
|
/* coordinates 0 ... var-1 equal the intersection */
|
|
INLINEset_and(temp1, and, mask);
|
|
INLINEset_or(temp, temp, temp1);
|
|
|
|
/* coordinates var+1 .. cube.num_vars equal a */
|
|
set_or(mask, mask, cube.var_mask[var]);
|
|
INLINEset_diff(temp1, a, mask);
|
|
INLINEset_or(temp, temp, temp1);
|
|
}
|
|
}
|
|
free_cube(diff);
|
|
free_cube(and);
|
|
free_cube(mask);
|
|
} else {
|
|
r = sf_addset(r, a);
|
|
}
|
|
return r;
|
|
}
|
|
|
|
/* cv_intersect -- form the intersection of two covers */
|
|
|
|
#define MAGIC 500 /* save 500 cubes before containment */
|
|
|
|
pcover cv_intersect(A, B)
|
|
pcover A, B;
|
|
{
|
|
register pcube pi, pj, lasti, lastj, pt;
|
|
pcover T, Tsave = NULL;
|
|
|
|
/* How large should each temporary result cover be ? */
|
|
T = new_cover(MAGIC);
|
|
pt = T->data;
|
|
|
|
/* Form pairwise intersection of each cube of A with each cube of B */
|
|
foreach_set(A, lasti, pi) {
|
|
foreach_set(B, lastj, pj) {
|
|
if (cdist0(pi, pj)) {
|
|
(void) set_and(pt, pi, pj);
|
|
if (++T->count >= T->capacity) {
|
|
if (Tsave == NULL)
|
|
Tsave = sf_contain(T);
|
|
else
|
|
Tsave = sf_union(Tsave, sf_contain(T));
|
|
T = new_cover(MAGIC);
|
|
pt = T->data;
|
|
} else
|
|
pt += T->wsize;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if (Tsave == NULL)
|
|
Tsave = sf_contain(T);
|
|
else
|
|
Tsave = sf_union(Tsave, sf_contain(T));
|
|
return Tsave;
|
|
}
|
|
ABC_NAMESPACE_IMPL_END
|
|
|