aboutsummaryrefslogtreecommitdiffstats
path: root/passes
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2017-01-04 18:12:41 +0100
committerClifford Wolf <clifford@clifford.at>2017-01-04 18:12:41 +0100
commit0cac95ea9403befe3dca49621ff577ce13faebf0 (patch)
treee35d2c6f69d34f5d93d4387d67ad0631ea165762 /passes
parent81a9ee2360740dd05e6fc8215abd0e30837f2cda (diff)
downloadyosys-0cac95ea9403befe3dca49621ff577ce13faebf0.tar.gz
yosys-0cac95ea9403befe3dca49621ff577ce13faebf0.tar.bz2
yosys-0cac95ea9403befe3dca49621ff577ce13faebf0.zip
Added "check -initdrv"
Diffstat (limited to 'passes')
-rw-r--r--passes/cmds/check.cc85
1 files changed, 82 insertions, 3 deletions
diff --git a/passes/cmds/check.cc b/passes/cmds/check.cc
index b3622cb19..bb8fe6856 100644
--- a/passes/cmds/check.cc
+++ b/passes/cmds/check.cc
@@ -44,6 +44,9 @@ struct CheckPass : public Pass {
log("When called with -noinit then this command also checks for wires which have\n");
log("the 'init' attribute set.\n");
log("\n");
+ log("When called with -initdrv then this command also checks for wires which have\n");
+ log("the 'init' attribute set and aren't driven by a FF cell type.\n");
+ log("\n");
log("When called with -assert then the command will produce an error if any\n");
log("problems are found in the current design.\n");
log("\n");
@@ -52,6 +55,7 @@ struct CheckPass : public Pass {
{
int counter = 0;
bool noinit = false;
+ bool initdrv = false;
bool assert_mode = false;
size_t argidx;
@@ -60,6 +64,10 @@ struct CheckPass : public Pass {
noinit = true;
continue;
}
+ if (args[argidx] == "-initdrv") {
+ initdrv = true;
+ continue;
+ }
if (args[argidx] == "-assert") {
assert_mode = true;
continue;
@@ -70,6 +78,49 @@ struct CheckPass : public Pass {
log_header(design, "Executing CHECK pass (checking for obvious problems).\n");
+ pool<IdString> fftypes;
+ fftypes.insert("$sr");
+ fftypes.insert("$ff");
+ fftypes.insert("$dff");
+ fftypes.insert("$dffe");
+ fftypes.insert("$dffsr");
+ fftypes.insert("$adff");
+ fftypes.insert("$dlatch");
+ fftypes.insert("$dlatchsr");
+ fftypes.insert("$_DFFE_NN_");
+ fftypes.insert("$_DFFE_NP_");
+ fftypes.insert("$_DFFE_PN_");
+ fftypes.insert("$_DFFE_PP_");
+ fftypes.insert("$_DFFSR_NNN_");
+ fftypes.insert("$_DFFSR_NNP_");
+ fftypes.insert("$_DFFSR_NPN_");
+ fftypes.insert("$_DFFSR_NPP_");
+ fftypes.insert("$_DFFSR_PNN_");
+ fftypes.insert("$_DFFSR_PNP_");
+ fftypes.insert("$_DFFSR_PPN_");
+ fftypes.insert("$_DFFSR_PPP_");
+ fftypes.insert("$_DFF_NN0_");
+ fftypes.insert("$_DFF_NN1_");
+ fftypes.insert("$_DFF_NP0_");
+ fftypes.insert("$_DFF_NP1_");
+ fftypes.insert("$_DFF_N_");
+ fftypes.insert("$_DFF_PN0_");
+ fftypes.insert("$_DFF_PN1_");
+ fftypes.insert("$_DFF_PP0_");
+ fftypes.insert("$_DFF_PP1_");
+ fftypes.insert("$_DFF_P_");
+ fftypes.insert("$_DLATCHSR_NNN_");
+ fftypes.insert("$_DLATCHSR_NNP_");
+ fftypes.insert("$_DLATCHSR_NPN_");
+ fftypes.insert("$_DLATCHSR_NPP_");
+ fftypes.insert("$_DLATCHSR_PNN_");
+ fftypes.insert("$_DLATCHSR_PNP_");
+ fftypes.insert("$_DLATCHSR_PPN_");
+ fftypes.insert("$_DLATCHSR_PPP_");
+ fftypes.insert("$_DLATCH_N_");
+ fftypes.insert("$_DLATCH_P_");
+ fftypes.insert("$_FF_");
+
for (auto module : design->selected_whole_modules_warn())
{
if (module->has_processes_warn())
@@ -109,6 +160,8 @@ struct CheckPass : public Pass {
if (bit.wire) wire_drivers_count[bit]++;
}
+ pool<SigBit> init_bits;
+
for (auto wire : module->wires()) {
if (wire->port_input) {
SigSpec sig = sigmap(wire);
@@ -121,9 +174,15 @@ struct CheckPass : public Pass {
if (wire->port_input && !wire->port_output)
for (auto bit : sigmap(wire))
if (bit.wire) wire_drivers_count[bit]++;
- if (noinit && wire->attributes.count("\\init")) {
- log_warning("Wire %s.%s has an unprocessed 'init' attribute.\n", log_id(module), log_id(wire));
- counter++;
+ if (wire->attributes.count("\\init")) {
+ 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)
+ init_bits.insert(sigmap(SigBit(wire, i)));
+ if (noinit) {
+ log_warning("Wire %s.%s has an unprocessed 'init' attribute.\n", log_id(module), log_id(wire));
+ counter++;
+ }
}
}
@@ -150,6 +209,26 @@ struct CheckPass : public Pass {
log_warning("%s", message.c_str());
counter++;
}
+
+ if (initdrv)
+ {
+ for (auto cell : module->cells())
+ {
+ if (fftypes.count(cell->type) == 0)
+ continue;
+
+ for (auto bit : sigmap(cell->getPort("\\Q")))
+ init_bits.erase(bit);
+ }
+
+ SigSpec init_sig(init_bits);
+ init_sig.sort_and_unify();
+
+ for (auto chunk : init_sig.chunks()) {
+ log_warning("Wire %s.%s has 'init' attribute and is not driven by an FF cell.\n", log_id(module), log_signal(chunk));
+ counter++;
+ }
+ }
}
log("found and reported %d problems.\n", counter);