Skip to content

Commit c5fd96e

Browse files
committed
macc_v2: Start new cell
1 parent 08394c5 commit c5fd96e

File tree

5 files changed

+120
-38
lines changed

5 files changed

+120
-38
lines changed

kernel/constids.inc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,3 +276,7 @@ X(Y)
276276
X(Y_WIDTH)
277277
X(area)
278278
X(capacitance)
279+
X(NTERMS)
280+
X(TERM_NEGATED)
281+
X(A_WIDTHS)
282+
X(B_WIDTHS)

kernel/macc.h

Lines changed: 67 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ struct Macc
8282
new_ports.swap(ports);
8383
}
8484

85-
void from_cell(RTLIL::Cell *cell)
85+
void from_cell_v1(RTLIL::Cell *cell)
8686
{
8787
RTLIL::SigSpec port_a = cell->getPort(ID::A);
8888

@@ -136,52 +136,82 @@ struct Macc
136136
log_assert(port_a_cursor == GetSize(port_a));
137137
}
138138

139-
void to_cell(RTLIL::Cell *cell) const
139+
void from_cell(RTLIL::Cell *cell)
140140
{
141-
RTLIL::SigSpec port_a;
142-
std::vector<RTLIL::State> config_bits;
143-
int max_size = 0, num_bits = 0;
144-
145-
for (auto &port : ports) {
146-
max_size = max(max_size, GetSize(port.in_a));
147-
max_size = max(max_size, GetSize(port.in_b));
141+
if (cell->type == ID($macc)) {
142+
from_cell_v1(cell);
143+
return;
148144
}
145+
log_assert(cell->type == ID($macc_v2));
149146

150-
while (max_size)
151-
num_bits++, max_size /= 2;
147+
RTLIL::SigSpec port_a = cell->getPort(ID::A);
148+
RTLIL::SigSpec port_b = cell->getPort(ID::B);
152149

153-
log_assert(num_bits < 16);
154-
config_bits.push_back(num_bits & 1 ? State::S1 : State::S0);
155-
config_bits.push_back(num_bits & 2 ? State::S1 : State::S0);
156-
config_bits.push_back(num_bits & 4 ? State::S1 : State::S0);
157-
config_bits.push_back(num_bits & 8 ? State::S1 : State::S0);
150+
ports.clear();
158151

159-
for (auto &port : ports)
160-
{
161-
if (GetSize(port.in_a) == 0)
162-
continue;
152+
int nterms = cell->getParam(ID::NTERMS).as_int();
153+
const Const &neg = cell->getParam(ID::TERM_NEGATED);
154+
const Const &a_widths = cell->getParam(ID::A_WIDTHS);
155+
const Const &b_widths = cell->getParam(ID::B_WIDTHS);
156+
const Const &a_signed = cell->getParam(ID::A_SIGNED);
157+
const Const &b_signed = cell->getParam(ID::B_SIGNED);
158+
159+
int ai = 0, bi = 0;
160+
for (int i = 0; i < nterms; i++) {
161+
port_t term;
162+
163+
log_assert(a_signed[i] == b_signed[i]);
164+
term.is_signed = (a_signed[i] == State::S1);
165+
int a_width = a_widths.extract(16 * i, 16).as_int(false);
166+
int b_width = b_widths.extract(16 * i, 16).as_int(false);
167+
168+
term.in_a = port_a.extract(ai, a_width);
169+
ai += a_width;
170+
term.in_b = port_b.extract(bi, b_width);
171+
bi += b_width;
172+
term.do_subtract = (neg[i] == State::S1);
173+
174+
ports.push_back(term);
175+
}
176+
log_assert(port_a.size() == ai);
177+
log_assert(port_b.size() == bi);
178+
}
163179

164-
config_bits.push_back(port.is_signed ? State::S1 : State::S0);
165-
config_bits.push_back(port.do_subtract ? State::S1 : State::S0);
180+
void to_cell(RTLIL::Cell *cell)
181+
{
182+
cell->type = ID($macc_v2);
166183

167-
int size_a = GetSize(port.in_a);
168-
for (int i = 0; i < num_bits; i++)
169-
config_bits.push_back(size_a & (1 << i) ? State::S1 : State::S0);
184+
int nterms = ports.size();
185+
const auto Sx = State::Sx;
186+
Const a_signed(Sx, nterms), b_signed(Sx, nterms), negated(Sx, nterms);
187+
Const a_widths, b_widths;
188+
SigSpec a, b;
170189

171-
int size_b = GetSize(port.in_b);
172-
for (int i = 0; i < num_bits; i++)
173-
config_bits.push_back(size_b & (1 << i) ? State::S1 : State::S0);
190+
for (int i = 0; i < nterms; i++) {
191+
SigSpec term_a = ports[i].in_a, term_b = ports[i].in_b;
174192

175-
port_a.append(port.in_a);
176-
port_a.append(port.in_b);
177-
}
193+
a_widths.append(Const(term_a.size(), 16));
194+
b_widths.append(Const(term_b.size(), 16));
178195

179-
cell->setPort(ID::A, port_a);
180-
cell->setPort(ID::B, {});
181-
cell->setParam(ID::CONFIG, config_bits);
182-
cell->setParam(ID::CONFIG_WIDTH, GetSize(config_bits));
183-
cell->setParam(ID::A_WIDTH, GetSize(port_a));
184-
cell->setParam(ID::B_WIDTH, 0);
196+
a_signed.bits()[i] = b_signed.bits()[i] =
197+
(ports[i].is_signed ? RTLIL::S1 : RTLIL::S0);
198+
negated.bits()[i] = (ports[i].do_subtract ? RTLIL::S1 : RTLIL::S0);
199+
200+
a.append(term_a);
201+
b.append(term_b);
202+
}
203+
negated.is_fully_def();
204+
a_signed.is_fully_def();
205+
b_signed.is_fully_def();
206+
207+
cell->setParam(ID::NTERMS, nterms);
208+
cell->setParam(ID::TERM_NEGATED, negated);
209+
cell->setParam(ID::A_SIGNED, a_signed);
210+
cell->setParam(ID::B_SIGNED, b_signed);
211+
cell->setParam(ID::A_WIDTHS, a_widths);
212+
cell->setParam(ID::B_WIDTHS, b_widths);
213+
cell->setPort(ID::A, a);
214+
cell->setPort(ID::B, b);
185215
}
186216

187217
bool eval(RTLIL::Const &result) const

kernel/rtlil.cc

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1467,6 +1467,30 @@ namespace {
14671467
return;
14681468
}
14691469

1470+
if (cell->type == ID($macc_v2)) {
1471+
if (param(ID::NTERMS) <= 0)
1472+
error(__LINE__);
1473+
param_bits(ID::TERM_NEGATED, param(ID::NTERMS));
1474+
param_bits(ID::A_SIGNED, param(ID::NTERMS));
1475+
param_bits(ID::B_SIGNED, param(ID::NTERMS));
1476+
if (cell->getParam(ID::A_SIGNED) != cell->getParam(ID::B_SIGNED))
1477+
error(__LINE__);
1478+
param_bits(ID::A_WIDTHS, param(ID::NTERMS) * 16);
1479+
param_bits(ID::B_WIDTHS, param(ID::NTERMS) * 16);
1480+
const Const &a_width = cell->getParam(ID::A_WIDTHS);
1481+
const Const &b_width = cell->getParam(ID::B_WIDTHS);
1482+
int a_width_sum = 0, b_width_sum = 0;
1483+
for (int i = 0; i < param(ID::NTERMS); i++) {
1484+
a_width_sum += a_width.extract(16 * i, 16).as_int(false);
1485+
b_width_sum += b_width.extract(16 * i, 16).as_int(false);
1486+
}
1487+
port(ID::A, a_width_sum);
1488+
port(ID::B, b_width_sum);
1489+
port(ID::Y, param(ID::Y_WIDTH));
1490+
check_expected();
1491+
return;
1492+
}
1493+
14701494
if (cell->type == ID($logic_not)) {
14711495
param_bool(ID::A_SIGNED);
14721496
port(ID::A, param(ID::A_WIDTH));
@@ -4099,6 +4123,11 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed)
40994123
return;
41004124
}
41014125

4126+
if (type == ID($macc_v2)) {
4127+
parameters[ID::Y_WIDTH] = GetSize(connections_[ID::Y]);
4128+
return;
4129+
}
4130+
41024131
bool signedness_ab = !type.in(ID($slice), ID($concat), ID($macc));
41034132

41044133
if (connections_.count(ID::A)) {

passes/techmap/maccmap.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@ struct MaccmapPass : public Pass {
403403

404404
for (auto mod : design->selected_modules())
405405
for (auto cell : mod->selected_cells())
406-
if (cell->type == ID($macc)) {
406+
if (cell->type.in(ID($macc), ID($macc_v2))) {
407407
log("Mapping %s.%s (%s).\n", log_id(mod), log_id(cell), log_id(cell->type));
408408
maccmap(mod, cell, unmap_mode);
409409
mod->remove(cell);
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
read_verilog <<EOF
2+
module gate(input signed [2:0] a1, input signed [2:0] b1,
3+
input [1:0] a2, input [3:0] b2, input c, input d, output signed [3:0] y);
4+
wire signed [3:0] ab1;
5+
assign ab1 = a1 * b1;
6+
assign y = ab1 + a2*b2 + c + d + 1;
7+
endmodule
8+
EOF
9+
prep
10+
11+
design -save gold
12+
alumacc
13+
opt_clean
14+
select -assert-count 1 t:$macc_v2
15+
maccmap -unmap
16+
design -copy-from gold -as gold gate
17+
equiv_make gold gate equiv
18+
equiv_induct equiv
19+
equiv_status -assert equiv

0 commit comments

Comments
 (0)