From 436d42c00c2bf1b2eaf84ada388d8aaab65da086 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Tue, 27 Jul 2021 15:24:48 +0200 Subject: [PATCH] opt_expr: Propagate constants to port connections. This adds one simple piece of functionality to opt_expr: when a cell port is connected to a fully-constant signal (as determined by sigmap), the port is reconnected directly to the constant value. This is just enough optimization to fix the "non-constant $meminit input" problem without requiring a full opt_clean or a separate pass. --- passes/opt/opt_expr.cc | 25 ++++++++++++++++++++++--- tests/opt/opt_expr_constconn.v | 8 ++++++++ tests/opt/opt_expr_constconn.ys | 7 +++++++ 3 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 tests/opt/opt_expr_constconn.v create mode 100644 tests/opt/opt_expr_constconn.ys diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index 709cb6020..b7bbb2adf 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -395,9 +395,6 @@ int get_highest_hot_index(RTLIL::SigSpec signal) void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool consume_x, bool mux_undef, bool mux_bool, bool do_fine, bool keepdc, bool noclkinv) { - if (!design->selected(module)) - return; - CellTypes ct_combinational; ct_combinational.setup_internals(); ct_combinational.setup_stdcells(); @@ -2007,6 +2004,23 @@ skip_alu_split: } } +void replace_const_connections(RTLIL::Module *module) { + SigMap assign_map(module); + for (auto cell : module->selected_cells()) + { + std::vector> changes; + for (auto &conn : cell->connections()) { + SigSpec mapped = assign_map(conn.second); + if (conn.second != mapped && mapped.is_fully_const()) + changes.push_back({conn.first, mapped}); + } + if (!changes.empty()) + did_something = true; + for (auto &it : changes) + cell->setPort(it.first, it.second); + } +} + struct OptExprPass : public Pass { OptExprPass() : Pass("opt_expr", "perform const folding and simple expression rewriting") { } void help() override @@ -2117,6 +2131,11 @@ struct OptExprPass : public Pass { design->scratchpad_set_bool("opt.did_something", true); } while (did_something); + did_something = false; + replace_const_connections(module); + if (did_something) + design->scratchpad_set_bool("opt.did_something", true); + log_suppressed(); } diff --git a/tests/opt/opt_expr_constconn.v b/tests/opt/opt_expr_constconn.v new file mode 100644 index 000000000..d18b120e3 --- /dev/null +++ b/tests/opt/opt_expr_constconn.v @@ -0,0 +1,8 @@ +module top(...); + +input [7:0] A; +output [7:0] B; +wire [7:0] C = 3; +assign B = A + C; + +endmodule diff --git a/tests/opt/opt_expr_constconn.ys b/tests/opt/opt_expr_constconn.ys new file mode 100644 index 000000000..9dd848a4b --- /dev/null +++ b/tests/opt/opt_expr_constconn.ys @@ -0,0 +1,7 @@ +read_verilog opt_expr_constconn.v +select -assert-count 1 t:$add +select -assert-count 1 t:$add %ci w:C %i +equiv_opt -assert opt_expr +design -load postopt +select -assert-count 1 t:$add +select -assert-count 0 t:$add %ci w:C %i -- 2.30.2