diff --git a/passes/hierarchy/flatten.cc b/passes/hierarchy/flatten.cc index e0dec47f1..5ad6e506a 100644 --- a/passes/hierarchy/flatten.cc +++ b/passes/hierarchy/flatten.cc @@ -20,6 +20,7 @@ #include "kernel/yosys.h" #include "kernel/utils.h" #include "kernel/sigtools.h" +#include "kernel/ffinit.h" #include #include @@ -264,7 +265,7 @@ struct FlattenWorker log_error("Cell port %s.%s.%s is driving constant bits: %s <= %s\n", module, cell, port_it.first.unescape(), log_signal(new_conn.first), log_signal(new_conn.second)); - if (barriers) { + if (barriers && !(tpl_wire->port_input && tpl_wire->port_output)) { // Drive public output wires with barriers and the rest with // connections RTLIL::SigSig skip_conn, barrier_conn; @@ -272,7 +273,7 @@ struct FlattenWorker for (int i = 0; i < GetSize(new_conn.first); i++) { const auto lhs = new_conn.first[i], rhs = new_conn.second[i]; log_assert(lhs.is_wire()); - auto& sigsig = !lhs.wire->name.isPublic() ? skip_conn : barrier_conn; + auto& sigsig = !lhs.wire->name.isPublic() || lhs.wire->port_input ? skip_conn : barrier_conn; sigsig.first.append(lhs); sigsig.second.append(rhs); } @@ -349,6 +350,12 @@ struct FlattenWorker // individual modules, this isn't the case, and the newly added cells might have to be flattened further. flatten_cell(design, module, cell, tpl, sigmap, worklist, separator); } + + if (barriers) { + SigMap init_sigmap(module); + FfInitVals initvals(&init_sigmap, module); + initvals.move_barrier_inits(module); + } } }; @@ -428,6 +435,7 @@ struct FlattenPass : public Pass { } if (args[argidx] == "-nocleanup") { cleanup = false; + continue; } if (args[argidx] == "-barriers") { worker.barriers = true; diff --git a/tests/various/barrier_flatten_prep.ys b/tests/various/barrier_flatten_prep.ys new file mode 100644 index 000000000..24142bf30 --- /dev/null +++ b/tests/various/barrier_flatten_prep.ys @@ -0,0 +1,160 @@ +# port connections that drive a public wire get a barrier +# port connections that drive a private wire get a plain connection + +read_rtlil <