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;
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);
}
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
{
bool mode_nomux = false;
bool mode_share_all = false;
+ bool mode_keepdc = false;
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++) {
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;
}
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