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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
state <SigBit> clock
state <bool> clock_pol clock_vld
state <SigSpec> sigA sigB sigY sigS
state <Cell*> addAB muxAB
match mul
select mul->type.in($mul)
select GetSize(mul->getPort(\A)) + GetSize(mul->getPort(\B)) > 10
select GetSize(mul->getPort(\Y)) > 10
endmatch
match ffA
select ffA->type.in($dff)
// select nusers(port(ffA, \Q)) == 2
index <SigSpec> port(ffA, \Q) === port(mul, \A)
optional
endmatch
code sigA clock clock_pol clock_vld
sigA = port(mul, \A);
if (ffA) {
sigA = port(ffA, \D);
clock = port(ffA, \CLK).as_bit();
clock_pol = param(ffA, \CLK_POLARITY).as_bool();
clock_vld = true;
}
endcode
match ffB
select ffB->type.in($dff)
// select nusers(port(ffB, \Q)) == 2
index <SigSpec> port(ffB, \Q) === port(mul, \B)
optional
endmatch
code sigB clock clock_pol clock_vld
sigB = port(mul, \B);
if (ffB) {
sigB = port(ffB, \D);
SigBit c = port(ffB, \CLK).as_bit();
bool cp = param(ffB, \CLK_POLARITY).as_bool();
if (clock_vld && (c != clock || cp != clock_pol))
reject;
clock = c;
clock_pol = cp;
clock_vld = true;
}
endcode
match ffY
select ffY->type.in($dff)
select nusers(port(ffY, \D)) == 2
index <SigSpec> port(ffY, \D) === port(mul, \Y)
optional
endmatch
code sigY clock clock_pol clock_vld
sigY = port(mul, \Y);
if (ffY) {
sigY = port(ffY, \Q);
SigBit c = port(ffY, \CLK).as_bit();
bool cp = param(ffY, \CLK_POLARITY).as_bool();
if (clock_vld && (c != clock || cp != clock_pol))
reject;
clock = c;
clock_pol = cp;
clock_vld = true;
}
endcode
match addA
select addA->type.in($add)
select nusers(port(addA, \A)) == 2
index <SigSpec> port(addA, \A) === sigY
optional
endmatch
match addB
if !addA
select addB->type.in($add, $sub)
select nusers(port(addB, \B)) == 2
index <SigSpec> port(addB, \B) === sigY
optional
endmatch
code addAB sigS
if (addA) {
addAB = addA;
sigS = port(addA, \B);
}
if (addB) {
addAB = addB;
sigS = port(addB, \A);
}
if (addAB) {
int natural_mul_width = GetSize(sigA) + GetSize(sigB);
int actual_mul_width = GetSize(sigY);
int actual_acc_width = GetSize(sigS);
if ((actual_acc_width > actual_mul_width) && (natural_mul_width > actual_mul_width))
reject;
if ((actual_acc_width != actual_mul_width) && (param(mul, \A_SIGNED).as_bool() != param(addAB, \A_SIGNED).as_bool()))
reject;
}
endcode
match muxA
if addAB
select muxA->type.in($mux)
select nusers(port(muxA, \A)) == 2
index <SigSpec> port(muxA, \A) === port(addAB, \Y)
optional
endmatch
match muxB
if addAB
if !muxA
select muxB->type.in($mux)
select nusers(port(muxB, \B)) == 2
index <SigSpec> port(muxB, \B) === port(addAB, \Y)
optional
endmatch
code muxAB
muxAB = addAB;
if (muxA)
muxAB = muxA;
if (muxB)
muxAB = muxB;
endcode
match ffS
if muxAB
select ffS->type.in($dff)
select nusers(port(ffS, \D)) == 2
index <SigSpec> port(ffS, \D) === port(muxAB, \Y)
index <SigSpec> port(ffS, \Q) === sigS
endmatch
code clock clock_pol clock_vld
if (ffS) {
SigBit c = port(ffS, \CLK).as_bit();
bool cp = param(ffS, \CLK_POLARITY).as_bool();
if (clock_vld && (c != clock || cp != clock_pol))
reject;
clock = c;
clock_pol = cp;
clock_vld = true;
}
endcode
|