aboutsummaryrefslogtreecommitdiffstats
path: root/passes
diff options
context:
space:
mode:
authorIcenowy Zheng <icenowy@aosc.io>2018-12-18 23:10:40 +0800
committerIcenowy Zheng <icenowy@aosc.io>2018-12-18 23:10:40 +0800
commit256fb8c95c3b974fb636f515297191a6fc70b356 (patch)
tree022e27ea57ffb2de990fb4821715d2a3230470bd /passes
parentfec8b3c81ffcf1f8a27e79250c05b6ea91571bbe (diff)
downloadyosys-256fb8c95c3b974fb636f515297191a6fc70b356.tar.gz
yosys-256fb8c95c3b974fb636f515297191a6fc70b356.tar.bz2
yosys-256fb8c95c3b974fb636f515297191a6fc70b356.zip
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 <icenowy@aosc.io>
Diffstat (limited to 'passes')
-rw-r--r--passes/techmap/dffinit.cc15
1 files changed, 14 insertions, 1 deletions
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<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
log_header(design, "Executing DFFINIT pass (set INIT param on FF cells).\n");
dict<IdString, dict<IdString, IdString>> 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]);
}