mirror of https://github.com/YosysHQ/yosys.git
opt_merge: Add `-keepdc` option required for formal verification
The `-keepdc` option prevents merging flipflops with dont-care bits in their initial value, as, in general, this is not a valid transform for formal verification. The keepdc option of `opt` is passed along to `opt_merge` now.
This commit is contained in:
parent
2ec4af56e6
commit
ca5b910296
|
@ -114,6 +114,7 @@ struct OptPass : public Pass {
|
|||
if (args[argidx] == "-keepdc") {
|
||||
opt_expr_args += " -keepdc";
|
||||
opt_dff_args += " -keepdc";
|
||||
opt_merge_args += " -keepdc";
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-nodffe") {
|
||||
|
|
|
@ -219,7 +219,15 @@ struct OptMergeWorker
|
|||
return conn1 == conn2;
|
||||
}
|
||||
|
||||
OptMergeWorker(RTLIL::Design *design, RTLIL::Module *module, bool mode_nomux, bool mode_share_all) :
|
||||
bool has_dont_care_initval(const RTLIL::Cell *cell)
|
||||
{
|
||||
if (!RTLIL::builtin_ff_cell_types().count(cell->type))
|
||||
return false;
|
||||
|
||||
return !initvals(cell->getPort(ID::Q)).is_fully_def();
|
||||
}
|
||||
|
||||
OptMergeWorker(RTLIL::Design *design, RTLIL::Module *module, bool mode_nomux, bool mode_share_all, bool mode_keepdc) :
|
||||
design(design), module(module), assign_map(module), mode_share_all(mode_share_all)
|
||||
{
|
||||
total_count = 0;
|
||||
|
@ -253,6 +261,8 @@ struct OptMergeWorker
|
|||
for (auto &it : module->cells_) {
|
||||
if (!design->selected(module, it.second))
|
||||
continue;
|
||||
if (mode_keepdc && has_dont_care_initval(it.second))
|
||||
continue;
|
||||
if (ct.cell_known(it.second->type) || (mode_share_all && it.second->known()))
|
||||
cells.push_back(it.second);
|
||||
}
|
||||
|
@ -319,6 +329,9 @@ struct OptMergePass : public Pass {
|
|||
log(" -share_all\n");
|
||||
log(" Operate on all cell types, not just built-in types.\n");
|
||||
log("\n");
|
||||
log(" -keepdc\n");
|
||||
log(" Do not merge flipflops with don't-care bits in their initial value.\n");
|
||||
log("\n");
|
||||
}
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||
{
|
||||
|
@ -326,6 +339,7 @@ struct OptMergePass : public Pass {
|
|||
|
||||
bool mode_nomux = false;
|
||||
bool mode_share_all = false;
|
||||
bool mode_keepdc = false;
|
||||
|
||||
size_t argidx;
|
||||
for (argidx = 1; argidx < args.size(); argidx++) {
|
||||
|
@ -338,13 +352,17 @@ struct OptMergePass : public Pass {
|
|||
mode_share_all = true;
|
||||
continue;
|
||||
}
|
||||
if (arg == "-keepdc") {
|
||||
mode_keepdc = true;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
extra_args(args, argidx, design);
|
||||
|
||||
int total_count = 0;
|
||||
for (auto module : design->selected_modules()) {
|
||||
OptMergeWorker worker(design, module, mode_nomux, mode_share_all);
|
||||
OptMergeWorker worker(design, module, mode_nomux, mode_share_all, mode_keepdc);
|
||||
total_count += worker.total_count;
|
||||
}
|
||||
|
||||
|
|
|
@ -75,3 +75,53 @@ EOT
|
|||
|
||||
opt_merge
|
||||
select -assert-count 2 t:$dff
|
||||
|
||||
design -reset
|
||||
read_verilog -icells <<EOT
|
||||
module top(input clk, i, (* init = 1'b0 *) output o, p);
|
||||
\$dff #(
|
||||
.CLK_POLARITY(1'h1),
|
||||
.WIDTH(32'd1)
|
||||
) ffo (
|
||||
.CLK(clk),
|
||||
.D(i),
|
||||
.Q(o)
|
||||
);
|
||||
\$dff #(
|
||||
.CLK_POLARITY(1'h1),
|
||||
.WIDTH(32'd1)
|
||||
) ffp (
|
||||
.CLK(clk),
|
||||
.D(i),
|
||||
.Q(p)
|
||||
);
|
||||
endmodule
|
||||
EOT
|
||||
|
||||
opt_merge -keepdc
|
||||
select -assert-count 1 t:$dff
|
||||
|
||||
design -reset
|
||||
read_verilog -icells <<EOT
|
||||
module top(input clk, i, output o, p);
|
||||
\$dff #(
|
||||
.CLK_POLARITY(1'h1),
|
||||
.WIDTH(32'd1)
|
||||
) ffo (
|
||||
.CLK(clk),
|
||||
.D(i),
|
||||
.Q(o)
|
||||
);
|
||||
\$dff #(
|
||||
.CLK_POLARITY(1'h1),
|
||||
.WIDTH(32'd1)
|
||||
) ffp (
|
||||
.CLK(clk),
|
||||
.D(i),
|
||||
.Q(p)
|
||||
);
|
||||
endmodule
|
||||
EOT
|
||||
|
||||
opt_merge -keepdc
|
||||
select -assert-count 2 t:$dff
|
||||
|
|
Loading…
Reference in New Issue