mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-07 09:55:20 +00:00
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.
This commit is contained in:
parent
9600f20be8
commit
436d42c00c
|
@ -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)
|
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;
|
CellTypes ct_combinational;
|
||||||
ct_combinational.setup_internals();
|
ct_combinational.setup_internals();
|
||||||
ct_combinational.setup_stdcells();
|
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<std::pair<RTLIL::IdString, SigSpec>> 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 {
|
struct OptExprPass : public Pass {
|
||||||
OptExprPass() : Pass("opt_expr", "perform const folding and simple expression rewriting") { }
|
OptExprPass() : Pass("opt_expr", "perform const folding and simple expression rewriting") { }
|
||||||
void help() override
|
void help() override
|
||||||
|
@ -2117,6 +2131,11 @@ struct OptExprPass : public Pass {
|
||||||
design->scratchpad_set_bool("opt.did_something", true);
|
design->scratchpad_set_bool("opt.did_something", true);
|
||||||
} while (did_something);
|
} while (did_something);
|
||||||
|
|
||||||
|
did_something = false;
|
||||||
|
replace_const_connections(module);
|
||||||
|
if (did_something)
|
||||||
|
design->scratchpad_set_bool("opt.did_something", true);
|
||||||
|
|
||||||
log_suppressed();
|
log_suppressed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
8
tests/opt/opt_expr_constconn.v
Normal file
8
tests/opt/opt_expr_constconn.v
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
module top(...);
|
||||||
|
|
||||||
|
input [7:0] A;
|
||||||
|
output [7:0] B;
|
||||||
|
wire [7:0] C = 3;
|
||||||
|
assign B = A + C;
|
||||||
|
|
||||||
|
endmodule
|
7
tests/opt/opt_expr_constconn.ys
Normal file
7
tests/opt/opt_expr_constconn.ys
Normal file
|
@ -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
|
Loading…
Reference in a new issue