Add clk2fflogic -negsetup

Signed-off-by: Claire Xenia Wolf <claire@clairexen.net>
This commit is contained in:
Claire Xenia Wolf 2021-05-04 18:53:30 +02:00
parent abefba2b58
commit daace6b154
1 changed files with 31 additions and 23 deletions

View File

@ -38,26 +38,34 @@ struct Clk2fflogicPass : public Pass {
log("implicit global clock. This is useful for formal verification of designs with\n"); log("implicit global clock. This is useful for formal verification of designs with\n");
log("multiple clocks.\n"); log("multiple clocks.\n");
log("\n"); log("\n");
log(" -negsetup\n");
log(" By default this pass assumes negative hold time on async FF inputs. With\n");
log(" this option negative setup time is assumed instead.\n");
log("\n");
} }
SigSpec wrap_async_control(Module *module, SigSpec sig, bool polarity) { SigSpec wrap_async_control(Module *module, SigSpec sig, bool polarity, bool negsetup) {
Wire *past_sig = module->addWire(NEW_ID, GetSize(sig)); if (!negsetup) {
module->addFf(NEW_ID, sig, past_sig); Wire *past_sig = module->addWire(NEW_ID, GetSize(sig));
if (polarity) module->addFf(NEW_ID, sig, past_sig);
sig = module->Or(NEW_ID, sig, past_sig); if (polarity)
else sig = module->Or(NEW_ID, sig, past_sig);
sig = module->And(NEW_ID, sig, past_sig); else
sig = module->And(NEW_ID, sig, past_sig);
}
if (polarity) if (polarity)
return sig; return sig;
else else
return module->Not(NEW_ID, sig); return module->Not(NEW_ID, sig);
} }
SigSpec wrap_async_control_gate(Module *module, SigSpec sig, bool polarity) { SigSpec wrap_async_control_gate(Module *module, SigSpec sig, bool polarity, bool negsetup) {
Wire *past_sig = module->addWire(NEW_ID); if (!negsetup) {
module->addFfGate(NEW_ID, sig, past_sig); Wire *past_sig = module->addWire(NEW_ID);
if (polarity) module->addFfGate(NEW_ID, sig, past_sig);
sig = module->OrGate(NEW_ID, sig, past_sig); if (polarity)
else sig = module->OrGate(NEW_ID, sig, past_sig);
sig = module->AndGate(NEW_ID, sig, past_sig); else
sig = module->AndGate(NEW_ID, sig, past_sig);
}
if (polarity) if (polarity)
return sig; return sig;
else else
@ -65,17 +73,17 @@ struct Clk2fflogicPass : public Pass {
} }
void execute(std::vector<std::string> args, RTLIL::Design *design) override void execute(std::vector<std::string> args, RTLIL::Design *design) override
{ {
// bool flag_noinit = false; bool negsetup = false;
log_header(design, "Executing CLK2FFLOGIC pass (convert clocked FFs to generic $ff cells).\n"); log_header(design, "Executing CLK2FFLOGIC pass (convert clocked FFs to generic $ff cells).\n");
size_t argidx; size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++) for (argidx = 1; argidx < args.size(); argidx++)
{ {
// if (args[argidx] == "-noinit") { if (args[argidx] == "-negsetup") {
// flag_noinit = true; negsetup = true;
// continue; continue;
// } }
break; break;
} }
extra_args(args, argidx, design); extra_args(args, argidx, design);
@ -208,7 +216,7 @@ struct Clk2fflogicPass : public Pass {
log_id(module), log_id(cell), log_id(cell->type), log_id(module), log_id(cell), log_id(cell->type),
log_signal(ff.sig_en), log_signal(ff.sig_d), log_signal(ff.sig_q)); log_signal(ff.sig_en), log_signal(ff.sig_d), log_signal(ff.sig_q));
SigSpec sig_en = wrap_async_control(module, ff.sig_en, ff.pol_en); SigSpec sig_en = wrap_async_control(module, ff.sig_en, ff.pol_en, negsetup);
if (!ff.is_fine) if (!ff.is_fine)
qval = module->Mux(NEW_ID, past_q, ff.sig_d, sig_en); qval = module->Mux(NEW_ID, past_q, ff.sig_d, sig_en);
@ -224,8 +232,8 @@ struct Clk2fflogicPass : public Pass {
} }
if (ff.has_sr) { if (ff.has_sr) {
SigSpec setval = wrap_async_control(module, ff.sig_set, ff.pol_set); SigSpec setval = wrap_async_control(module, ff.sig_set, ff.pol_set, negsetup);
SigSpec clrval = wrap_async_control(module, ff.sig_clr, ff.pol_clr); SigSpec clrval = wrap_async_control(module, ff.sig_clr, ff.pol_clr, negsetup);
if (!ff.is_fine) { if (!ff.is_fine) {
clrval = module->Not(NEW_ID, clrval); clrval = module->Not(NEW_ID, clrval);
qval = module->Or(NEW_ID, qval, setval); qval = module->Or(NEW_ID, qval, setval);
@ -236,7 +244,7 @@ struct Clk2fflogicPass : public Pass {
module->addAndGate(NEW_ID, qval, clrval, ff.sig_q); module->addAndGate(NEW_ID, qval, clrval, ff.sig_q);
} }
} else if (ff.has_arst) { } else if (ff.has_arst) {
SigSpec arst = wrap_async_control(module, ff.sig_arst, ff.pol_arst); SigSpec arst = wrap_async_control(module, ff.sig_arst, ff.pol_arst, negsetup);
if (!ff.is_fine) if (!ff.is_fine)
module->addMux(NEW_ID, qval, ff.val_arst, arst, ff.sig_q); module->addMux(NEW_ID, qval, ff.val_arst, arst, ff.sig_q);
else else