Skip to content

Commit fb8f72a

Browse files
committed
Preserve assign_map across ABC invocations.
Currently `assign_map` is rebuilt from the module from scratch every time we invoke ABC. That doesn't scale when we do thousands of ABC runs over large modules. Instead, create it once and then maintain incrementally it as we update the module.
1 parent 48f7ffc commit fb8f72a

File tree

1 file changed

+66
-62
lines changed

1 file changed

+66
-62
lines changed

passes/techmap/abc.cc

Lines changed: 66 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,6 @@ struct AbcModuleState {
142142
const AbcConfig &config;
143143

144144
int map_autoidx = 0;
145-
SigMap assign_map;
146145
std::vector<gate_t> signal_list;
147146
dict<RTLIL::SigBit, int> signal_map;
148147
FfInitVals initvals;
@@ -162,19 +161,19 @@ struct AbcModuleState {
162161

163162
AbcModuleState(const AbcConfig &config) : config(config) {}
164163

165-
int map_signal(RTLIL::SigBit bit, gate_type_t gate_type = G(NONE), int in1 = -1, int in2 = -1, int in3 = -1, int in4 = -1);
166-
void mark_port(RTLIL::SigSpec sig);
167-
void extract_cell(RTLIL::Module *module, RTLIL::Cell *cell, bool keepff);
164+
int map_signal(const SigMap &assign_map, RTLIL::SigBit bit, gate_type_t gate_type = G(NONE), int in1 = -1, int in2 = -1, int in3 = -1, int in4 = -1);
165+
void mark_port(const SigMap &assign_map, RTLIL::SigSpec sig);
166+
void extract_cell(const SigMap &assign_map, RTLIL::Module *module, RTLIL::Cell *cell, bool keepff);
168167
std::string remap_name(RTLIL::IdString abc_name, RTLIL::Wire **orig_wire = nullptr);
169168
void dump_loop_graph(FILE *f, int &nr, dict<int, pool<int>> &edges, pool<int> &workpool, std::vector<int> &in_counts);
170-
void handle_loops(RTLIL::Module *module);
171-
void abc_module(RTLIL::Design *design, RTLIL::Module *module, const std::vector<RTLIL::Cell*> &cells,
169+
void handle_loops(SigMap &assign_map, RTLIL::Module *module);
170+
void abc_module(RTLIL::Design *design, RTLIL::Module *module, SigMap &assign_map, const std::vector<RTLIL::Cell*> &cells,
172171
bool dff_mode, std::string clk_str);
173-
void extract(RTLIL::Design *design, RTLIL::Module *module);
172+
void extract(SigMap &assign_map, RTLIL::Design *design, RTLIL::Module *module);
174173
void finish();
175174
};
176175

177-
int AbcModuleState::map_signal(RTLIL::SigBit bit, gate_type_t gate_type, int in1, int in2, int in3, int in4)
176+
int AbcModuleState::map_signal(const SigMap &assign_map, RTLIL::SigBit bit, gate_type_t gate_type, int in1, int in2, int in3, int in4)
178177
{
179178
assign_map.apply(bit);
180179

@@ -212,14 +211,14 @@ int AbcModuleState::map_signal(RTLIL::SigBit bit, gate_type_t gate_type, int in1
212211
return gate.id;
213212
}
214213

215-
void AbcModuleState::mark_port(RTLIL::SigSpec sig)
214+
void AbcModuleState::mark_port(const SigMap &assign_map, RTLIL::SigSpec sig)
216215
{
217216
for (auto &bit : assign_map(sig))
218217
if (bit.wire != nullptr && signal_map.count(bit) > 0)
219218
signal_list[signal_map[bit]].is_port = true;
220219
}
221220

222-
void AbcModuleState::extract_cell(RTLIL::Module *module, RTLIL::Cell *cell, bool keepff)
221+
void AbcModuleState::extract_cell(const SigMap &assign_map, RTLIL::Module *module, RTLIL::Cell *cell, bool keepff)
223222
{
224223
if (RTLIL::builtin_ff_cell_types().count(cell->type)) {
225224
FfData ff(&initvals, cell);
@@ -296,7 +295,7 @@ void AbcModuleState::extract_cell(RTLIL::Module *module, RTLIL::Cell *cell, bool
296295
if (c.wire != nullptr)
297296
c.wire->attributes[ID::keep] = 1;
298297

299-
map_signal(ff.sig_q, type, map_signal(ff.sig_d));
298+
map_signal(assign_map, ff.sig_q, type, map_signal(assign_map, ff.sig_d));
300299

301300
ff.remove();
302301
return;
@@ -310,7 +309,7 @@ void AbcModuleState::extract_cell(RTLIL::Module *module, RTLIL::Cell *cell, bool
310309
assign_map.apply(sig_a);
311310
assign_map.apply(sig_y);
312311

313-
map_signal(sig_y, cell->type == ID($_BUF_) ? G(BUF) : G(NOT), map_signal(sig_a));
312+
map_signal(assign_map, sig_y, cell->type == ID($_BUF_) ? G(BUF) : G(NOT), map_signal(assign_map, sig_a));
314313

315314
module->remove(cell);
316315
return;
@@ -326,25 +325,25 @@ void AbcModuleState::extract_cell(RTLIL::Module *module, RTLIL::Cell *cell, bool
326325
assign_map.apply(sig_b);
327326
assign_map.apply(sig_y);
328327

329-
int mapped_a = map_signal(sig_a);
330-
int mapped_b = map_signal(sig_b);
328+
int mapped_a = map_signal(assign_map, sig_a);
329+
int mapped_b = map_signal(assign_map, sig_b);
331330

332331
if (cell->type == ID($_AND_))
333-
map_signal(sig_y, G(AND), mapped_a, mapped_b);
332+
map_signal(assign_map, sig_y, G(AND), mapped_a, mapped_b);
334333
else if (cell->type == ID($_NAND_))
335-
map_signal(sig_y, G(NAND), mapped_a, mapped_b);
334+
map_signal(assign_map, sig_y, G(NAND), mapped_a, mapped_b);
336335
else if (cell->type == ID($_OR_))
337-
map_signal(sig_y, G(OR), mapped_a, mapped_b);
336+
map_signal(assign_map, sig_y, G(OR), mapped_a, mapped_b);
338337
else if (cell->type == ID($_NOR_))
339-
map_signal(sig_y, G(NOR), mapped_a, mapped_b);
338+
map_signal(assign_map, sig_y, G(NOR), mapped_a, mapped_b);
340339
else if (cell->type == ID($_XOR_))
341-
map_signal(sig_y, G(XOR), mapped_a, mapped_b);
340+
map_signal(assign_map, sig_y, G(XOR), mapped_a, mapped_b);
342341
else if (cell->type == ID($_XNOR_))
343-
map_signal(sig_y, G(XNOR), mapped_a, mapped_b);
342+
map_signal(assign_map, sig_y, G(XNOR), mapped_a, mapped_b);
344343
else if (cell->type == ID($_ANDNOT_))
345-
map_signal(sig_y, G(ANDNOT), mapped_a, mapped_b);
344+
map_signal(assign_map, sig_y, G(ANDNOT), mapped_a, mapped_b);
346345
else if (cell->type == ID($_ORNOT_))
347-
map_signal(sig_y, G(ORNOT), mapped_a, mapped_b);
346+
map_signal(assign_map, sig_y, G(ORNOT), mapped_a, mapped_b);
348347
else
349348
log_abort();
350349

@@ -364,11 +363,11 @@ void AbcModuleState::extract_cell(RTLIL::Module *module, RTLIL::Cell *cell, bool
364363
assign_map.apply(sig_s);
365364
assign_map.apply(sig_y);
366365

367-
int mapped_a = map_signal(sig_a);
368-
int mapped_b = map_signal(sig_b);
369-
int mapped_s = map_signal(sig_s);
366+
int mapped_a = map_signal(assign_map, sig_a);
367+
int mapped_b = map_signal(assign_map, sig_b);
368+
int mapped_s = map_signal(assign_map, sig_s);
370369

371-
map_signal(sig_y, cell->type == ID($_MUX_) ? G(MUX) : G(NMUX), mapped_a, mapped_b, mapped_s);
370+
map_signal(assign_map, sig_y, cell->type == ID($_MUX_) ? G(MUX) : G(NMUX), mapped_a, mapped_b, mapped_s);
372371

373372
module->remove(cell);
374373
return;
@@ -386,11 +385,11 @@ void AbcModuleState::extract_cell(RTLIL::Module *module, RTLIL::Cell *cell, bool
386385
assign_map.apply(sig_c);
387386
assign_map.apply(sig_y);
388387

389-
int mapped_a = map_signal(sig_a);
390-
int mapped_b = map_signal(sig_b);
391-
int mapped_c = map_signal(sig_c);
388+
int mapped_a = map_signal(assign_map, sig_a);
389+
int mapped_b = map_signal(assign_map, sig_b);
390+
int mapped_c = map_signal(assign_map, sig_c);
392391

393-
map_signal(sig_y, cell->type == ID($_AOI3_) ? G(AOI3) : G(OAI3), mapped_a, mapped_b, mapped_c);
392+
map_signal(assign_map, sig_y, cell->type == ID($_AOI3_) ? G(AOI3) : G(OAI3), mapped_a, mapped_b, mapped_c);
394393

395394
module->remove(cell);
396395
return;
@@ -410,12 +409,12 @@ void AbcModuleState::extract_cell(RTLIL::Module *module, RTLIL::Cell *cell, bool
410409
assign_map.apply(sig_d);
411410
assign_map.apply(sig_y);
412411

413-
int mapped_a = map_signal(sig_a);
414-
int mapped_b = map_signal(sig_b);
415-
int mapped_c = map_signal(sig_c);
416-
int mapped_d = map_signal(sig_d);
412+
int mapped_a = map_signal(assign_map, sig_a);
413+
int mapped_b = map_signal(assign_map, sig_b);
414+
int mapped_c = map_signal(assign_map, sig_c);
415+
int mapped_d = map_signal(assign_map, sig_d);
417416

418-
map_signal(sig_y, cell->type == ID($_AOI4_) ? G(AOI4) : G(OAI4), mapped_a, mapped_b, mapped_c, mapped_d);
417+
map_signal(assign_map, sig_y, cell->type == ID($_AOI4_) ? G(AOI4) : G(OAI4), mapped_a, mapped_b, mapped_c, mapped_d);
419418

420419
module->remove(cell);
421420
return;
@@ -490,7 +489,13 @@ void AbcModuleState::dump_loop_graph(FILE *f, int &nr, dict<int, pool<int>> &edg
490489
fprintf(f, "}\n");
491490
}
492491

493-
void AbcModuleState::handle_loops(RTLIL::Module *module)
492+
void connect(SigMap &assign_map, RTLIL::Module *module, const RTLIL::SigSig &conn)
493+
{
494+
module->connect(conn);
495+
assign_map.add(conn.first, conn.second);
496+
}
497+
498+
void AbcModuleState::handle_loops(SigMap &assign_map, RTLIL::Module *module)
494499
{
495500
// http://en.wikipedia.org/wiki/Topological_sorting
496501
// (Kahn, Arthur B. (1962), "Topological sorting of large networks")
@@ -595,7 +600,7 @@ void AbcModuleState::handle_loops(RTLIL::Module *module)
595600
first_line = false;
596601
}
597602

598-
int id3 = map_signal(RTLIL::SigSpec(wire));
603+
int id3 = map_signal(assign_map, RTLIL::SigSpec(wire));
599604
signal_list[id1].is_port = true;
600605
signal_list[id3].is_port = true;
601606
log_assert(id3 == int(in_edges_count.size()));
@@ -614,7 +619,7 @@ void AbcModuleState::handle_loops(RTLIL::Module *module)
614619
}
615620
edges[id1].swap(edges[id3]);
616621

617-
module->connect(RTLIL::SigSig(signal_list[id3].bit, signal_list[id1].bit));
622+
connect(assign_map, module, RTLIL::SigSig(signal_list[id3].bit, signal_list[id1].bit));
618623
dump_loop_graph(dot_f, dot_nr, edges, workpool, in_edges_count);
619624
}
620625
}
@@ -750,7 +755,7 @@ struct abc_output_filter
750755
}
751756
};
752757

753-
void AbcModuleState::abc_module(RTLIL::Design *design, RTLIL::Module *module, const std::vector<RTLIL::Cell*> &cells,
758+
void AbcModuleState::abc_module(RTLIL::Design *design, RTLIL::Module *module, SigMap &assign_map, const std::vector<RTLIL::Cell*> &cells,
754759
bool dff_mode, std::string clk_str)
755760
{
756761
initvals.set(&assign_map, module);
@@ -936,33 +941,33 @@ void AbcModuleState::abc_module(RTLIL::Design *design, RTLIL::Module *module, co
936941

937942
had_init = false;
938943
for (auto c : cells)
939-
extract_cell(module, c, config.keepff);
944+
extract_cell(assign_map, module, c, config.keepff);
940945

941946
if (undef_bits_lost)
942947
log("Replacing %d occurrences of constant undef bits with constant zero bits\n", undef_bits_lost);
943948

944949
for (auto wire : module->wires()) {
945950
if (wire->port_id > 0 || wire->get_bool_attribute(ID::keep))
946-
mark_port(wire);
951+
mark_port(assign_map, wire);
947952
}
948953

949954
for (auto cell : module->cells())
950955
for (auto &port_it : cell->connections())
951-
mark_port(port_it.second);
956+
mark_port(assign_map, port_it.second);
952957

953958
if (clk_sig.size() != 0)
954-
mark_port(clk_sig);
959+
mark_port(assign_map, clk_sig);
955960

956961
if (en_sig.size() != 0)
957-
mark_port(en_sig);
962+
mark_port(assign_map, en_sig);
958963

959964
if (arst_sig.size() != 0)
960-
mark_port(arst_sig);
965+
mark_port(assign_map, arst_sig);
961966

962967
if (srst_sig.size() != 0)
963-
mark_port(srst_sig);
968+
mark_port(assign_map, srst_sig);
964969

965-
handle_loops(module);
970+
handle_loops(assign_map, module);
966971

967972
buffer = stringf("%s/input.blif", tempdir_name.c_str());
968973
f = fopen(buffer.c_str(), "wt");
@@ -1205,7 +1210,7 @@ void AbcModuleState::abc_module(RTLIL::Design *design, RTLIL::Module *module, co
12051210
log("Don't call ABC as there is nothing to map.\n");
12061211
}
12071212

1208-
void AbcModuleState::extract(RTLIL::Design *design, RTLIL::Module *module)
1213+
void AbcModuleState::extract(SigMap &assign_map, RTLIL::Design *design, RTLIL::Module *module)
12091214
{
12101215
if (!did_run_abc) {
12111216
return;
@@ -1250,7 +1255,7 @@ void AbcModuleState::extract(RTLIL::Design *design, RTLIL::Module *module)
12501255
RTLIL::IdString name_y = remap_name(c->getPort(ID::Y).as_wire()->name);
12511256
conn.first = module->wire(name_y);
12521257
conn.second = RTLIL::SigSpec(c->type == ID(ZERO) ? 0 : 1, 1);
1253-
module->connect(conn);
1258+
connect(assign_map, module, conn);
12541259
continue;
12551260
}
12561261
if (c->type == ID(BUF)) {
@@ -1259,7 +1264,7 @@ void AbcModuleState::extract(RTLIL::Design *design, RTLIL::Module *module)
12591264
RTLIL::IdString name_a = remap_name(c->getPort(ID::A).as_wire()->name);
12601265
conn.first = module->wire(name_y);
12611266
conn.second = module->wire(name_a);
1262-
module->connect(conn);
1267+
connect(assign_map, module, conn);
12631268
continue;
12641269
}
12651270
if (c->type == ID(NOT)) {
@@ -1391,7 +1396,7 @@ void AbcModuleState::extract(RTLIL::Design *design, RTLIL::Module *module)
13911396
RTLIL::SigSig conn;
13921397
conn.first = module->wire(remap_name(c->connections().begin()->second.as_wire()->name));
13931398
conn.second = RTLIL::SigSpec(c->type == ID(_const0_) ? 0 : 1, 1);
1394-
module->connect(conn);
1399+
connect(assign_map, module, conn);
13951400
continue;
13961401
}
13971402

@@ -1436,7 +1441,7 @@ void AbcModuleState::extract(RTLIL::Design *design, RTLIL::Module *module)
14361441
if (c->type == ID($lut) && GetSize(c->getPort(ID::A)) == 1 && c->getParam(ID::LUT).as_int() == 2) {
14371442
SigSpec my_a = module->wire(remap_name(c->getPort(ID::A).as_wire()->name));
14381443
SigSpec my_y = module->wire(remap_name(c->getPort(ID::Y).as_wire()->name));
1439-
module->connect(my_y, my_a);
1444+
connect(assign_map, module, RTLIL::SigSig(my_a, my_y));
14401445
continue;
14411446
}
14421447

@@ -1461,7 +1466,7 @@ void AbcModuleState::extract(RTLIL::Design *design, RTLIL::Module *module)
14611466
conn.first = module->wire(remap_name(conn.first.as_wire()->name));
14621467
if (!conn.second.is_fully_const())
14631468
conn.second = module->wire(remap_name(conn.second.as_wire()->name));
1464-
module->connect(conn);
1469+
connect(assign_map, module, conn);
14651470
}
14661471

14671472
cell_stats.sort();
@@ -1482,7 +1487,7 @@ void AbcModuleState::extract(RTLIL::Design *design, RTLIL::Module *module)
14821487
conn.second = si.bit;
14831488
in_wires++;
14841489
}
1485-
module->connect(conn);
1490+
connect(assign_map, module, conn);
14861491
}
14871492
log("ABC RESULTS: internal signals: %8d\n", int(signal_list.size()) - in_wires - out_wires);
14881493
log("ABC RESULTS: input signals: %8d\n", in_wires);
@@ -2076,16 +2081,18 @@ struct AbcPass : public Pass {
20762081

20772082
for (auto mod : design->selected_modules())
20782083
{
2084+
SigMap assign_map;
2085+
assign_map.set(mod);
2086+
20792087
if (mod->processes.size() > 0) {
20802088
log("Skipping module %s as it contains processes.\n", log_id(mod));
20812089
continue;
20822090
}
20832091

20842092
if (!dff_mode || !clk_str.empty()) {
20852093
AbcModuleState state(config);
2086-
state.assign_map.set(mod);
2087-
state.abc_module(design, mod, mod->selected_cells(), dff_mode, clk_str);
2088-
state.extract(design, mod);
2094+
state.abc_module(design, mod, assign_map, mod->selected_cells(), dff_mode, clk_str);
2095+
state.extract(assign_map, design, mod);
20892096
state.finish();
20902097
continue;
20912098
}
@@ -2106,8 +2113,6 @@ struct AbcPass : public Pass {
21062113
dict<RTLIL::Cell*, pool<RTLIL::SigBit>> cell_to_bit, cell_to_bit_up, cell_to_bit_down;
21072114
dict<RTLIL::SigBit, pool<RTLIL::Cell*>> bit_to_cell, bit_to_cell_up, bit_to_cell_down;
21082115

2109-
SigMap assign_map;
2110-
assign_map.set(mod);
21112116
FfInitVals initvals;
21122117
initvals.set(&assign_map, mod);
21132118
for (auto cell : all_cells)
@@ -2244,7 +2249,6 @@ struct AbcPass : public Pass {
22442249

22452250
for (auto &it : assigned_cells) {
22462251
AbcModuleState state(config);
2247-
state.assign_map.set(mod);
22482252
state.clk_polarity = std::get<0>(it.first);
22492253
state.clk_sig = assign_map(std::get<1>(it.first));
22502254
state.en_polarity = std::get<2>(it.first);
@@ -2253,8 +2257,8 @@ struct AbcPass : public Pass {
22532257
state.arst_sig = assign_map(std::get<5>(it.first));
22542258
state.srst_polarity = std::get<6>(it.first);
22552259
state.srst_sig = assign_map(std::get<7>(it.first));
2256-
state.abc_module(design, mod, it.second, !state.clk_sig.empty(), "$");
2257-
state.extract(design, mod);
2260+
state.abc_module(design, mod, assign_map, it.second, !state.clk_sig.empty(), "$");
2261+
state.extract(assign_map, design, mod);
22582262
state.finish();
22592263
}
22602264
}

0 commit comments

Comments
 (0)