-
Notifications
You must be signed in to change notification settings - Fork 0
/
lutcuts.pmg
102 lines (84 loc) · 2.05 KB
/
lutcuts.pmg
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
pattern lut_cuts
udata <int> max_nluts max_nouterfans max_nleaves
udata <Cell *> root
state <SigSpec> leaves
state <dict<SigBit, int>> cut_users
state <int> descend nluts
state <SigPool> outerfans driven
match root_
index <Cell*> root_ === root
endmatch
code leaves cut_users nluts outerfans driven
nluts = 1;
outerfans.add(port(root, \Y));
driven.add(port(root, \Y));
SigSpec a = port(root, \A);
a.sort_and_unify();
log_assert(!a.has_const());
for (auto bit : a)
cut_users[bit]++;
leaves = a;
endcode
code descend
for (descend = 0; descend < leaves.size(); descend++)
branch;
reject;
endcode
code
subpattern(cuts_descended);
reject;
endcode
subpattern cuts_descended
arg leaves cut_users descend nluts outerfans driven
match node
select node->type == $lut
index <SigBit> port(node, \Y) === leaves.extract(descend)
endmatch
code leaves cut_users descend nluts outerfans driven
for (auto pair : cut_users)
log_assert(driven.check(pair.first) || leaves.extract(pair.first).size());
nluts++;
SigBit y = port(node, \Y);
log_assert(cut_users[y] < nusers(y));
if (cut_users[y] + 1 != nusers(y)) {
if ((int) outerfans.size() == max_nouterfans)
reject;
outerfans.add(y);
}
driven.add(y);
leaves.remove(descend);
{
SigSpec a = port(node, \A);
a.sort_and_unify();
log_assert(!a.has_const());
for (auto bit : a) {
if (!cut_users[bit]++) {
leaves.append(bit);
} else if (cut_users[bit] + 1 == nusers(bit)) {
// Our earlier outerfans reasoning applies
// no more, we need to revisit all options
// for expansion
descend = 0;
if (outerfans.check(bit))
outerfans.remove(bit);
}
}
}
if (leaves.size() > max_nleaves)
reject;
for (auto pair : cut_users)
log_assert(driven.check(pair.first) || leaves.extract(pair.first).size());
endcode
code descend
if (nluts < max_nluts)
for (; descend < leaves.size(); descend++)
branch;
accept;
reject;
endcode
code
subpattern(cuts_descended);
finally
for (auto pair : cut_users)
log_assert(driven.check(pair.first) || leaves.extract(pair.first).size());
endcode