Merge pull request #3080 from YosysHQ/micko/init_wire
[yosys.git] / backends / verilog / verilog_backend.cc
index 47b48a4603980870dac605ea240a816f24d6aea1..47ef1c479d97d01bcdceb8609ade8e006395adb7 100644 (file)
@@ -44,6 +44,7 @@ std::string auto_prefix, extmem_prefix;
 RTLIL::Module *active_module;
 dict<RTLIL::SigBit, RTLIL::State> active_initdata;
 SigMap active_sigmap;
+IdString initial_id;
 
 void reset_auto_counter_id(RTLIL::IdString id, bool may_rename)
 {
@@ -1398,7 +1399,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
                FfData ff(nullptr, cell);
 
                // $ff / $_FF_ cell: not supported.
-               if (ff.has_d && !ff.has_clk && !ff.has_en)
+               if (ff.has_gclk)
                        return false;
 
                std::string reg_name = cellname(cell);
@@ -1419,17 +1420,19 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
 
                for (int i = 0; i < chunks; i++)
                {
-                       SigSpec sig_d;
+                       SigSpec sig_d, sig_ad;
                        Const val_arst, val_srst;
-                       std::string reg_bit_name, sig_set_name, sig_clr_name, sig_arst_name;
+                       std::string reg_bit_name, sig_set_name, sig_clr_name, sig_arst_name, sig_aload_name;
                        if (chunky) {
                                reg_bit_name = stringf("%s[%d]", reg_name.c_str(), i);
-                               if (ff.has_d)
+                               if (ff.has_gclk || ff.has_clk)
                                        sig_d = ff.sig_d[i];
+                               if (ff.has_aload)
+                                       sig_ad = ff.sig_ad[i];
                        } else {
                                reg_bit_name = reg_name;
-                               if (ff.has_d)
-                                       sig_d = ff.sig_d;
+                               sig_d = ff.sig_d;
+                               sig_ad = ff.sig_ad;
                        }
                        if (ff.has_arst)
                                val_arst = chunky ? ff.val_arst[i] : ff.val_arst;
@@ -1437,28 +1440,38 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
                                val_srst = chunky ? ff.val_srst[i] : ff.val_srst;
 
                        // If there are constants in the sensitivity list, replace them with an intermediate wire
-                       if (ff.has_sr) {
-                               if (ff.sig_set[i].wire == NULL)
-                               {
-                                       sig_set_name = next_auto_id();
-                                       f << stringf("%s" "wire %s = ", indent.c_str(), sig_set_name.c_str());
-                                       dump_const(f, ff.sig_set[i].data);
-                                       f << stringf(";\n");
-                               }
-                               if (ff.sig_clr[i].wire == NULL)
-                               {
-                                       sig_clr_name = next_auto_id();
-                                       f << stringf("%s" "wire %s = ", indent.c_str(), sig_clr_name.c_str());
-                                       dump_const(f, ff.sig_clr[i].data);
-                                       f << stringf(";\n");
-                               }
-                       } else if (ff.has_arst) {
-                               if (ff.sig_arst[i].wire == NULL)
-                               {
-                                       sig_arst_name = next_auto_id();
-                                       f << stringf("%s" "wire %s = ", indent.c_str(), sig_arst_name.c_str());
-                                       dump_const(f, ff.sig_arst[i].data);
-                                       f << stringf(";\n");
+                       if (ff.has_clk) {
+                               if (ff.has_sr) {
+                                       if (ff.sig_set[i].wire == NULL)
+                                       {
+                                               sig_set_name = next_auto_id();
+                                               f << stringf("%s" "wire %s = ", indent.c_str(), sig_set_name.c_str());
+                                               dump_const(f, ff.sig_set[i].data);
+                                               f << stringf(";\n");
+                                       }
+                                       if (ff.sig_clr[i].wire == NULL)
+                                       {
+                                               sig_clr_name = next_auto_id();
+                                               f << stringf("%s" "wire %s = ", indent.c_str(), sig_clr_name.c_str());
+                                               dump_const(f, ff.sig_clr[i].data);
+                                               f << stringf(";\n");
+                                       }
+                               } else if (ff.has_arst) {
+                                       if (ff.sig_arst[0].wire == NULL)
+                                       {
+                                               sig_arst_name = next_auto_id();
+                                               f << stringf("%s" "wire %s = ", indent.c_str(), sig_arst_name.c_str());
+                                               dump_const(f, ff.sig_arst[0].data);
+                                               f << stringf(";\n");
+                                       }
+                               } else if (ff.has_aload) {
+                                       if (ff.sig_aload[0].wire == NULL)
+                                       {
+                                               sig_aload_name = next_auto_id();
+                                               f << stringf("%s" "wire %s = ", indent.c_str(), sig_aload_name.c_str());
+                                               dump_const(f, ff.sig_aload[0].data);
+                                               f << stringf(";\n");
+                                       }
                                }
                        }
 
@@ -1480,13 +1493,18 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
                                                f << stringf("%s", sig_clr_name.c_str());
                                        else
                                                dump_sigspec(f, ff.sig_clr[i]);
-
                                } else if (ff.has_arst) {
                                        f << stringf(", %sedge ", ff.pol_arst ? "pos" : "neg");
-                                       if (ff.sig_arst[i].wire == NULL)
+                                       if (ff.sig_arst[0].wire == NULL)
                                                f << stringf("%s", sig_arst_name.c_str());
                                        else
                                                dump_sigspec(f, ff.sig_arst);
+                               } else if (ff.has_aload) {
+                                       f << stringf(", %sedge ", ff.pol_aload ? "pos" : "neg");
+                                       if (ff.sig_aload[0].wire == NULL)
+                                               f << stringf("%s", sig_aload_name.c_str());
+                                       else
+                                               dump_sigspec(f, ff.sig_aload);
                                }
                                f << stringf(")\n");
 
@@ -1507,7 +1525,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
                                        f << stringf("%s" "  else ", indent.c_str());
                                } else if (ff.has_arst) {
                                        f << stringf("if (%s", ff.pol_arst ? "" : "!");
-                                       if (ff.sig_arst[i].wire == NULL)
+                                       if (ff.sig_arst[0].wire == NULL)
                                                f << stringf("%s", sig_arst_name.c_str());
                                        else
                                                dump_sigspec(f, ff.sig_arst);
@@ -1515,11 +1533,21 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
                                        dump_sigspec(f, val_arst);
                                        f << stringf(";\n");
                                        f << stringf("%s" "  else ", indent.c_str());
+                               } else if (ff.has_aload) {
+                                       f << stringf("if (%s", ff.pol_aload ? "" : "!");
+                                       if (ff.sig_aload[0].wire == NULL)
+                                               f << stringf("%s", sig_aload_name.c_str());
+                                       else
+                                               dump_sigspec(f, ff.sig_aload);
+                                       f << stringf(") %s <= ", reg_bit_name.c_str());
+                                       dump_sigspec(f, sig_ad);
+                                       f << stringf(";\n");
+                                       f << stringf("%s" "  else ", indent.c_str());
                                }
 
-                               if (ff.has_srst && ff.has_en && ff.ce_over_srst) {
-                                       f << stringf("if (%s", ff.pol_en ? "" : "!");
-                                       dump_sigspec(f, ff.sig_en);
+                               if (ff.has_srst && ff.has_ce && ff.ce_over_srst) {
+                                       f << stringf("if (%s", ff.pol_ce ? "" : "!");
+                                       dump_sigspec(f, ff.sig_ce);
                                        f << stringf(")\n");
                                        f << stringf("%s" "    if (%s", indent.c_str(), ff.pol_srst ? "" : "!");
                                        dump_sigspec(f, ff.sig_srst);
@@ -1536,9 +1564,9 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
                                                f << stringf(";\n");
                                                f << stringf("%s" "  else ", indent.c_str());
                                        }
-                                       if (ff.has_en) {
-                                               f << stringf("if (%s", ff.pol_en ? "" : "!");
-                                               dump_sigspec(f, ff.sig_en);
+                                       if (ff.has_ce) {
+                                               f << stringf("if (%s", ff.pol_ce ? "" : "!");
+                                               dump_sigspec(f, ff.sig_ce);
                                                f << stringf(") ");
                                        }
                                }
@@ -1560,7 +1588,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
                                        f << stringf("%s" "  else if (%s", indent.c_str(), ff.pol_set ? "" : "!");
                                        dump_sigspec(f, ff.sig_set[i]);
                                        f << stringf(") %s = 1'b1;\n", reg_bit_name.c_str());
-                                       if (ff.has_d)
+                                       if (ff.has_aload)
                                                f << stringf("%s" "  else ", indent.c_str());
                                } else if (ff.has_arst) {
                                        f << stringf("if (%s", ff.pol_arst ? "" : "!");
@@ -1568,14 +1596,14 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
                                        f << stringf(") %s = ", reg_bit_name.c_str());
                                        dump_sigspec(f, val_arst);
                                        f << stringf(";\n");
-                                       if (ff.has_d)
+                                       if (ff.has_aload)
                                                f << stringf("%s" "  else ", indent.c_str());
                                }
-                               if (ff.has_d) {
-                                       f << stringf("if (%s", ff.pol_en ? "" : "!");
-                                       dump_sigspec(f, ff.sig_en);
+                               if (ff.has_aload) {
+                                       f << stringf("if (%s", ff.pol_aload ? "" : "!");
+                                       dump_sigspec(f, ff.sig_aload);
                                        f << stringf(") %s = ", reg_bit_name.c_str());
-                                       dump_sigspec(f, sig_d);
+                                       dump_sigspec(f, sig_ad);
                                        f << stringf(";\n");
                                }
                        }
@@ -1916,7 +1944,7 @@ void dump_process(std::ostream &f, std::string indent, RTLIL::Process *proc, boo
 
        f << stringf("%s" "always%s begin\n", indent.c_str(), systemverilog ? "_comb" : " @*");
        if (!systemverilog)
-               f << indent + "  " << "if (" << id("\\initial") << ") begin end\n";
+               f << indent + "  " << "if (" << id(initial_id) << ") begin end\n";
        dump_case_body(f, indent, &proc->root_case, true);
 
        std::string backup_indent = indent;
@@ -2035,6 +2063,7 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module)
        dump_attributes(f, indent, module->attributes, '\n', /*modattr=*/true);
        f << stringf("%s" "module %s(", indent.c_str(), id(module->name, false).c_str());
        bool keep_running = true;
+       int cnt = 0;
        for (int port_id = 1; keep_running; port_id++) {
                keep_running = false;
                for (auto wire : module->wires()) {
@@ -2043,14 +2072,16 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module)
                                        f << stringf(", ");
                                f << stringf("%s", id(wire->name).c_str());
                                keep_running = true;
+                               if (cnt==20) { f << stringf("\n"); cnt = 0; } else cnt++;
                                continue;
                        }
                }
        }
        f << stringf(");\n");
-
-       if (!systemverilog && !module->processes.empty())
-               f << indent + "  " << "reg " << id("\\initial") << " = 0;\n";
+       if (!systemverilog && !module->processes.empty()) {
+               initial_id = NEW_ID;
+               f << indent + "  " << "reg " << id(initial_id) << " = 0;\n";
+       }
 
        for (auto w : module->wires())
                dump_wire(f, indent + "  ", w);