Skip to content

Commit ac8259b

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 4de3ee0 commit ac8259b

File tree

1 file changed

+68
-62
lines changed

1 file changed

+68
-62
lines changed

passes/techmap/abc.cc

Lines changed: 68 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);
@@ -291,7 +290,7 @@ void AbcModuleState::extract_cell(RTLIL::Module *module, RTLIL::Cell *cell, bool
291290
return;
292291
}
293292

294-
int gate_id = map_signal(ff.sig_q, type, map_signal(ff.sig_d));
293+
int gate_id = map_signal(assign_map, ff.sig_q, type, map_signal(assign_map, ff.sig_d));
295294
if (keepff) {
296295
SigBit bit = ff.sig_q;
297296
if (assign_map(bit).wire != nullptr) {
@@ -301,6 +300,8 @@ void AbcModuleState::extract_cell(RTLIL::Module *module, RTLIL::Cell *cell, bool
301300
bit.wire->attributes[ID::keep] = 1;
302301
}
303302

303+
map_signal(assign_map, ff.sig_q, type, map_signal(assign_map, ff.sig_d));
304+
304305
ff.remove();
305306
return;
306307
}
@@ -313,7 +314,7 @@ void AbcModuleState::extract_cell(RTLIL::Module *module, RTLIL::Cell *cell, bool
313314
assign_map.apply(sig_a);
314315
assign_map.apply(sig_y);
315316

316-
map_signal(sig_y, cell->type == ID($_BUF_) ? G(BUF) : G(NOT), map_signal(sig_a));
317+
map_signal(assign_map, sig_y, cell->type == ID($_BUF_) ? G(BUF) : G(NOT), map_signal(assign_map, sig_a));
317318

318319
module->remove(cell);
319320
return;
@@ -329,25 +330,25 @@ void AbcModuleState::extract_cell(RTLIL::Module *module, RTLIL::Cell *cell, bool
329330
assign_map.apply(sig_b);
330331
assign_map.apply(sig_y);
331332

332-
int mapped_a = map_signal(sig_a);
333-
int mapped_b = map_signal(sig_b);
333+
int mapped_a = map_signal(assign_map, sig_a);
334+
int mapped_b = map_signal(assign_map, sig_b);
334335

335336
if (cell->type == ID($_AND_))
336-
map_signal(sig_y, G(AND), mapped_a, mapped_b);
337+
map_signal(assign_map, sig_y, G(AND), mapped_a, mapped_b);
337338
else if (cell->type == ID($_NAND_))
338-
map_signal(sig_y, G(NAND), mapped_a, mapped_b);
339+
map_signal(assign_map, sig_y, G(NAND), mapped_a, mapped_b);
339340
else if (cell->type == ID($_OR_))
340-
map_signal(sig_y, G(OR), mapped_a, mapped_b);
341+
map_signal(assign_map, sig_y, G(OR), mapped_a, mapped_b);
341342
else if (cell->type == ID($_NOR_))
342-
map_signal(sig_y, G(NOR), mapped_a, mapped_b);
343+
map_signal(assign_map, sig_y, G(NOR), mapped_a, mapped_b);
343344
else if (cell->type == ID($_XOR_))
344-
map_signal(sig_y, G(XOR), mapped_a, mapped_b);
345+
map_signal(assign_map, sig_y, G(XOR), mapped_a, mapped_b);
345346
else if (cell->type == ID($_XNOR_))
346-
map_signal(sig_y, G(XNOR), mapped_a, mapped_b);
347+
map_signal(assign_map, sig_y, G(XNOR), mapped_a, mapped_b);
347348
else if (cell->type == ID($_ANDNOT_))
348-
map_signal(sig_y, G(ANDNOT), mapped_a, mapped_b);
349+
map_signal(assign_map, sig_y, G(ANDNOT), mapped_a, mapped_b);
349350
else if (cell->type == ID($_ORNOT_))
350-
map_signal(sig_y, G(ORNOT), mapped_a, mapped_b);
351+
map_signal(assign_map, sig_y, G(ORNOT), mapped_a, mapped_b);
351352
else
352353
log_abort();
353354

@@ -367,11 +368,11 @@ void AbcModuleState::extract_cell(RTLIL::Module *module, RTLIL::Cell *cell, bool
367368
assign_map.apply(sig_s);
368369
assign_map.apply(sig_y);
369370

370-
int mapped_a = map_signal(sig_a);
371-
int mapped_b = map_signal(sig_b);
372-
int mapped_s = map_signal(sig_s);
371+
int mapped_a = map_signal(assign_map, sig_a);
372+
int mapped_b = map_signal(assign_map, sig_b);
373+
int mapped_s = map_signal(assign_map, sig_s);
373374

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

376377
module->remove(cell);
377378
return;
@@ -389,11 +390,11 @@ void AbcModuleState::extract_cell(RTLIL::Module *module, RTLIL::Cell *cell, bool
389390
assign_map.apply(sig_c);
390391
assign_map.apply(sig_y);
391392

392-
int mapped_a = map_signal(sig_a);
393-
int mapped_b = map_signal(sig_b);
394-
int mapped_c = map_signal(sig_c);
393+
int mapped_a = map_signal(assign_map, sig_a);
394+
int mapped_b = map_signal(assign_map, sig_b);
395+
int mapped_c = map_signal(assign_map, sig_c);
395396

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

398399
module->remove(cell);
399400
return;
@@ -413,12 +414,12 @@ void AbcModuleState::extract_cell(RTLIL::Module *module, RTLIL::Cell *cell, bool
413414
assign_map.apply(sig_d);
414415
assign_map.apply(sig_y);
415416

416-
int mapped_a = map_signal(sig_a);
417-
int mapped_b = map_signal(sig_b);
418-
int mapped_c = map_signal(sig_c);
419-
int mapped_d = map_signal(sig_d);
417+
int mapped_a = map_signal(assign_map, sig_a);
418+
int mapped_b = map_signal(assign_map, sig_b);
419+
int mapped_c = map_signal(assign_map, sig_c);
420+
int mapped_d = map_signal(assign_map, sig_d);
420421

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

423424
module->remove(cell);
424425
return;
@@ -493,7 +494,13 @@ void AbcModuleState::dump_loop_graph(FILE *f, int &nr, dict<int, pool<int>> &edg
493494
fprintf(f, "}\n");
494495
}
495496

496-
void AbcModuleState::handle_loops(RTLIL::Module *module)
497+
void connect(SigMap &assign_map, RTLIL::Module *module, const RTLIL::SigSig &conn)
498+
{
499+
module->connect(conn);
500+
assign_map.add(conn.first, conn.second);
501+
}
502+
503+
void AbcModuleState::handle_loops(SigMap &assign_map, RTLIL::Module *module)
497504
{
498505
// http://en.wikipedia.org/wiki/Topological_sorting
499506
// (Kahn, Arthur B. (1962), "Topological sorting of large networks")
@@ -598,7 +605,7 @@ void AbcModuleState::handle_loops(RTLIL::Module *module)
598605
first_line = false;
599606
}
600607

601-
int id3 = map_signal(RTLIL::SigSpec(wire));
608+
int id3 = map_signal(assign_map, RTLIL::SigSpec(wire));
602609
signal_list[id1].is_port = true;
603610
signal_list[id3].is_port = true;
604611
log_assert(id3 == int(in_edges_count.size()));
@@ -617,7 +624,7 @@ void AbcModuleState::handle_loops(RTLIL::Module *module)
617624
}
618625
edges[id1].swap(edges[id3]);
619626

620-
module->connect(RTLIL::SigSig(signal_list[id3].bit, signal_list[id1].bit));
627+
connect(assign_map, module, RTLIL::SigSig(signal_list[id3].bit, signal_list[id1].bit));
621628
dump_loop_graph(dot_f, dot_nr, edges, workpool, in_edges_count);
622629
}
623630
}
@@ -753,7 +760,7 @@ struct abc_output_filter
753760
}
754761
};
755762

756-
void AbcModuleState::abc_module(RTLIL::Design *design, RTLIL::Module *module, const std::vector<RTLIL::Cell*> &cells,
763+
void AbcModuleState::abc_module(RTLIL::Design *design, RTLIL::Module *module, SigMap &assign_map, const std::vector<RTLIL::Cell*> &cells,
757764
bool dff_mode, std::string clk_str)
758765
{
759766
initvals.set(&assign_map, module);
@@ -939,33 +946,33 @@ void AbcModuleState::abc_module(RTLIL::Design *design, RTLIL::Module *module, co
939946

940947
had_init = false;
941948
for (auto c : cells)
942-
extract_cell(module, c, config.keepff);
949+
extract_cell(assign_map, module, c, config.keepff);
943950

944951
if (undef_bits_lost)
945952
log("Replacing %d occurrences of constant undef bits with constant zero bits\n", undef_bits_lost);
946953

947954
for (auto wire : module->wires()) {
948955
if (wire->port_id > 0 || wire->get_bool_attribute(ID::keep))
949-
mark_port(wire);
956+
mark_port(assign_map, wire);
950957
}
951958

952959
for (auto cell : module->cells())
953960
for (auto &port_it : cell->connections())
954-
mark_port(port_it.second);
961+
mark_port(assign_map, port_it.second);
955962

956963
if (clk_sig.size() != 0)
957-
mark_port(clk_sig);
964+
mark_port(assign_map, clk_sig);
958965

959966
if (en_sig.size() != 0)
960-
mark_port(en_sig);
967+
mark_port(assign_map, en_sig);
961968

962969
if (arst_sig.size() != 0)
963-
mark_port(arst_sig);
970+
mark_port(assign_map, arst_sig);
964971

965972
if (srst_sig.size() != 0)
966-
mark_port(srst_sig);
973+
mark_port(assign_map, srst_sig);
967974

968-
handle_loops(module);
975+
handle_loops(assign_map, module);
969976

970977
buffer = stringf("%s/input.blif", tempdir_name.c_str());
971978
f = fopen(buffer.c_str(), "wt");
@@ -1208,7 +1215,7 @@ void AbcModuleState::abc_module(RTLIL::Design *design, RTLIL::Module *module, co
12081215
log("Don't call ABC as there is nothing to map.\n");
12091216
}
12101217

1211-
void AbcModuleState::extract(RTLIL::Design *design, RTLIL::Module *module)
1218+
void AbcModuleState::extract(SigMap &assign_map, RTLIL::Design *design, RTLIL::Module *module)
12121219
{
12131220
if (!did_run_abc) {
12141221
return;
@@ -1253,7 +1260,7 @@ void AbcModuleState::extract(RTLIL::Design *design, RTLIL::Module *module)
12531260
RTLIL::IdString name_y = remap_name(c->getPort(ID::Y).as_wire()->name);
12541261
conn.first = module->wire(name_y);
12551262
conn.second = RTLIL::SigSpec(c->type == ID(ZERO) ? 0 : 1, 1);
1256-
module->connect(conn);
1263+
connect(assign_map, module, conn);
12571264
continue;
12581265
}
12591266
if (c->type == ID(BUF)) {
@@ -1262,7 +1269,7 @@ void AbcModuleState::extract(RTLIL::Design *design, RTLIL::Module *module)
12621269
RTLIL::IdString name_a = remap_name(c->getPort(ID::A).as_wire()->name);
12631270
conn.first = module->wire(name_y);
12641271
conn.second = module->wire(name_a);
1265-
module->connect(conn);
1272+
connect(assign_map, module, conn);
12661273
continue;
12671274
}
12681275
if (c->type == ID(NOT)) {
@@ -1394,7 +1401,7 @@ void AbcModuleState::extract(RTLIL::Design *design, RTLIL::Module *module)
13941401
RTLIL::SigSig conn;
13951402
conn.first = module->wire(remap_name(c->connections().begin()->second.as_wire()->name));
13961403
conn.second = RTLIL::SigSpec(c->type == ID(_const0_) ? 0 : 1, 1);
1397-
module->connect(conn);
1404+
connect(assign_map, module, conn);
13981405
continue;
13991406
}
14001407

@@ -1439,7 +1446,7 @@ void AbcModuleState::extract(RTLIL::Design *design, RTLIL::Module *module)
14391446
if (c->type == ID($lut) && GetSize(c->getPort(ID::A)) == 1 && c->getParam(ID::LUT).as_int() == 2) {
14401447
SigSpec my_a = module->wire(remap_name(c->getPort(ID::A).as_wire()->name));
14411448
SigSpec my_y = module->wire(remap_name(c->getPort(ID::Y).as_wire()->name));
1442-
module->connect(my_y, my_a);
1449+
connect(assign_map, module, RTLIL::SigSig(my_a, my_y));
14431450
continue;
14441451
}
14451452

@@ -1464,7 +1471,7 @@ void AbcModuleState::extract(RTLIL::Design *design, RTLIL::Module *module)
14641471
conn.first = module->wire(remap_name(conn.first.as_wire()->name));
14651472
if (!conn.second.is_fully_const())
14661473
conn.second = module->wire(remap_name(conn.second.as_wire()->name));
1467-
module->connect(conn);
1474+
connect(assign_map, module, conn);
14681475
}
14691476

14701477
cell_stats.sort();
@@ -1485,7 +1492,7 @@ void AbcModuleState::extract(RTLIL::Design *design, RTLIL::Module *module)
14851492
conn.second = si.bit;
14861493
in_wires++;
14871494
}
1488-
module->connect(conn);
1495+
connect(assign_map, module, conn);
14891496
}
14901497
log("ABC RESULTS: internal signals: %8d\n", int(signal_list.size()) - in_wires - out_wires);
14911498
log("ABC RESULTS: input signals: %8d\n", in_wires);
@@ -2079,16 +2086,18 @@ struct AbcPass : public Pass {
20792086

20802087
for (auto mod : design->selected_modules())
20812088
{
2089+
SigMap assign_map;
2090+
assign_map.set(mod);
2091+
20822092
if (mod->processes.size() > 0) {
20832093
log("Skipping module %s as it contains processes.\n", log_id(mod));
20842094
continue;
20852095
}
20862096

20872097
if (!dff_mode || !clk_str.empty()) {
20882098
AbcModuleState state(config);
2089-
state.assign_map.set(mod);
2090-
state.abc_module(design, mod, mod->selected_cells(), dff_mode, clk_str);
2091-
state.extract(design, mod);
2099+
state.abc_module(design, mod, assign_map, mod->selected_cells(), dff_mode, clk_str);
2100+
state.extract(assign_map, design, mod);
20922101
state.finish();
20932102
continue;
20942103
}
@@ -2109,8 +2118,6 @@ struct AbcPass : public Pass {
21092118
dict<RTLIL::Cell*, pool<RTLIL::SigBit>> cell_to_bit, cell_to_bit_up, cell_to_bit_down;
21102119
dict<RTLIL::SigBit, pool<RTLIL::Cell*>> bit_to_cell, bit_to_cell_up, bit_to_cell_down;
21112120

2112-
SigMap assign_map;
2113-
assign_map.set(mod);
21142121
FfInitVals initvals;
21152122
initvals.set(&assign_map, mod);
21162123
for (auto cell : all_cells)
@@ -2247,7 +2254,6 @@ struct AbcPass : public Pass {
22472254

22482255
for (auto &it : assigned_cells) {
22492256
AbcModuleState state(config);
2250-
state.assign_map.set(mod);
22512257
state.clk_polarity = std::get<0>(it.first);
22522258
state.clk_sig = assign_map(std::get<1>(it.first));
22532259
state.en_polarity = std::get<2>(it.first);
@@ -2256,8 +2262,8 @@ struct AbcPass : public Pass {
22562262
state.arst_sig = assign_map(std::get<5>(it.first));
22572263
state.srst_polarity = std::get<6>(it.first);
22582264
state.srst_sig = assign_map(std::get<7>(it.first));
2259-
state.abc_module(design, mod, it.second, !state.clk_sig.empty(), "$");
2260-
state.extract(design, mod);
2265+
state.abc_module(design, mod, assign_map, it.second, !state.clk_sig.empty(), "$");
2266+
state.extract(assign_map, design, mod);
22612267
state.finish();
22622268
}
22632269
}

0 commit comments

Comments
 (0)