aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorclairexen <claire@symbioticeda.com>2020-09-29 17:31:01 +0200
committerGitHub <noreply@github.com>2020-09-29 17:31:01 +0200
commit7b9a93aa2e455de499f8ddccf19507f5e932dd42 (patch)
tree48c22225727f0cc1e7d3efd19c78317c87296cc0
parente8c9e541a735894a974aaebfb88dfaa9aa3e0f31 (diff)
parentdc4a6176945618a40960fdd79ecfa2a8ef104487 (diff)
downloadyosys-7b9a93aa2e455de499f8ddccf19507f5e932dd42.tar.gz
yosys-7b9a93aa2e455de499f8ddccf19507f5e932dd42.tar.bz2
yosys-7b9a93aa2e455de499f8ddccf19507f5e932dd42.zip
Merge pull request #2393 from nakengelhardt/no_const_sensitivity
write_verilog: emit intermediate wire for constant values in sensitivity list
-rw-r--r--backends/verilog/verilog_backend.cc60
-rw-r--r--tests/verilog/const_arst.ys24
-rw-r--r--tests/verilog/const_sr.ys25
3 files changed, 102 insertions, 7 deletions
diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc
index 372f68ea5..bf980129d 100644
--- a/backends/verilog/verilog_backend.cc
+++ b/backends/verilog/verilog_backend.cc
@@ -926,7 +926,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
{
SigSpec sig_d;
Const val_arst, val_srst;
- std::string reg_bit_name;
+ std::string reg_bit_name, sig_set_name, sig_clr_name, sig_arst_name;
if (chunky) {
reg_bit_name = stringf("%s[%d]", reg_name.c_str(), i);
if (ff.has_d)
@@ -941,6 +941,32 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
if (ff.has_srst)
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");
+ }
+ }
+
dump_attributes(f, indent, cell->attributes);
if (ff.has_clk)
{
@@ -949,27 +975,47 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
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]);
+ if (ff.sig_set[i].wire == NULL)
+ f << stringf("%s", sig_set_name.c_str());
+ else
+ dump_sigspec(f, ff.sig_set[i]);
+
f << stringf(", %sedge ", ff.pol_clr ? "pos" : "neg");
- dump_sigspec(f, ff.sig_clr[i]);
+ if (ff.sig_clr[i].wire == NULL)
+ 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");
- dump_sigspec(f, ff.sig_arst);
+ if (ff.sig_arst[i].wire == NULL)
+ f << stringf("%s", sig_arst_name.c_str());
+ else
+ 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]);
+ if (ff.sig_clr[i].wire == NULL)
+ f << stringf("%s", sig_clr_name.c_str());
+ else
+ 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]);
+ if (ff.sig_set[i].wire == NULL)
+ f << stringf("%s", sig_set_name.c_str());
+ else
+ 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);
+ if (ff.sig_arst[i].wire == NULL)
+ f << stringf("%s", sig_arst_name.c_str());
+ else
+ dump_sigspec(f, ff.sig_arst);
f << stringf(") %s <= ", reg_bit_name.c_str());
dump_sigspec(f, val_arst);
f << stringf(";\n");
diff --git a/tests/verilog/const_arst.ys b/tests/verilog/const_arst.ys
new file mode 100644
index 000000000..df720575c
--- /dev/null
+++ b/tests/verilog/const_arst.ys
@@ -0,0 +1,24 @@
+read_verilog <<EOT
+module test (
+ input clk, d,
+ output reg q
+);
+wire nop = 1'h0;
+always @(posedge clk, posedge nop) begin
+ if (nop) q <= 1'b0;
+ else q <= d;
+end
+endmodule
+EOT
+prep -top test
+write_verilog const_arst.v
+design -stash gold
+read_verilog const_arst.v
+prep -top test
+design -stash gate
+design -copy-from gold -as gold A:top
+design -copy-from gate -as gate A:top
+miter -equiv -flatten -make_assert gold gate miter
+prep -top miter
+clk2fflogic
+sat -set-init-zero -tempinduct -prove-asserts -verify
diff --git a/tests/verilog/const_sr.ys b/tests/verilog/const_sr.ys
new file mode 100644
index 000000000..c1406b0a0
--- /dev/null
+++ b/tests/verilog/const_sr.ys
@@ -0,0 +1,25 @@
+read_verilog <<EOT
+module test (
+ input clk, rst, d,
+ output reg q
+);
+wire nop = 1'h0;
+always @(posedge clk, posedge nop, posedge rst) begin
+ if (rst) q <= 1'b0;
+ else if (nop) q <= 1'b1;
+ else q <= d;
+end
+endmodule
+EOT
+prep -top test
+write_verilog const_sr.v
+design -stash gold
+read_verilog const_sr.v
+prep -top test
+design -stash gate
+design -copy-from gold -as gold A:top
+design -copy-from gate -as gate A:top
+miter -equiv -flatten -make_assert gold gate miter
+prep -top miter
+clk2fflogic
+sat -set-init-zero -tempinduct -prove-asserts -verify