aboutsummaryrefslogtreecommitdiffstats
path: root/backends
diff options
context:
space:
mode:
Diffstat (limited to 'backends')
-rw-r--r--backends/cxxrtl/cxxrtl.h3
-rw-r--r--backends/smt2/smt2.cc13
-rw-r--r--backends/smt2/smtbmc.py4
-rw-r--r--backends/smt2/smtio.py24
-rw-r--r--backends/verilog/verilog_backend.cc386
5 files changed, 170 insertions, 260 deletions
diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h
index f0d7b9fc7..e3c96d422 100644
--- a/backends/cxxrtl/cxxrtl.h
+++ b/backends/cxxrtl/cxxrtl.h
@@ -452,10 +452,11 @@ struct value : public expr_base<value<Bits>> {
bool carry = CarryIn;
for (size_t n = 0; n < result.chunks; n++) {
result.data[n] = data[n] + (Invert ? ~other.data[n] : other.data[n]) + carry;
+ if (result.chunks - 1 == n)
+ result.data[result.chunks - 1] &= result.msb_mask;
carry = (result.data[n] < data[n]) ||
(result.data[n] == data[n] && carry);
}
- result.data[result.chunks - 1] &= result.msb_mask;
return {result, carry};
}
diff --git a/backends/smt2/smt2.cc b/backends/smt2/smt2.cc
index 526b36352..a79c0bd99 100644
--- a/backends/smt2/smt2.cc
+++ b/backends/smt2/smt2.cc
@@ -1387,6 +1387,10 @@ struct Smt2Backend : public Backend {
log(" use the given template file. the line containing only the token '%%%%'\n");
log(" is replaced with the regular output of this command.\n");
log("\n");
+ log(" -solver-option <option> <value>\n");
+ log(" emit a `; yosys-smt2-solver-option` directive for yosys-smtbmc to write\n");
+ log(" the given option as a `(set-option ...)` command in the SMT-LIBv2.\n");
+ log("\n");
log("[1] For more information on SMT-LIBv2 visit http://smt-lib.org/ or read David\n");
log("R. Cok's tutorial: http://www.grammatech.com/resources/smt/SMTLIBTutorial.pdf\n");
log("\n");
@@ -1441,6 +1445,7 @@ struct Smt2Backend : public Backend {
std::ifstream template_f;
bool bvmode = true, memmode = true, wiresmode = false, verbose = false, statebv = false, statedt = false;
bool forallmode = false;
+ dict<std::string, std::string> solver_options;
log_header(design, "Executing SMT2 backend.\n");
@@ -1484,6 +1489,11 @@ struct Smt2Backend : public Backend {
verbose = true;
continue;
}
+ if (args[argidx] == "-solver-option" && argidx+2 < args.size()) {
+ solver_options.emplace(args[argidx+1], args[argidx+2]);
+ argidx += 2;
+ continue;
+ }
break;
}
extra_args(f, filename, args, argidx);
@@ -1514,6 +1524,9 @@ struct Smt2Backend : public Backend {
if (statedt)
*f << stringf("; yosys-smt2-stdt\n");
+ for (auto &it : solver_options)
+ *f << stringf("; yosys-smt2-solver-option %s %s\n", it.first.c_str(), it.second.c_str());
+
std::vector<RTLIL::Module*> sorted_modules;
// extract module dependencies
diff --git a/backends/smt2/smtbmc.py b/backends/smt2/smtbmc.py
index 03f001bfd..69dab5590 100644
--- a/backends/smt2/smtbmc.py
+++ b/backends/smt2/smtbmc.py
@@ -1275,10 +1275,10 @@ def smt_pop():
asserts_consequent_cache.pop()
smt.write("(pop 1)")
-def smt_check_sat():
+def smt_check_sat(expected=["sat", "unsat"]):
if asserts_cache_dirty:
smt_forall_assert()
- return smt.check_sat()
+ return smt.check_sat(expected=expected)
if tempind:
retstatus = "FAILED"
diff --git a/backends/smt2/smtio.py b/backends/smt2/smtio.py
index 72ab39d39..516091011 100644
--- a/backends/smt2/smtio.py
+++ b/backends/smt2/smtio.py
@@ -124,6 +124,7 @@ class SmtIo:
self.timeout = 0
self.produce_models = True
self.smt2cache = [list()]
+ self.smt2_options = dict()
self.p = None
self.p_index = solvers_index
solvers_index += 1
@@ -258,14 +259,24 @@ class SmtIo:
for stmt in self.info_stmts:
self.write(stmt)
- if self.forall and self.solver == "yices":
- self.write("(set-option :yices-ef-max-iters 1000000000)")
-
if self.produce_models:
self.write("(set-option :produce-models true)")
+ #See the SMT-LIB Standard, Section 4.1.7
+ modestart_options = [":global-declarations", ":interactive-mode", ":produce-assertions", ":produce-assignments", ":produce-models", ":produce-proofs", ":produce-unsat-assumptions", ":produce-unsat-cores", ":random-seed"]
+ for key, val in self.smt2_options.items():
+ if key in modestart_options:
+ self.write("(set-option {} {})".format(key, val))
+
self.write("(set-logic %s)" % self.logic)
+ if self.forall and self.solver == "yices":
+ self.write("(set-option :yices-ef-max-iters 1000000000)")
+
+ for key, val in self.smt2_options.items():
+ if key not in modestart_options:
+ self.write("(set-option {} {})".format(key, val))
+
def timestamp(self):
secs = int(time() - self.start_time)
return "## %3d:%02d:%02d " % (secs // (60*60), (secs // 60) % 60, secs % 60)
@@ -468,6 +479,9 @@ class SmtIo:
fields = stmt.split()
+ if fields[1] == "yosys-smt2-solver-option":
+ self.smt2_options[fields[2]] = fields[3]
+
if fields[1] == "yosys-smt2-nomem":
if self.logic is None:
self.logic_ax = False
@@ -653,7 +667,7 @@ class SmtIo:
return stmt
- def check_sat(self):
+ def check_sat(self, expected=["sat", "unsat", "unknown", "timeout", "interrupted"]):
if self.debug_print:
print("> (check-sat)")
if self.debug_file and not self.nocomments:
@@ -740,7 +754,7 @@ class SmtIo:
print("(check-sat)", file=self.debug_file)
self.debug_file.flush()
- if result not in ["sat", "unsat", "unknown", "timeout", "interrupted"]:
+ if result not in expected:
if result == "":
print("%s Unexpected EOF response from solver." % (self.timestamp()), flush=True)
else:
diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc
index 71f71554b..a0e677d13 100644
--- a/backends/verilog/verilog_backend.cc
+++ b/backends/verilog/verilog_backend.cc
@@ -25,6 +25,7 @@
#include "kernel/celltypes.h"
#include "kernel/log.h"
#include "kernel/sigtools.h"
+#include "kernel/ff.h"
#include <string>
#include <sstream>
#include <set>
@@ -36,7 +37,7 @@ PRIVATE_NAMESPACE_BEGIN
bool verbose, norename, noattr, attr2comment, noexpr, nodec, nohex, nostr, extmem, defparam, decimal, siminit, systemverilog;
int auto_name_counter, auto_name_offset, auto_name_digits, extmem_counter;
std::map<RTLIL::IdString, int> auto_name_map;
-std::set<RTLIL::IdString> reg_wires, reg_ct;
+std::set<RTLIL::IdString> reg_wires;
std::string auto_prefix, extmem_prefix;
RTLIL::Module *active_module;
@@ -451,7 +452,7 @@ void dump_cell_expr_port(std::ostream &f, RTLIL::Cell *cell, std::string port, b
std::string cellname(RTLIL::Cell *cell)
{
- if (!norename && cell->name[0] == '$' && reg_ct.count(cell->type) && cell->hasPort(ID::Q))
+ if (!norename && cell->name[0] == '$' && RTLIL::builtin_ff_cell_types().count(cell->type) && cell->hasPort(ID::Q) && !cell->type.in(ID($ff), ID($_FF_)))
{
RTLIL::SigSpec sig = cell->getPort(ID::Q);
if (GetSize(sig) != 1 || sig.is_fully_const())
@@ -605,93 +606,6 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
return true;
}
- if (cell->type.begins_with("$_DFF_"))
- {
- std::string reg_name = cellname(cell);
- bool out_is_reg_wire = is_reg_wire(cell->getPort(ID::Q), reg_name);
-
- if (!out_is_reg_wire) {
- f << stringf("%s" "reg %s", indent.c_str(), reg_name.c_str());
- dump_reg_init(f, cell->getPort(ID::Q));
- f << ";\n";
- }
-
- dump_attributes(f, indent, cell->attributes);
- f << stringf("%s" "always%s @(%sedge ", indent.c_str(), systemverilog ? "_ff" : "", cell->type[6] == 'P' ? "pos" : "neg");
- dump_sigspec(f, cell->getPort(ID::C));
- if (cell->type[7] != '_') {
- f << stringf(" or %sedge ", cell->type[7] == 'P' ? "pos" : "neg");
- dump_sigspec(f, cell->getPort(ID::R));
- }
- f << stringf(")\n");
-
- if (cell->type[7] != '_') {
- f << stringf("%s" " if (%s", indent.c_str(), cell->type[7] == 'P' ? "" : "!");
- dump_sigspec(f, cell->getPort(ID::R));
- f << stringf(")\n");
- f << stringf("%s" " %s <= %c;\n", indent.c_str(), reg_name.c_str(), cell->type[8]);
- f << stringf("%s" " else\n", indent.c_str());
- }
-
- f << stringf("%s" " %s <= ", indent.c_str(), reg_name.c_str());
- dump_cell_expr_port(f, cell, "D", false);
- f << stringf(";\n");
-
- if (!out_is_reg_wire) {
- f << stringf("%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->getPort(ID::Q));
- f << stringf(" = %s;\n", reg_name.c_str());
- }
-
- return true;
- }
-
- if (cell->type.begins_with("$_DFFSR_"))
- {
- char pol_c = cell->type[8], pol_s = cell->type[9], pol_r = cell->type[10];
-
- std::string reg_name = cellname(cell);
- bool out_is_reg_wire = is_reg_wire(cell->getPort(ID::Q), reg_name);
-
- if (!out_is_reg_wire) {
- f << stringf("%s" "reg %s", indent.c_str(), reg_name.c_str());
- dump_reg_init(f, cell->getPort(ID::Q));
- f << ";\n";
- }
-
- dump_attributes(f, indent, cell->attributes);
- f << stringf("%s" "always%s @(%sedge ", indent.c_str(), systemverilog ? "_ff" : "", pol_c == 'P' ? "pos" : "neg");
- dump_sigspec(f, cell->getPort(ID::C));
- f << stringf(" or %sedge ", pol_s == 'P' ? "pos" : "neg");
- dump_sigspec(f, cell->getPort(ID::S));
- f << stringf(" or %sedge ", pol_r == 'P' ? "pos" : "neg");
- dump_sigspec(f, cell->getPort(ID::R));
- f << stringf(")\n");
-
- f << stringf("%s" " if (%s", indent.c_str(), pol_r == 'P' ? "" : "!");
- dump_sigspec(f, cell->getPort(ID::R));
- f << stringf(")\n");
- f << stringf("%s" " %s <= 0;\n", indent.c_str(), reg_name.c_str());
-
- f << stringf("%s" " else if (%s", indent.c_str(), pol_s == 'P' ? "" : "!");
- dump_sigspec(f, cell->getPort(ID::S));
- f << stringf(")\n");
- f << stringf("%s" " %s <= 1;\n", indent.c_str(), reg_name.c_str());
-
- f << stringf("%s" " else\n", indent.c_str());
- f << stringf("%s" " %s <= ", indent.c_str(), reg_name.c_str());
- dump_cell_expr_port(f, cell, "D", false);
- f << stringf(";\n");
-
- if (!out_is_reg_wire) {
- f << stringf("%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->getPort(ID::Q));
- f << stringf(" = %s;\n", reg_name.c_str());
- }
-
- return true;
- }
-
#define HANDLE_UNIOP(_type, _operator) \
if (cell->type ==_type) { dump_cell_expr_uniop(f, indent, cell, _operator); return true; }
#define HANDLE_BINOP(_type, _operator) \
@@ -986,154 +900,151 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
return true;
}
- if (cell->type == ID($dffsr))
+ if (RTLIL::builtin_ff_cell_types().count(cell->type))
{
- SigSpec sig_clk = cell->getPort(ID::CLK);
- SigSpec sig_set = cell->getPort(ID::SET);
- SigSpec sig_clr = cell->getPort(ID::CLR);
- SigSpec sig_d = cell->getPort(ID::D);
- SigSpec sig_q = cell->getPort(ID::Q);
+ FfData ff(nullptr, cell);
- int width = cell->parameters[ID::WIDTH].as_int();
- bool pol_clk = cell->parameters[ID::CLK_POLARITY].as_bool();
- bool pol_set = cell->parameters[ID::SET_POLARITY].as_bool();
- bool pol_clr = cell->parameters[ID::CLR_POLARITY].as_bool();
+ // $ff / $_FF_ cell: not supported.
+ if (ff.has_d && !ff.has_clk && !ff.has_en)
+ return false;
std::string reg_name = cellname(cell);
- bool out_is_reg_wire = is_reg_wire(sig_q, reg_name);
-
- if (!out_is_reg_wire) {
- f << stringf("%s" "reg [%d:0] %s", indent.c_str(), width-1, reg_name.c_str());
- dump_reg_init(f, sig_q);
- f << ";\n";
- }
-
- for (int i = 0; i < width; i++) {
- f << stringf("%s" "always%s @(%sedge ", indent.c_str(), systemverilog ? "_ff" : "", pol_clk ? "pos" : "neg");
- dump_sigspec(f, sig_clk);
- f << stringf(", %sedge ", pol_set ? "pos" : "neg");
- dump_sigspec(f, sig_set);
- f << stringf(", %sedge ", pol_clr ? "pos" : "neg");
- dump_sigspec(f, sig_clr);
- f << stringf(")\n");
-
- f << stringf("%s" " if (%s", indent.c_str(), pol_clr ? "" : "!");
- dump_sigspec(f, sig_clr);
- f << stringf(") %s[%d] <= 1'b0;\n", reg_name.c_str(), i);
-
- f << stringf("%s" " else if (%s", indent.c_str(), pol_set ? "" : "!");
- dump_sigspec(f, sig_set);
- f << stringf(") %s[%d] <= 1'b1;\n", reg_name.c_str(), i);
-
- f << stringf("%s" " else %s[%d] <= ", indent.c_str(), reg_name.c_str(), i);
- dump_sigspec(f, sig_d[i]);
- f << stringf(";\n");
- }
+ bool out_is_reg_wire = is_reg_wire(ff.sig_q, reg_name);
if (!out_is_reg_wire) {
- f << stringf("%s" "assign ", indent.c_str());
- dump_sigspec(f, sig_q);
- f << stringf(" = %s;\n", reg_name.c_str());
- }
-
- return true;
- }
-
- if (cell->type.in(ID($dff), ID($adff), ID($dffe)))
- {
- RTLIL::SigSpec sig_clk, sig_arst, sig_en, val_arst;
- bool pol_clk, pol_arst = false, pol_en = false;
-
- sig_clk = cell->getPort(ID::CLK);
- pol_clk = cell->parameters[ID::CLK_POLARITY].as_bool();
-
- if (cell->type == ID($adff)) {
- sig_arst = cell->getPort(ID::ARST);
- pol_arst = cell->parameters[ID::ARST_POLARITY].as_bool();
- val_arst = RTLIL::SigSpec(cell->parameters[ID::ARST_VALUE]);
- }
-
- if (cell->type == ID($dffe)) {
- sig_en = cell->getPort(ID::EN);
- pol_en = cell->parameters[ID::EN_POLARITY].as_bool();
- }
-
- std::string reg_name = cellname(cell);
- bool out_is_reg_wire = is_reg_wire(cell->getPort(ID::Q), reg_name);
-
- if (!out_is_reg_wire) {
- f << stringf("%s" "reg [%d:0] %s", indent.c_str(), cell->parameters[ID::WIDTH].as_int()-1, reg_name.c_str());
- dump_reg_init(f, cell->getPort(ID::Q));
+ if (ff.width == 1)
+ f << stringf("%s" "reg %s", indent.c_str(), reg_name.c_str());
+ else
+ f << stringf("%s" "reg [%d:0] %s", indent.c_str(), ff.width-1, reg_name.c_str());
+ dump_reg_init(f, ff.sig_q);
f << ";\n";
}
- f << stringf("%s" "always%s @(%sedge ", indent.c_str(), systemverilog ? "_ff" : "", pol_clk ? "pos" : "neg");
- dump_sigspec(f, sig_clk);
- if (cell->type == ID($adff)) {
- f << stringf(" or %sedge ", pol_arst ? "pos" : "neg");
- dump_sigspec(f, sig_arst);
- }
- f << stringf(")\n");
-
- if (cell->type == ID($adff)) {
- f << stringf("%s" " if (%s", indent.c_str(), pol_arst ? "" : "!");
- dump_sigspec(f, sig_arst);
- f << stringf(")\n");
- f << stringf("%s" " %s <= ", indent.c_str(), reg_name.c_str());
- dump_sigspec(f, val_arst);
- f << stringf(";\n");
- f << stringf("%s" " else\n", indent.c_str());
- }
-
- if (cell->type == ID($dffe)) {
- f << stringf("%s" " if (%s", indent.c_str(), pol_en ? "" : "!");
- dump_sigspec(f, sig_en);
- f << stringf(")\n");
- }
-
- f << stringf("%s" " %s <= ", indent.c_str(), reg_name.c_str());
- dump_cell_expr_port(f, cell, "D", false);
- f << stringf(";\n");
-
- if (!out_is_reg_wire) {
- f << stringf("%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->getPort(ID::Q));
- f << stringf(" = %s;\n", reg_name.c_str());
- }
-
- return true;
- }
+ // If the FF has CLR/SET inputs, emit every bit slice separately.
+ int chunks = ff.has_sr ? ff.width : 1;
+ bool chunky = ff.has_sr && ff.width != 1;
- if (cell->type == ID($dlatch))
- {
- RTLIL::SigSpec sig_en;
- bool pol_en = false;
+ for (int i = 0; i < chunks; i++)
+ {
+ SigSpec sig_d;
+ Const val_arst, val_srst;
+ std::string reg_bit_name;
+ if (chunky) {
+ reg_bit_name = stringf("%s[%d]", reg_name.c_str(), i);
+ if (ff.has_d)
+ sig_d = ff.sig_d[i];
+ } else {
+ reg_bit_name = reg_name;
+ if (ff.has_d)
+ sig_d = ff.sig_d;
+ }
+ if (ff.has_arst)
+ val_arst = chunky ? ff.val_arst[i] : ff.val_arst;
+ if (ff.has_srst)
+ val_srst = chunky ? ff.val_srst[i] : ff.val_srst;
- sig_en = cell->getPort(ID::EN);
- pol_en = cell->parameters[ID::EN_POLARITY].as_bool();
+ dump_attributes(f, indent, cell->attributes);
+ if (ff.has_clk)
+ {
+ // FFs.
+ f << stringf("%s" "always%s @(%sedge ", indent.c_str(), systemverilog ? "_ff" : "", ff.pol_clk ? "pos" : "neg");
+ dump_sigspec(f, ff.sig_clk);
+ if (ff.has_sr) {
+ f << stringf(", %sedge ", ff.pol_set ? "pos" : "neg");
+ dump_sigspec(f, ff.sig_set[i]);
+ f << stringf(", %sedge ", ff.pol_clr ? "pos" : "neg");
+ dump_sigspec(f, ff.sig_clr[i]);
+ } else if (ff.has_arst) {
+ f << stringf(", %sedge ", ff.pol_arst ? "pos" : "neg");
+ dump_sigspec(f, ff.sig_arst);
+ }
+ f << stringf(")\n");
+
+ f << stringf("%s" " ", indent.c_str());
+ if (ff.has_sr) {
+ f << stringf("if (%s", ff.pol_clr ? "" : "!");
+ dump_sigspec(f, ff.sig_clr[i]);
+ f << stringf(") %s <= 1'b0;\n", reg_bit_name.c_str());
+ 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());
+ f << stringf("%s" " else ", indent.c_str());
+ } else if (ff.has_arst) {
+ f << stringf("if (%s", ff.pol_arst ? "" : "!");
+ dump_sigspec(f, ff.sig_arst);
+ f << stringf(") %s <= ", reg_bit_name.c_str());
+ dump_sigspec(f, val_arst);
+ f << stringf(";\n");
+ f << stringf("%s" " else ", indent.c_str());
+ }
- std::string reg_name = cellname(cell);
- bool out_is_reg_wire = is_reg_wire(cell->getPort(ID::Q), reg_name);
+ if (ff.has_srst && ff.has_en && ff.ce_over_srst) {
+ f << stringf("if (%s", ff.pol_en ? "" : "!");
+ dump_sigspec(f, ff.sig_en);
+ f << stringf(")\n");
+ f << stringf("%s" " if (%s", indent.c_str(), ff.pol_srst ? "" : "!");
+ dump_sigspec(f, ff.sig_srst);
+ f << stringf(") %s <= ", reg_bit_name.c_str());
+ dump_sigspec(f, val_srst);
+ f << stringf(";\n");
+ f << stringf("%s" " else ", indent.c_str());
+ } else {
+ if (ff.has_srst) {
+ f << stringf("if (%s", ff.pol_srst ? "" : "!");
+ dump_sigspec(f, ff.sig_srst);
+ f << stringf(") %s <= ", reg_bit_name.c_str());
+ dump_sigspec(f, val_srst);
+ 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);
+ f << stringf(") ");
+ }
+ }
- if (!out_is_reg_wire) {
- f << stringf("%s" "reg [%d:0] %s", indent.c_str(), cell->parameters[ID::WIDTH].as_int()-1, reg_name.c_str());
- dump_reg_init(f, cell->getPort(ID::Q));
- f << ";\n";
+ f << stringf("%s <= ", reg_bit_name.c_str());
+ dump_sigspec(f, sig_d);
+ f << stringf(";\n");
+ }
+ else
+ {
+ // Latches.
+ f << stringf("%s" "always%s\n", indent.c_str(), systemverilog ? "_latch" : " @*");
+
+ f << stringf("%s" " ", indent.c_str());
+ if (ff.has_sr) {
+ f << stringf("if (%s", ff.pol_clr ? "" : "!");
+ dump_sigspec(f, ff.sig_clr[i]);
+ f << stringf(") %s = 1'b0;\n", reg_bit_name.c_str());
+ 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)
+ f << stringf("%s" " else ", indent.c_str());
+ } else if (ff.has_arst) {
+ f << stringf("if (%s", ff.pol_arst ? "" : "!");
+ dump_sigspec(f, ff.sig_arst);
+ f << stringf(") %s = ", reg_bit_name.c_str());
+ dump_sigspec(f, val_arst);
+ f << stringf(";\n");
+ if (ff.has_d)
+ f << stringf("%s" " else ", indent.c_str());
+ }
+ if (ff.has_d) {
+ f << stringf("if (%s", ff.pol_en ? "" : "!");
+ dump_sigspec(f, ff.sig_en);
+ f << stringf(") %s = ", reg_bit_name.c_str());
+ dump_sigspec(f, sig_d);
+ f << stringf(";\n");
+ }
+ }
}
- f << stringf("%s" "always%s\n", indent.c_str(), systemverilog ? "_latch" : " @*");
-
- f << stringf("%s" " if (%s", indent.c_str(), pol_en ? "" : "!");
- dump_sigspec(f, sig_en);
- f << stringf(")\n");
-
- f << stringf("%s" " %s = ", indent.c_str(), reg_name.c_str());
- dump_cell_expr_port(f, cell, "D", false);
- f << stringf(";\n");
-
if (!out_is_reg_wire) {
f << stringf("%s" "assign ", indent.c_str());
- dump_sigspec(f, cell->getPort(ID::Q));
+ dump_sigspec(f, ff.sig_q);
f << stringf(" = %s;\n", reg_name.c_str());
}
@@ -1528,8 +1439,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
return true;
}
- // FIXME: $_SR_[PN][PN]_, $_DLATCH_[PN]_, $_DLATCHSR_[PN][PN][PN]_
- // FIXME: $sr, $dlatch, $memrd, $memwr, $fsm
+ // FIXME: $memrd, $memwr, $fsm
return false;
}
@@ -1602,7 +1512,7 @@ void dump_cell(std::ostream &f, std::string indent, RTLIL::Cell *cell)
}
}
- if (siminit && reg_ct.count(cell->type) && cell->hasPort(ID::Q)) {
+ if (siminit && RTLIL::builtin_ff_cell_types().count(cell->type) && cell->hasPort(ID::Q) && !cell->type.in(ID($ff), ID($_FF_))) {
std::stringstream ss;
dump_reg_init(ss, cell->getPort(ID::Q));
if (!ss.str().empty()) {
@@ -1812,7 +1722,7 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module)
std::set<std::pair<RTLIL::Wire*,int>> reg_bits;
for (auto cell : module->cells())
{
- if (!reg_ct.count(cell->type) || !cell->hasPort(ID::Q))
+ if (!RTLIL::builtin_ff_cell_types().count(cell->type) || !cell->hasPort(ID::Q) || cell->type.in(ID($ff), ID($_FF_)))
continue;
RTLIL::SigSpec sig = cell->getPort(ID::Q);
@@ -1984,33 +1894,6 @@ struct VerilogBackend : public Backend {
auto_name_map.clear();
reg_wires.clear();
- reg_ct.clear();
-
- reg_ct.insert(ID($dff));
- reg_ct.insert(ID($adff));
- reg_ct.insert(ID($dffe));
- reg_ct.insert(ID($dlatch));
-
- reg_ct.insert(ID($_DFF_N_));
- reg_ct.insert(ID($_DFF_P_));
-
- reg_ct.insert(ID($_DFF_NN0_));
- reg_ct.insert(ID($_DFF_NN1_));
- reg_ct.insert(ID($_DFF_NP0_));
- reg_ct.insert(ID($_DFF_NP1_));
- reg_ct.insert(ID($_DFF_PN0_));
- reg_ct.insert(ID($_DFF_PN1_));
- reg_ct.insert(ID($_DFF_PP0_));
- reg_ct.insert(ID($_DFF_PP1_));
-
- reg_ct.insert(ID($_DFFSR_NNN_));
- reg_ct.insert(ID($_DFFSR_NNP_));
- reg_ct.insert(ID($_DFFSR_NPN_));
- reg_ct.insert(ID($_DFFSR_NPP_));
- reg_ct.insert(ID($_DFFSR_PNN_));
- reg_ct.insert(ID($_DFFSR_PNP_));
- reg_ct.insert(ID($_DFFSR_PPN_));
- reg_ct.insert(ID($_DFFSR_PPP_));
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++) {
@@ -2107,7 +1990,6 @@ struct VerilogBackend : public Backend {
auto_name_map.clear();
reg_wires.clear();
- reg_ct.clear();
}
} VerilogBackend;