mirror of
https://github.com/YosysHQ/yosys.git
synced 2026-10-06 10:03:36 +02:00
Merge branch 'main' into nella/cell-rank
This commit is contained in:
+45
-38
@@ -297,9 +297,11 @@ struct AbcModuleState {
|
||||
RunAbcState run_abc;
|
||||
|
||||
int state_index;
|
||||
int map_autoidx = 0;
|
||||
int map_autoidx;
|
||||
std::vector<RTLIL::SigBit> signal_bits;
|
||||
dict<RTLIL::SigBit, int> signal_map;
|
||||
// Deletions are deferred until extract for multi-threaded determinism
|
||||
std::vector<RTLIL::Cell*> cells_to_remove;
|
||||
FfInitVals &initvals;
|
||||
bool had_init = false;
|
||||
|
||||
@@ -311,19 +313,19 @@ struct AbcModuleState {
|
||||
|
||||
int undef_bits_lost = 0;
|
||||
|
||||
AbcModuleState(const AbcConfig &config, FfInitVals &initvals, int state_index)
|
||||
: run_abc(config), state_index(state_index), initvals(initvals) {}
|
||||
AbcModuleState(const AbcConfig &config, FfInitVals &initvals, int state_index, int map_autoidx)
|
||||
: run_abc(config), state_index(state_index), map_autoidx(map_autoidx), initvals(initvals) {}
|
||||
AbcModuleState(AbcModuleState&&) = delete;
|
||||
|
||||
int map_signal(const AbcSigMap &assign_map, RTLIL::SigBit bit, gate_type_t gate_type = G(NONE), int in1 = -1, int in2 = -1, int in3 = -1, int in4 = -1);
|
||||
void mark_port(const AbcSigMap &assign_map, RTLIL::SigSpec sig);
|
||||
bool extract_cell(const AbcSigMap &assign_map, RTLIL::Module *module, RTLIL::Cell *cell, bool keepff);
|
||||
bool prepare_cell(const AbcSigMap &assign_map, RTLIL::Cell *cell, bool keepff);
|
||||
std::string remap_name(RTLIL::IdString abc_name, RTLIL::Wire **orig_wire = nullptr);
|
||||
void dump_loop_graph(FILE *f, int &nr, dict<int, pool<int>> &edges, pool<int> &workpool, std::vector<int> &in_counts);
|
||||
void handle_loops(AbcSigMap &assign_map, RTLIL::Module *module);
|
||||
void prepare_module(RTLIL::Design *design, RTLIL::Module *module, AbcSigMap &assign_map, const std::vector<RTLIL::Cell*> &cells,
|
||||
bool dff_mode, std::string clk_str);
|
||||
void extract(AbcSigMap &assign_map, RTLIL::Design *design, RTLIL::Module *module);
|
||||
void extract(RTLIL::Design *design, RTLIL::Module *module);
|
||||
void finish();
|
||||
};
|
||||
|
||||
@@ -375,7 +377,7 @@ void AbcModuleState::mark_port(const AbcSigMap &assign_map, RTLIL::SigSpec sig)
|
||||
run_abc.signal_list[signal_map[bit]].is_port = true;
|
||||
}
|
||||
|
||||
bool AbcModuleState::extract_cell(const AbcSigMap &assign_map, RTLIL::Module *module, RTLIL::Cell *cell, bool keepff)
|
||||
bool AbcModuleState::prepare_cell(const AbcSigMap &assign_map, RTLIL::Cell *cell, bool keepff)
|
||||
{
|
||||
if (cell->is_builtin_ff()) {
|
||||
FfData ff(&initvals, cell);
|
||||
@@ -459,7 +461,8 @@ bool AbcModuleState::extract_cell(const AbcSigMap &assign_map, RTLIL::Module *mo
|
||||
|
||||
map_signal(assign_map, ff.sig_q, type, map_signal(assign_map, ff.sig_d));
|
||||
|
||||
ff.remove();
|
||||
ff.remove_init();
|
||||
cells_to_remove.push_back(cell);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -473,7 +476,7 @@ bool AbcModuleState::extract_cell(const AbcSigMap &assign_map, RTLIL::Module *mo
|
||||
|
||||
map_signal(assign_map, sig_y, cell->type == ID($_BUF_) ? G(BUF) : G(NOT), map_signal(assign_map, sig_a));
|
||||
|
||||
module->remove(cell);
|
||||
cells_to_remove.push_back(cell);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -509,7 +512,7 @@ bool AbcModuleState::extract_cell(const AbcSigMap &assign_map, RTLIL::Module *mo
|
||||
else
|
||||
log_abort();
|
||||
|
||||
module->remove(cell);
|
||||
cells_to_remove.push_back(cell);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -531,7 +534,7 @@ bool AbcModuleState::extract_cell(const AbcSigMap &assign_map, RTLIL::Module *mo
|
||||
|
||||
map_signal(assign_map, sig_y, cell->type == ID($_MUX_) ? G(MUX) : G(NMUX), mapped_a, mapped_b, mapped_s);
|
||||
|
||||
module->remove(cell);
|
||||
cells_to_remove.push_back(cell);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -553,7 +556,7 @@ bool AbcModuleState::extract_cell(const AbcSigMap &assign_map, RTLIL::Module *mo
|
||||
|
||||
map_signal(assign_map, sig_y, cell->type == ID($_AOI3_) ? G(AOI3) : G(OAI3), mapped_a, mapped_b, mapped_c);
|
||||
|
||||
module->remove(cell);
|
||||
cells_to_remove.push_back(cell);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -578,7 +581,7 @@ bool AbcModuleState::extract_cell(const AbcSigMap &assign_map, RTLIL::Module *mo
|
||||
|
||||
map_signal(assign_map, sig_y, cell->type == ID($_AOI4_) ? G(AOI4) : G(OAI4), mapped_a, mapped_b, mapped_c, mapped_d);
|
||||
|
||||
module->remove(cell);
|
||||
cells_to_remove.push_back(cell);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -653,12 +656,6 @@ void AbcModuleState::dump_loop_graph(FILE *f, int &nr, dict<int, pool<int>> &edg
|
||||
fprintf(f, "}\n");
|
||||
}
|
||||
|
||||
void connect(AbcSigMap &assign_map, RTLIL::Module *module, const RTLIL::SigSig &conn)
|
||||
{
|
||||
module->connect(conn);
|
||||
assign_map.add(conn.first, conn.second);
|
||||
}
|
||||
|
||||
void AbcModuleState::handle_loops(AbcSigMap &assign_map, RTLIL::Module *module)
|
||||
{
|
||||
// http://en.wikipedia.org/wiki/Topological_sorting
|
||||
@@ -670,6 +667,8 @@ void AbcModuleState::handle_loops(AbcSigMap &assign_map, RTLIL::Module *module)
|
||||
|
||||
FILE *dot_f = nullptr;
|
||||
int dot_nr = 0;
|
||||
// Avoids mutating autoidx for multi-threaded determinism
|
||||
int loop_count = 0;
|
||||
|
||||
// uncomment for troubleshooting the loop detection code
|
||||
// dot_f = fopen("test.dot", "w");
|
||||
@@ -749,9 +748,7 @@ void AbcModuleState::handle_loops(AbcSigMap &assign_map, RTLIL::Module *module)
|
||||
|
||||
log_assert(signal_bits[id1].wire != nullptr);
|
||||
|
||||
std::stringstream sstr;
|
||||
sstr << "$abcloop$" << (autoidx++);
|
||||
RTLIL::Wire *wire = module->addWire(sstr.str());
|
||||
RTLIL::Wire *wire = module->addWire(stringf("$abcloop$%d$%d", map_autoidx, loop_count++));
|
||||
|
||||
bool first_line = true;
|
||||
for (int id2 : edges[id1]) {
|
||||
@@ -783,7 +780,9 @@ void AbcModuleState::handle_loops(AbcSigMap &assign_map, RTLIL::Module *module)
|
||||
}
|
||||
edges[id1].swap(edges[id3]);
|
||||
|
||||
connect(assign_map, module, RTLIL::SigSig(signal_bits[id3], signal_bits[id1]));
|
||||
auto conn = SigSig(signal_bits[id3], signal_bits[id1]);
|
||||
module->connect(conn);
|
||||
assign_map.add(conn.first, conn.second);
|
||||
dump_loop_graph(dot_f, dot_nr, edges, workpool, in_edges_count);
|
||||
}
|
||||
}
|
||||
@@ -930,8 +929,6 @@ struct abc_output_filter
|
||||
void AbcModuleState::prepare_module(RTLIL::Design *design, RTLIL::Module *module, AbcSigMap &assign_map, const std::vector<RTLIL::Cell*> &cells,
|
||||
bool dff_mode, std::string clk_str)
|
||||
{
|
||||
map_autoidx = autoidx++;
|
||||
|
||||
if (clk_str != "$")
|
||||
{
|
||||
clk_polarity = true;
|
||||
@@ -1124,7 +1121,7 @@ void AbcModuleState::prepare_module(RTLIL::Design *design, RTLIL::Module *module
|
||||
had_init = false;
|
||||
std::vector<RTLIL::Cell *> kept_cells;
|
||||
for (auto c : cells)
|
||||
if (!extract_cell(assign_map, module, c, config.keepff))
|
||||
if (!prepare_cell(assign_map, c, config.keepff))
|
||||
kept_cells.push_back(c);
|
||||
|
||||
if (undef_bits_lost)
|
||||
@@ -1132,7 +1129,7 @@ void AbcModuleState::prepare_module(RTLIL::Design *design, RTLIL::Module *module
|
||||
|
||||
// Wires with port_id > 0, ID::keep, and connections to cells outside our cell set have already
|
||||
// been accounted for via AbcSigVal::is_port. Now we just need to account for
|
||||
// connections to cells inside our cell set that weren't removed by extract_cell().
|
||||
// connections to cells inside our cell set that weren't removed by prepare_cell().
|
||||
for (auto cell : kept_cells)
|
||||
for (auto &port_it : cell->connections())
|
||||
mark_port(assign_map, port_it.second);
|
||||
@@ -1506,8 +1503,12 @@ void emit_global_input_files(const AbcConfig &config)
|
||||
}
|
||||
}
|
||||
|
||||
void AbcModuleState::extract(AbcSigMap &assign_map, RTLIL::Design *design, RTLIL::Module *module)
|
||||
void AbcModuleState::extract(RTLIL::Design *design, RTLIL::Module *module)
|
||||
{
|
||||
for (RTLIL::Cell *cell : cells_to_remove)
|
||||
module->remove(cell);
|
||||
cells_to_remove.clear();
|
||||
|
||||
log_push();
|
||||
log_header(design, "Executed ABC.\n");
|
||||
run_abc.logs.flush();
|
||||
@@ -1556,7 +1557,7 @@ void AbcModuleState::extract(AbcSigMap &assign_map, RTLIL::Design *design, RTLIL
|
||||
RTLIL::IdString name_y = remap_name(c->getPort(ID::Y).as_wire()->name);
|
||||
conn.first = module->wire(name_y);
|
||||
conn.second = RTLIL::SigSpec(c->type == ID(ZERO) ? 0 : 1, 1);
|
||||
connect(assign_map, module, conn);
|
||||
module->connect(conn);
|
||||
continue;
|
||||
}
|
||||
if (c->type == ID(BUF)) {
|
||||
@@ -1565,7 +1566,7 @@ void AbcModuleState::extract(AbcSigMap &assign_map, RTLIL::Design *design, RTLIL
|
||||
RTLIL::IdString name_a = remap_name(c->getPort(ID::A).as_wire()->name);
|
||||
conn.first = module->wire(name_y);
|
||||
conn.second = module->wire(name_a);
|
||||
connect(assign_map, module, conn);
|
||||
module->connect(conn);
|
||||
continue;
|
||||
}
|
||||
if (c->type == ID(NOT)) {
|
||||
@@ -1697,7 +1698,7 @@ void AbcModuleState::extract(AbcSigMap &assign_map, RTLIL::Design *design, RTLIL
|
||||
RTLIL::SigSig conn;
|
||||
conn.first = module->wire(remap_name(c->connections().begin()->second.as_wire()->name));
|
||||
conn.second = RTLIL::SigSpec(c->type == ID(_const0_) ? 0 : 1, 1);
|
||||
connect(assign_map, module, conn);
|
||||
module->connect(conn);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1742,7 +1743,7 @@ void AbcModuleState::extract(AbcSigMap &assign_map, RTLIL::Design *design, RTLIL
|
||||
if (c->type == ID($lut) && GetSize(c->getPort(ID::A)) == 1 && c->getParam(ID::LUT).as_int() == 2) {
|
||||
SigSpec my_a = module->wire(remap_name(c->getPort(ID::A).as_wire()->name));
|
||||
SigSpec my_y = module->wire(remap_name(c->getPort(ID::Y).as_wire()->name));
|
||||
connect(assign_map, module, RTLIL::SigSig(my_a, my_y));
|
||||
module->connect(RTLIL::SigSig(my_a, my_y));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1767,7 +1768,7 @@ void AbcModuleState::extract(AbcSigMap &assign_map, RTLIL::Design *design, RTLIL
|
||||
conn.first = module->wire(remap_name(conn.first.as_wire()->name));
|
||||
if (!conn.second.is_fully_const())
|
||||
conn.second = module->wire(remap_name(conn.second.as_wire()->name));
|
||||
connect(assign_map, module, conn);
|
||||
module->connect(conn);
|
||||
}
|
||||
|
||||
cell_stats.sort();
|
||||
@@ -1788,7 +1789,7 @@ void AbcModuleState::extract(AbcSigMap &assign_map, RTLIL::Design *design, RTLIL
|
||||
conn.second = signal_bits[si.id];
|
||||
in_wires++;
|
||||
}
|
||||
connect(assign_map, module, conn);
|
||||
module->connect(conn);
|
||||
}
|
||||
log("ABC RESULTS: internal signals: %8d\n", int(run_abc.signal_list.size()) - in_wires - out_wires);
|
||||
log("ABC RESULTS: input signals: %8d\n", in_wires);
|
||||
@@ -2397,11 +2398,11 @@ struct AbcPass : public Pass {
|
||||
std::vector<RTLIL::Cell*> cells = mod->selected_cells();
|
||||
assign_cell_connection_ports(mod, {&cells}, assign_map);
|
||||
|
||||
AbcModuleState state(config, initvals, 0);
|
||||
AbcModuleState state(config, initvals, 0, autoidx++);
|
||||
state.prepare_module(design, mod, assign_map, cells, dff_mode, clk_str);
|
||||
ConcurrentStack<AbcProcess> process_pool;
|
||||
state.run_abc.run(process_pool);
|
||||
state.extract(assign_map, design, mod);
|
||||
state.extract(design, mod);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2559,6 +2560,10 @@ struct AbcPass : public Pass {
|
||||
assign_cell_connection_ports(mod, cell_sets, assign_map);
|
||||
}
|
||||
|
||||
// Advance autoidx by the clock domain count for multi-threaded determinism
|
||||
int autoidx_base = autoidx;
|
||||
autoidx.ensure_at_least(autoidx_base + GetSize(assigned_cells));
|
||||
|
||||
// Reserve one core for our main thread, and don't create more worker threads
|
||||
// than ABC runs.
|
||||
int max_threads = assigned_cells.size();
|
||||
@@ -2596,11 +2601,12 @@ struct AbcPass : public Pass {
|
||||
++work_finished_count;
|
||||
}
|
||||
while (work_finished_by_index[next_state_index_to_process] != nullptr) {
|
||||
work_finished_by_index[next_state_index_to_process]->extract(assign_map, design, mod);
|
||||
work_finished_by_index[next_state_index_to_process]->extract(design, mod);
|
||||
work_finished_by_index[next_state_index_to_process] = nullptr;
|
||||
++next_state_index_to_process;
|
||||
}
|
||||
std::unique_ptr<AbcModuleState> state = std::make_unique<AbcModuleState>(config, initvals, state_index++);
|
||||
std::unique_ptr<AbcModuleState> state = std::make_unique<AbcModuleState>(
|
||||
config, initvals, state_index, autoidx_base + state_index);
|
||||
state->clk_polarity = std::get<0>(it.first);
|
||||
state->clk_sig = assign_map(std::get<1>(it.first));
|
||||
state->en_polarity = std::get<2>(it.first);
|
||||
@@ -2617,6 +2623,7 @@ struct AbcPass : public Pass {
|
||||
state->run_abc.run(process_pool);
|
||||
work_finished_queue.push_back(std::move(state));
|
||||
}
|
||||
state_index++;
|
||||
}
|
||||
work_queue.close();
|
||||
while (work_finished_count < GetSize(assigned_cells)) {
|
||||
@@ -2626,7 +2633,7 @@ struct AbcPass : public Pass {
|
||||
++work_finished_count;
|
||||
}
|
||||
while (next_state_index_to_process < GetSize(work_finished_by_index)) {
|
||||
work_finished_by_index[next_state_index_to_process]->extract(assign_map, design, mod);
|
||||
work_finished_by_index[next_state_index_to_process]->extract(design, mod);
|
||||
work_finished_by_index[next_state_index_to_process] = nullptr;
|
||||
++next_state_index_to_process;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user