From: Icenowy Zheng Date: Tue, 18 Dec 2018 15:10:40 +0000 (+0800) Subject: Add "dffinit -noreinit" parameter X-Git-Tag: yosys-0.9~349^2^2~1 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=256fb8c95c3b974fb636f515297191a6fc70b356;p=yosys.git Add "dffinit -noreinit" parameter Sometimes the FF cell might be initialized during the map process, e.g. some FPGA platforms (Anlogic Eagle and Lattice ECP5 for example) has only a "SR" pin for a FF for async reset, that resets the FF to the initial value, which means the async reset value should be set as the initial value. In this case the DFFINIT pass shouldn't reinitialize it to a different value, which will lead to error. Add a "-noreinit" parameter for the safeguard. If a FF is not technically initialized before DFFINIT pass, the default value should be set to x. Signed-off-by: Icenowy Zheng --- diff --git a/passes/techmap/dffinit.cc b/passes/techmap/dffinit.cc index 4fa15a35b..48390488e 100644 --- a/passes/techmap/dffinit.cc +++ b/passes/techmap/dffinit.cc @@ -48,13 +48,18 @@ struct DffinitPass : public Pass { log(" initial value of 1 or 0. (multi-bit values are not supported in this\n"); log(" mode.)\n"); log("\n"); + log(" -noreinit\n"); + log(" fail if the FF cell has already a defined initial value set in other\n"); + log(" passes and the initial value of the net it drives is not equal to\n"); + log(" the already defined initial value.\n"); + log("\n"); } void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE { log_header(design, "Executing DFFINIT pass (set INIT param on FF cells).\n"); dict> ff_types; - bool highlow_mode = false; + bool highlow_mode = false, noreinit = false; std::string high_string, low_string; size_t argidx; @@ -78,6 +83,10 @@ struct DffinitPass : public Pass { ff_types[cell_name][output_port] = init_param; continue; } + if (args[argidx] == "-noreinit") { + noreinit = true; + continue; + } break; } extra_args(args, argidx, design); @@ -126,6 +135,10 @@ struct DffinitPass : public Pass { continue; while (GetSize(value.bits) <= i) value.bits.push_back(State::S0); + if (noreinit && value.bits[i] != State::Sx && value.bits[i] != init_bits.at(sig[i])) + log_error("Trying to assign a different init value for %s.%s.%s which technically " + "have a conflicted init value.\n", + log_id(module), log_id(cell), log_id(it.second)); value.bits[i] = init_bits.at(sig[i]); cleanup_bits.insert(sig[i]); }