From 9d117eba9d65cf978716f1c7d41e86466ca03fc6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 30 Apr 2019 14:46:12 +0200 Subject: [PATCH] Add handling of init attributes in "opt_expr -undriven" Signed-off-by: Clifford Wolf --- passes/opt/opt_expr.cc | 43 +++++++++++++++++++++++++++++++++++-- techlibs/ecp5/synth_ecp5.cc | 2 +- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index af6d352af..b445afdc8 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -39,6 +39,9 @@ void replace_undriven(RTLIL::Design *design, RTLIL::Module *module) SigPool used_signals; SigPool all_signals; + dict> initbits; + pool revisit_initwires; + for (auto cell : module->cells()) for (auto &conn : cell->connections()) { if (!ct.cell_known(cell->type) || ct.cell_output(cell->type, conn.first)) @@ -48,6 +51,14 @@ void replace_undriven(RTLIL::Design *design, RTLIL::Module *module) } for (auto wire : module->wires()) { + if (wire->attributes.count("\\init")) { + SigSpec sig = sigmap(wire); + Const initval = wire->attributes.at("\\init"); + for (int i = 0; i < GetSize(initval) && i < GetSize(wire); i++) { + if (initval[i] == State::S0 || initval[i] == State::S1) + initbits[sig[i]] = make_pair(wire, initval[i]); + } + } if (wire->port_input) driven_signals.add(sigmap(wire)); if (wire->port_output) @@ -67,10 +78,38 @@ void replace_undriven(RTLIL::Design *design, RTLIL::Module *module) if (sig.size() == 0) continue; - log_debug("Setting undriven signal in %s to undef: %s\n", RTLIL::id2cstr(module->name), log_signal(c)); - module->connect(RTLIL::SigSig(c, RTLIL::SigSpec(RTLIL::State::Sx, c.width))); + Const val(RTLIL::State::Sx, GetSize(sig)); + for (int i = 0; i < GetSize(sig); i++) { + SigBit bit = sigmap(sig[i]); + auto cursor = initbits.find(bit); + if (cursor != initbits.end()) { + revisit_initwires.insert(cursor->second.first); + val[i] = cursor->second.second; + } + } + + log_debug("Setting undriven signal in %s to constant: %s = %s\n", RTLIL::id2cstr(module->name), log_signal(sig), log_signal(val)); + module->connect(sig, val); did_something = true; } + + if (!revisit_initwires.empty()) + { + SigMap sm2(module); + + for (auto wire : revisit_initwires) { + SigSpec sig = sm2(wire); + Const initval = wire->attributes.at("\\init"); + for (int i = 0; i < GetSize(initval) && i < GetSize(wire); i++) { + if (SigBit(initval[i]) == sig[i]) + initval[i] = State::Sx; + } + if (initval.is_fully_undef()) + wire->attributes.erase("\\init"); + else + wire->attributes["\\init"] = initval; + } + } } void replace_cell(SigMap &assign_map, RTLIL::Module *module, RTLIL::Cell *cell, std::string info, std::string out_port, RTLIL::SigSpec out_val) diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc index 4b889d672..c6e12248e 100644 --- a/techlibs/ecp5/synth_ecp5.cc +++ b/techlibs/ecp5/synth_ecp5.cc @@ -253,7 +253,7 @@ struct SynthEcp5Pass : public ScriptPass if (!nodffe) run("dff2dffe -direct-match $_DFF_* -direct-match $__DFFS_*"); run("techmap -D NO_LUT -map +/ecp5/cells_map.v"); - run("opt_expr -mux_undef"); + run("opt_expr -undriven -mux_undef"); run("simplemap"); run("ecp5_ffinit"); } -- 2.30.2