Added "check -initdrv"

This commit is contained in:
Clifford Wolf 2017-01-04 18:12:41 +01:00
parent 81a9ee2360
commit 0cac95ea94
1 changed files with 82 additions and 3 deletions

View File

@ -44,6 +44,9 @@ struct CheckPass : public Pass {
log("When called with -noinit then this command also checks for wires which have\n"); log("When called with -noinit then this command also checks for wires which have\n");
log("the 'init' attribute set.\n"); log("the 'init' attribute set.\n");
log("\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("When called with -assert then the command will produce an error if any\n");
log("problems are found in the current design.\n"); log("problems are found in the current design.\n");
log("\n"); log("\n");
@ -52,6 +55,7 @@ struct CheckPass : public Pass {
{ {
int counter = 0; int counter = 0;
bool noinit = false; bool noinit = false;
bool initdrv = false;
bool assert_mode = false; bool assert_mode = false;
size_t argidx; size_t argidx;
@ -60,6 +64,10 @@ struct CheckPass : public Pass {
noinit = true; noinit = true;
continue; continue;
} }
if (args[argidx] == "-initdrv") {
initdrv = true;
continue;
}
if (args[argidx] == "-assert") { if (args[argidx] == "-assert") {
assert_mode = true; assert_mode = true;
continue; continue;
@ -70,6 +78,49 @@ struct CheckPass : public Pass {
log_header(design, "Executing CHECK pass (checking for obvious problems).\n"); 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()) for (auto module : design->selected_whole_modules_warn())
{ {
if (module->has_processes_warn()) if (module->has_processes_warn())
@ -109,6 +160,8 @@ struct CheckPass : public Pass {
if (bit.wire) wire_drivers_count[bit]++; if (bit.wire) wire_drivers_count[bit]++;
} }
pool<SigBit> init_bits;
for (auto wire : module->wires()) { for (auto wire : module->wires()) {
if (wire->port_input) { if (wire->port_input) {
SigSpec sig = sigmap(wire); SigSpec sig = sigmap(wire);
@ -121,9 +174,15 @@ struct CheckPass : public Pass {
if (wire->port_input && !wire->port_output) if (wire->port_input && !wire->port_output)
for (auto bit : sigmap(wire)) for (auto bit : sigmap(wire))
if (bit.wire) wire_drivers_count[bit]++; if (bit.wire) wire_drivers_count[bit]++;
if (noinit && wire->attributes.count("\\init")) { if (wire->attributes.count("\\init")) {
log_warning("Wire %s.%s has an unprocessed 'init' attribute.\n", log_id(module), log_id(wire)); Const initval = wire->attributes.at("\\init");
counter++; 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()); log_warning("%s", message.c_str());
counter++; 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); log("found and reported %d problems.\n", counter);