Revert "Wrap SB_LUT+SB_CARRY into $__ICE40_CARRY_WRAPPER"
authorDavid Shah <davey1576@gmail.com>
Sat, 10 Aug 2019 16:14:48 +0000 (17:14 +0100)
committerGitHub <noreply@github.com>
Sat, 10 Aug 2019 16:14:48 +0000 (17:14 +0100)
25 files changed:
CHANGELOG
frontends/ast/ast.cc
passes/pmgen/Makefile.inc
passes/pmgen/ice40_wrapcarry.cc [deleted file]
passes/pmgen/ice40_wrapcarry.pmg [deleted file]
techlibs/ice40/Makefile.inc
techlibs/ice40/arith_map.v
techlibs/ice40/cells_map.v
techlibs/ice40/ice40_unlut.cc [new file with mode: 0644]
techlibs/ice40/synth_ice40.cc
techlibs/ice40/tests/test_arith.ys
tests/opt/opt_expr.ys [deleted file]
tests/opt/opt_ff.v [new file with mode: 0644]
tests/opt/opt_ff.ys [new file with mode: 0644]
tests/opt/opt_ff_sat.v [new file with mode: 0644]
tests/opt/opt_ff_sat.ys [new file with mode: 0644]
tests/opt/opt_lut.ys
tests/opt/opt_rmdff.v [deleted file]
tests/opt/opt_rmdff.ys [deleted file]
tests/opt/opt_rmdff_sat.v [deleted file]
tests/opt/opt_rmdff_sat.ys [deleted file]
tests/various/opt_expr.ys [new file with mode: 0644]
tests/various/opt_rmdff.v [new file with mode: 0644]
tests/various/opt_rmdff.ys [new file with mode: 0644]
tests/various/wreduce.ys

index 21fb8a3f5415c528c4bdbcc0a57654d87125c34d..638c3612174ca21580d98cc0d82718d7784348a9 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -19,8 +19,6 @@ Yosys 0.9 .. Yosys 0.9-dev
     - Added automatic gzip compression (based on filename extension) for backends
     - Improve attribute and parameter encoding in JSON to avoid ambiguities between
       bit vectors and strings containing [01xz]*
-    - Added "ice40_wrapcarry" to encapsulate SB_LUT+SB_CARRY pairs for techmapping
-    - Removed "ice40_unlut"
 
 Yosys 0.8 .. Yosys 0.8-dev
 --------------------------
index 0d6626b196e25f6773291dd6d4e4ed1770d9e11b..07ef0a86e839018a54885e20085c837d6b444e0e 100644 (file)
@@ -1172,7 +1172,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump
 
                        if (design->has((*it)->str)) {
                                RTLIL::Module *existing_mod = design->module((*it)->str);
-                               if (!nooverwrite && !overwrite && !existing_mod->get_blackbox_attribute()) {
+                               if (!nooverwrite && !overwrite && !existing_mod->get_bool_attribute("\\blackbox")) {
                                        log_file_error((*it)->filename, (*it)->linenum, "Re-definition of module `%s'!\n", (*it)->str.c_str());
                                } else if (nooverwrite) {
                                        log("Ignoring re-definition of module `%s' at %s:%d.\n",
index c036061524af565c4a0873a396984951662f933e..7911132db44d6c5f94d7b105a9b1740b2623c61f 100644 (file)
@@ -1,5 +1,4 @@
 OBJS += passes/pmgen/ice40_dsp.o
-OBJS += passes/pmgen/ice40_wrapcarry.o
 OBJS += passes/pmgen/peepopt.o
 
 # --------------------------------------
@@ -13,15 +12,6 @@ passes/pmgen/ice40_dsp_pm.h: passes/pmgen/pmgen.py passes/pmgen/ice40_dsp.pmg
 
 # --------------------------------------
 
-passes/pmgen/ice40_wrapcarry.o: passes/pmgen/ice40_wrapcarry_pm.h
-EXTRA_OBJS += passes/pmgen/ice40_wrapcarry_pm.h
-.SECONDARY: passes/pmgen/ice40_wrapcarry_pm.h
-
-passes/pmgen/ice40_wrapcarry_pm.h: passes/pmgen/pmgen.py passes/pmgen/ice40_wrapcarry.pmg
-       $(P) mkdir -p passes/pmgen && python3 $< -o $@ -p ice40_wrapcarry $(filter-out $<,$^)
-
-# --------------------------------------
-
 passes/pmgen/peepopt.o: passes/pmgen/peepopt_pm.h
 EXTRA_OBJS += passes/pmgen/peepopt_pm.h
 .SECONDARY: passes/pmgen/peepopt_pm.h
diff --git a/passes/pmgen/ice40_wrapcarry.cc b/passes/pmgen/ice40_wrapcarry.cc
deleted file mode 100644 (file)
index 69ef3cd..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- *  yosys -- Yosys Open SYnthesis Suite
- *
- *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
- *
- *  Permission to use, copy, modify, and/or distribute this software for any
- *  purpose with or without fee is hereby granted, provided that the above
- *  copyright notice and this permission notice appear in all copies.
- *
- *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
-
-#include "kernel/yosys.h"
-#include "kernel/sigtools.h"
-
-USING_YOSYS_NAMESPACE
-PRIVATE_NAMESPACE_BEGIN
-
-#include "passes/pmgen/ice40_wrapcarry_pm.h"
-
-void create_ice40_wrapcarry(ice40_wrapcarry_pm &pm)
-{
-       auto &st = pm.st_ice40_wrapcarry;
-
-#if 0
-       log("\n");
-       log("carry: %s\n", log_id(st.carry, "--"));
-       log("lut:   %s\n", log_id(st.lut, "--"));
-#endif
-
-       log("  replacing SB_LUT + SB_CARRY with $__ICE40_CARRY_WRAPPER cell.\n");
-
-       Cell *cell = pm.module->addCell(NEW_ID, "$__ICE40_CARRY_WRAPPER");
-       pm.module->swap_names(cell, st.carry);
-
-       cell->setPort("\\A", st.carry->getPort("\\I0"));
-       cell->setPort("\\B", st.carry->getPort("\\I1"));
-       cell->setPort("\\CI", st.carry->getPort("\\CI"));
-       cell->setPort("\\CO", st.carry->getPort("\\CO"));
-
-       cell->setPort("\\I0", st.lut->getPort("\\I0"));
-       cell->setPort("\\I3", st.lut->getPort("\\I3"));
-       cell->setPort("\\O", st.lut->getPort("\\O"));
-       cell->setParam("\\LUT", st.lut->getParam("\\LUT_INIT"));
-
-       pm.autoremove(st.carry);
-       pm.autoremove(st.lut);
-}
-
-struct Ice40WrapCarryPass : public Pass {
-       Ice40WrapCarryPass() : Pass("ice40_wrapcarry", "iCE40: wrap carries") { }
-       void help() YS_OVERRIDE
-       {
-               //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
-               log("\n");
-               log("    ice40_wrapcarry [selection]\n");
-               log("\n");
-               log("Wrap manually instantiated SB_CARRY cells, along with their associated SB_LUTs,\n");
-               log("into an internal $__ICE40_CARRY_WRAPPER cell for preservation across technology\n");
-               log("mapping.");
-               log("\n");
-       }
-       void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
-       {
-               log_header(design, "Executing ICE40_WRAPCARRY pass (wrap carries).\n");
-
-               size_t argidx;
-               for (argidx = 1; argidx < args.size(); argidx++)
-               {
-                       // if (args[argidx] == "-singleton") {
-                       //      singleton_mode = true;
-                       //      continue;
-                       // }
-                       break;
-               }
-               extra_args(args, argidx, design);
-
-               for (auto module : design->selected_modules())
-                       ice40_wrapcarry_pm(module, module->selected_cells()).run_ice40_wrapcarry(create_ice40_wrapcarry);
-       }
-} Ice40WrapCarryPass;
-
-PRIVATE_NAMESPACE_END
diff --git a/passes/pmgen/ice40_wrapcarry.pmg b/passes/pmgen/ice40_wrapcarry.pmg
deleted file mode 100644 (file)
index 9e64c74..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-pattern ice40_wrapcarry
-
-match carry
-       select carry->type.in(\SB_CARRY)
-endmatch
-
-match lut
-       select lut->type.in(\SB_LUT4)
-       index <SigSpec> port(lut, \I1) === port(carry, \I0)
-       index <SigSpec> port(lut, \I2) === port(carry, \I1)
-endmatch
index 76a89b107383148b4139a150dc7f959cf8125bb6..d258d5a5d901c3753da7c3fb1618bf479bfc5fea 100644 (file)
@@ -4,6 +4,7 @@ OBJS += techlibs/ice40/ice40_braminit.o
 OBJS += techlibs/ice40/ice40_ffssr.o
 OBJS += techlibs/ice40/ice40_ffinit.o
 OBJS += techlibs/ice40/ice40_opt.o
+OBJS += techlibs/ice40/ice40_unlut.o
 
 GENFILES += techlibs/ice40/brams_init1.vh
 GENFILES += techlibs/ice40/brams_init2.vh
index 26b24db9e3c62e7624646a8b44ec76f6f14b1743..fe83a8e38156aad9693617ccbaffbcfd3bb84371 100644 (file)
@@ -44,21 +44,35 @@ module _80_ice40_alu (A, B, CI, BI, X, Y, CO);
 
        genvar i;
        generate for (i = 0; i < Y_WIDTH; i = i + 1) begin:slice
-               \$__ICE40_CARRY_WRAPPER #(
-                       //    A[0]: 1010 1010 1010 1010
-                       //    A[1]: 1100 1100 1100 1100
-                       //    A[2]: 1111 0000 1111 0000
-                       //    A[3]: 1111 1111 0000 0000
-                       .LUT(16'b 0110_1001_1001_0110)
-               ) fadd (
+`ifdef _ABC
+               \$__ICE40_FULL_ADDER carry (
                        .A(AA[i]),
                        .B(BB[i]),
                        .CI(C[i]),
+                       .CO(CO[i]),
+                       .O(Y[i])
+               );
+`else
+               SB_CARRY carry (
+                       .I0(AA[i]),
+                       .I1(BB[i]),
+                       .CI(C[i]),
+                       .CO(CO[i])
+               );
+               SB_LUT4 #(
+                       //         I0: 1010 1010 1010 1010
+                       //         I1: 1100 1100 1100 1100
+                       //         I2: 1111 0000 1111 0000
+                       //         I3: 1111 1111 0000 0000
+                       .LUT_INIT(16'b 0110_1001_1001_0110)
+               ) adder (
                        .I0(1'b0),
+                       .I1(AA[i]),
+                       .I2(BB[i]),
                        .I3(C[i]),
-                       .CO(CO[i]),
                        .O(Y[i])
                );
+`endif
        end endgenerate
 
        assign X = AA ^ BB;
index 0c10c9ac4cf6a1e12b3d49e7e4818b5f9152067e..b4b8311650e156a759cebc5c050fcfe9c4a27666 100644 (file)
@@ -62,21 +62,26 @@ module \$lut (A, Y);
 endmodule
 `endif
 
-`ifndef NO_ADDER
-module \$__ICE40_CARRY_WRAPPER (output CO, O, input A, B, CI, I0, I3);
-  parameter LUT = 0;
+`ifdef _ABC
+module \$__ICE40_FULL_ADDER (output CO, O, input A, B, CI);
   SB_CARRY carry (
     .I0(A),
     .I1(B),
     .CI(CI),
     .CO(CO)
   );
-  \$lut #(
-    .WIDTH(4),
-    .LUT(LUT)
-  ) lut (
-    .A({I3,B,A,I0}),
-    .Y(O)
+  SB_LUT4 #(
+    //         I0: 1010 1010 1010 1010
+    //         I1: 1100 1100 1100 1100
+    //         I2: 1111 0000 1111 0000
+    //         I3: 1111 1111 0000 0000
+    .LUT_INIT(16'b 0110_1001_1001_0110)
+  ) adder (
+    .I0(1'b0),
+    .I1(A),
+    .I2(B),
+    .I3(CI),
+    .O(O)
   );
 endmodule
 `endif
diff --git a/techlibs/ice40/ice40_unlut.cc b/techlibs/ice40/ice40_unlut.cc
new file mode 100644 (file)
index 0000000..f3f70ac
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ *  yosys -- Yosys Open SYnthesis Suite
+ *
+ *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
+ *
+ *  Permission to use, copy, modify, and/or distribute this software for any
+ *  purpose with or without fee is hereby granted, provided that the above
+ *  copyright notice and this permission notice appear in all copies.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include "kernel/yosys.h"
+#include "kernel/sigtools.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+static SigBit get_bit_or_zero(const SigSpec &sig)
+{
+       if (GetSize(sig) == 0)
+               return State::S0;
+       return sig[0];
+}
+
+static void run_ice40_unlut(Module *module)
+{
+       SigMap sigmap(module);
+
+       for (auto cell : module->selected_cells())
+       {
+               if (cell->type == "\\SB_LUT4")
+               {
+                       SigSpec inbits;
+
+                       inbits.append(get_bit_or_zero(cell->getPort("\\I0")));
+                       inbits.append(get_bit_or_zero(cell->getPort("\\I1")));
+                       inbits.append(get_bit_or_zero(cell->getPort("\\I2")));
+                       inbits.append(get_bit_or_zero(cell->getPort("\\I3")));
+                       sigmap.apply(inbits);
+
+                       log("Mapping SB_LUT4 cell %s.%s to $lut.\n", log_id(module), log_id(cell));
+
+                       cell->type ="$lut";
+                       cell->setParam("\\WIDTH", 4);
+                       cell->setParam("\\LUT", cell->getParam("\\LUT_INIT"));
+                       cell->unsetParam("\\LUT_INIT");
+
+                       cell->setPort("\\A", SigSpec({
+                               get_bit_or_zero(cell->getPort("\\I0")),
+                               get_bit_or_zero(cell->getPort("\\I1")),
+                               get_bit_or_zero(cell->getPort("\\I2")),
+                               get_bit_or_zero(cell->getPort("\\I3"))
+                       }));
+                       cell->setPort("\\Y", cell->getPort("\\O")[0]);
+                       cell->unsetPort("\\I0");
+                       cell->unsetPort("\\I1");
+                       cell->unsetPort("\\I2");
+                       cell->unsetPort("\\I3");
+                       cell->unsetPort("\\O");
+
+                       cell->check();
+               }
+       }
+}
+
+struct Ice40UnlutPass : public Pass {
+       Ice40UnlutPass() : Pass("ice40_unlut", "iCE40: transform SB_LUT4 cells to $lut cells") { }
+       void help() YS_OVERRIDE
+       {
+               //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+               log("\n");
+               log("    ice40_unlut [options] [selection]\n");
+               log("\n");
+               log("This command transforms all SB_LUT4 cells to generic $lut cells.\n");
+               log("\n");
+       }
+       void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
+       {
+               log_header(design, "Executing ICE40_UNLUT pass (convert SB_LUT4 to $lut).\n");
+               log_push();
+
+               size_t argidx;
+               for (argidx = 1; argidx < args.size(); argidx++) {
+                       // if (args[argidx] == "-???") {
+                       //  continue;
+                       // }
+                       break;
+               }
+               extra_args(args, argidx, design);
+
+               for (auto module : design->selected_modules())
+                       run_ice40_unlut(module);
+       }
+} Ice40UnlutPass;
+
+PRIVATE_NAMESPACE_END
index c6de81bd91caa42a9a974326fe74e5bfe67d2b1a..dc04eed675de06635264f7b33f4f5a7fd69ed42a 100644 (file)
@@ -238,7 +238,7 @@ struct SynthIce40Pass : public ScriptPass
        {
                if (check_label("begin"))
                {
-                       run("read_verilog -icells -lib +/ice40/cells_sim.v");
+                       run("read_verilog -icells -lib -D_ABC +/ice40/cells_sim.v");
                        run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
                        run("proc");
                }
@@ -293,10 +293,8 @@ struct SynthIce40Pass : public ScriptPass
                {
                        if (nocarry)
                                run("techmap");
-                       else {
-                               run("ice40_wrapcarry");
-                               run("techmap -map +/techmap.v -map +/ice40/arith_map.v");
-                       }
+                       else
+                               run("techmap -map +/techmap.v -map +/ice40/arith_map.v" + std::string(abc == "abc9" ? " -D _ABC" : ""));
                        if (retime || help_mode)
                                run(abc + " -dff", "(only if -retime)");
                        run("ice40_opt");
@@ -311,7 +309,7 @@ struct SynthIce40Pass : public ScriptPass
                                run("opt_merge");
                                run(stringf("dff2dffe -unmap-mince %d", min_ce_use));
                        }
-                       run("techmap -D NO_LUT -D NO_ADDER -map +/ice40/cells_map.v");
+                       run("techmap -D NO_LUT -map +/ice40/cells_map.v");
                        run("opt_expr -mux_undef");
                        run("simplemap");
                        run("ice40_ffinit");
@@ -340,12 +338,13 @@ struct SynthIce40Pass : public ScriptPass
                                        else
                                                wire_delay = 250;
                                        run(abc + stringf(" -W %d -lut +/ice40/abc_%s.lut -box +/ice40/abc_%s.box", wire_delay, device_opt.c_str(), device_opt.c_str()), "(skip if -noabc)");
+                                       run("techmap -D NO_LUT -D _ABC -map +/ice40/cells_map.v");
                                }
                                else
                                        run(abc + " -dress -lut 4", "(skip if -noabc)");
                        }
-                       run("techmap -D NO_LUT -map +/ice40/cells_map.v");
                        run("clean");
+                       run("ice40_unlut");
                        run("opt_lut -dlogic SB_CARRY:I0=2:I1=1:CI=0");
                }
 
index ddb80b700d00c400f79f88f327ac8c7caa0a2dd7..160c767fb873c77310cf5ff8d1765ad163ef5eab 100644 (file)
@@ -1,5 +1,6 @@
 read_verilog test_arith.v
 synth_ice40
+techmap -map ../cells_sim.v
 rename test gate
 
 read_verilog test_arith.v
@@ -7,11 +8,3 @@ rename test gold
 
 miter -equiv -flatten -make_outputs gold gate miter
 sat -verify -prove trigger 0 -show-ports miter
-
-synth_ice40 -top gate
-
-read_verilog test_arith.v
-rename test gold
-
-miter -equiv -flatten -make_outputs gold gate miter
-sat -verify -prove trigger 0 -show-ports miter
diff --git a/tests/opt/opt_expr.ys b/tests/opt/opt_expr.ys
deleted file mode 100644 (file)
index 0c61ac8..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-
-read_verilog <<EOT
-module opt_expr_add_test(input [3:0] i, input [7:0] j, output [8:0] o);
-    assign o = (i << 4) + j;
-endmodule
-EOT
-
-hierarchy -auto-top
-proc
-design -save gold
-
-opt_expr -fine
-wreduce
-
-select -assert-count 1 t:$add r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i
-
-design -stash gate
-
-design -import gold -as gold
-design -import gate -as gate
-
-miter -equiv -flatten -make_assert -make_outputs gold gate miter
-sat -verify -prove-asserts -show-ports miter
-
-##########
-
-read_verilog <<EOT
-module opt_expr_add_signed_test(input signed [3:0] i, input signed [7:0] j, output signed [8:0] o);
-    assign o = (i << 4) + j;
-endmodule
-EOT
-
-hierarchy -auto-top
-proc
-design -save gold
-
-opt_expr -fine
-wreduce
-
-select -assert-count 1 t:$add r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i
-
-design -stash gate
-
-design -import gold -as gold
-design -import gate -as gate
-
-miter -equiv -flatten -make_assert -make_outputs gold gate miter
-sat -verify -prove-asserts -show-ports miter
-
-##########
-
-read_verilog <<EOT
-module opt_expr_sub_test1(input [3:0] i, input [7:0] j, output [8:0] o);
-    assign o = j - (i << 4);
-endmodule
-EOT
-
-hierarchy -auto-top
-proc
-design -save gold
-
-opt_expr -fine
-wreduce
-
-select -assert-count 1 t:$sub r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i
-
-design -stash gate
-
-design -import gold -as gold
-design -import gate -as gate
-
-miter -equiv -flatten -make_assert -make_outputs gold gate miter
-sat -verify -prove-asserts -show-ports miter
-
-##########
-
-read_verilog <<EOT
-module opt_expr_sub_signed_test1(input signed [3:0] i, input signed [7:0] j, output signed [8:0] o);
-    assign o = j - (i << 4);
-endmodule
-EOT
-
-hierarchy -auto-top
-proc
-design -save gold
-
-opt_expr -fine
-wreduce
-
-select -assert-count 1 t:$sub r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i
-
-design -stash gate
-
-design -import gold -as gold
-design -import gate -as gate
-
-miter -equiv -flatten -make_assert -make_outputs gold gate miter
-sat -verify -prove-asserts -show-ports miter
-
-##########
-
-read_verilog <<EOT
-module opt_expr_sub_test2(input [3:0] i, input [7:0] j, output [8:0] o);
-    assign o = (i << 4) - j;
-endmodule
-EOT
-
-hierarchy -auto-top
-proc
-design -save gold
-
-opt_expr -fine
-wreduce
-
-select -assert-count 1 t:$sub r:A_WIDTH=8 r:B_WIDTH=8 r:Y_WIDTH=9 %i %i %i
-
-design -stash gate
-
-design -import gold -as gold
-design -import gate -as gate
-
-miter -equiv -flatten -make_assert -make_outputs gold gate miter
-sat -verify -prove-asserts -show-ports miter
-
-##########
-
-read_verilog <<EOT
-module opt_expr_sub_test4(input [3:0] i, output [8:0] o);
-    assign o = 5'b00010 - i;
-endmodule
-EOT
-
-hierarchy -auto-top
-proc
-design -save gold
-
-opt_expr -fine
-wreduce
-
-select -assert-count 1 t:$sub r:A_WIDTH=2 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i
-
-design -stash gate
-
-design -import gold -as gold
-design -import gate -as gate
-
-miter -equiv -flatten -make_assert -make_outputs gold gate miter
-sat -verify -prove-asserts -show-ports miter
diff --git a/tests/opt/opt_ff.v b/tests/opt/opt_ff.v
new file mode 100644 (file)
index 0000000..a01b64b
--- /dev/null
@@ -0,0 +1,21 @@
+module top(
+    input clk,
+    input rst,
+    input [2:0] a,
+    output [1:0] b
+);
+    reg [2:0] b_reg;
+    initial begin
+        b_reg <= 3'b0;
+    end
+
+    assign b = b_reg[1:0];
+    always @(posedge clk or posedge rst) begin
+        if(rst) begin
+            b_reg <= 3'b0;
+        end else begin
+            b_reg <= a;
+        end
+    end
+endmodule
+
diff --git a/tests/opt/opt_ff.ys b/tests/opt/opt_ff.ys
new file mode 100644 (file)
index 0000000..704c7ac
--- /dev/null
@@ -0,0 +1,3 @@
+read_verilog opt_ff.v
+synth_ice40
+ice40_unlut
diff --git a/tests/opt/opt_ff_sat.v b/tests/opt/opt_ff_sat.v
new file mode 100644 (file)
index 0000000..5a0a6fe
--- /dev/null
@@ -0,0 +1,12 @@
+module top (
+       input clk,
+       output reg [7:0] cnt
+);
+       initial cnt = 0;
+       always @(posedge clk) begin
+               if (cnt < 20)
+                       cnt <= cnt + 1;
+               else
+                       cnt <= 0;
+       end
+endmodule
diff --git a/tests/opt/opt_ff_sat.ys b/tests/opt/opt_ff_sat.ys
new file mode 100644 (file)
index 0000000..4e7cc6c
--- /dev/null
@@ -0,0 +1,5 @@
+read_verilog opt_ff_sat.v
+prep -flatten
+opt_rmdff -sat
+synth
+select -assert-count 5 t:$_DFF_P_
index a9fccbb624c05e4d47e0baf73573977396025abd..59b12c3511544f7c20351948f0110e9606f686b5 100644 (file)
@@ -1,2 +1,4 @@
 read_verilog opt_lut.v
-equiv_opt -map +/ice40/cells_sim.v -assert synth_ice40
+synth_ice40
+ice40_unlut
+equiv_opt -map +/ice40/cells_sim.v -assert opt_lut -dlogic SB_CARRY:I0=1:I1=2:CI=3
diff --git a/tests/opt/opt_rmdff.v b/tests/opt/opt_rmdff.v
deleted file mode 100644 (file)
index b1c0670..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-module opt_rmdff_test (input C, input D, input E, output [29:0] Q);
-\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) remove0 (.CLK(C), .D(D), .EN(1'b0), .Q(Q[0])); // EN is never active
-(* init = "1'b1" *) wire Q1; assign Q[1] = Q1;
-\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) remove1 (.CLK(C), .D(D), .EN(1'b0), .Q(Q1)); // EN is never active
-\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) remove2 (.CLK(C), .D(D), .EN(1'bx), .Q(Q[2])); // EN is don't care
-\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) keep3 (.CLK(C), .D(D), .EN(1'b1), .Q(Q[3])); // EN is always active
-(* init = "1'b0" *) wire Q4; assign Q[4] = Q4;
-\$dffe #(.WIDTH(1), .CLK_POLARITY(0), .EN_POLARITY(1)) keep4 (.CLK(C), .D(D), .EN(1'b1), .Q(Q4)); // EN is always active
-\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(0)) remove5 (.CLK(C), .D(D), .EN(1'b1), .Q(Q[5])); // EN is never active
-\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(0)) remove6 (.CLK(C), .D(D), .EN(1'bx), .Q(Q[6])); // EN is don't care
-(* init = "1'b0" *) wire Q7; assign Q[7] = Q7;
-\$dffe #(.WIDTH(1), .CLK_POLARITY(0), .EN_POLARITY(0)) keep7 (.CLK(C), .D(D), .EN(E), .Q(Q7)); // EN is non constant
-
-\$_DFFE_PP_ remove8 (.C(C), .D(D), .E(1'b0), .Q(Q[8])); // EN is never active
-(* init = "1'b1" *) wire Q9; assign Q[9] = Q9;
-\$_DFFE_PP_ remove9 (.C(C), .D(D), .E(1'b0), .Q(Q9)); // EN is never active
-\$_DFFE_PP_ remove10 (.C(C), .D(D), .E(1'bx), .Q(Q[10])); // EN is don't care
-\$_DFFE_PP_ keep11 (.C(C), .D(D), .E(1'b1), .Q(Q[11])); // EN is always active
-(* init = "1'b0" *) wire Q12; assign Q[12] = Q12;
-\$_DFFE_PP_ keep12 (.C(C), .D(D), .E(1'b1), .Q(Q12)); // EN is always active
-
-\$_DFFE_NN_ remove13 (.C(C), .D(D), .E(1'b1), .Q(Q[13])); // EN is never active
-(* init = "1'b1" *) wire Q14; assign Q[14] = Q14;
-\$_DFFE_NN_ remove14 (.C(C), .D(D), .E(1'b1), .Q(Q14)); // EN is never active
-\$_DFFE_NN_ remove15 (.C(C), .D(D), .E(1'bx), .Q(Q[15])); // EN is don't care
-\$_DFFE_NN_ keep16 (.C(C), .D(D), .E(1'b0), .Q(Q[16])); // EN is always active
-(* init = "1'b0" *) wire Q17; assign Q[17] = Q17;
-\$_DFFE_NN_ keep17 (.C(C), .D(D), .E(1'b0), .Q(Q17)); // EN is always active
-
-\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) remove18 (.CLK(1'b0), .D(D), .EN(E), .Q(Q[18])); // CLK is constant
-(* init = "1'b1" *) wire Q19; assign Q[19] = Q19;
-\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) remove19 (.CLK(1'b1), .D(D), .EN(E), .Q(Q19)); // CLK is constant
-\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) remove20 (.CLK(C), .D(1'bx), .EN(E), .Q(Q[20])); // D is undriven, Q has no initial value
-(* init = "1'b0" *) wire Q21; assign Q[21] = Q21;
-\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) keep21 (.CLK(C), .D(1'bx), .EN(E), .Q(Q21)); // D is undriven, Q has initial value
-//\$dffe #(.WIDTH(1), .CLK_POLARITY(0), .EN_POLARITY(1)) remove22 (.CLK(C), .D(1'b0), .EN(1'b1), .Q(Q[22])); // D is constant, no initial Q value, EN is always active
-//                                                                                                           // (TODO, Q starts with 1'bx and becomes 1'b0)
-(* init = "1'b0" *) wire Q23; assign Q[23] = Q23;
-\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) noenable23 (.CLK(C), .D(1'b0), .EN(1'b1), .Q(Q23)); // D is constant, initial Q value same as D, EN is always active
-(* init = "1'b1" *) wire Q24; assign Q[24] = Q24;
-\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(0)) keep24 (.CLK(C), .D(1'b0), .EN(1'b0), .Q(Q24)); // D is constant, initial Q value NOT same as D, EN is always active
-(* init = "1'b1" *) wire Q25; assign Q[25] = Q25;
-\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(0)) remove25 (.CLK(C), .D(1'b0), .EN(1'b1), .Q(Q25)); // D is constant, EN is never active
-\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) remove26 (.CLK(C), .D(Q[26]), .EN(1'b1), .Q(Q[26])); // D is Q, EN is always active
-\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(0)) remove27 (.CLK(C), .D(Q[27]), .EN(1'b1), .Q(Q[27])); // D is Q, EN is never active, but no initial value
-\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(0)) remove28 (.CLK(C), .D(Q[28]), .EN(E), .Q(Q[28])); // EN is nonconst, but no initial value
-(* init = "1'b1" *) wire Q29; assign Q[29] = Q29;
-\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) keep29 (.CLK(C), .D(Q[29]), .EN(1'b1), .Q(Q29)); // EN is always active, but with initial value
-
-endmodule
diff --git a/tests/opt/opt_rmdff.ys b/tests/opt/opt_rmdff.ys
deleted file mode 100644 (file)
index 081f817..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-read_verilog -icells opt_rmdff.v
-prep
-design -stash gold
-read_verilog -icells opt_rmdff.v
-proc
-opt_rmdff
-
-select -assert-count 0 c:remove*
-select -assert-min 7 c:keep*
-select -assert-count 0  t:$dffe 7:$_DFFE_* %u c:noenable* %i
-
-design -stash gate
-
-design -import gold -as gold
-design -import gate -as gate
-
-equiv_make gold gate equiv
-hierarchy -top equiv
-equiv_simple -undef
-equiv_status -assert
-
-design -load gold
-stat
-
-design -load gate
-stat
diff --git a/tests/opt/opt_rmdff_sat.v b/tests/opt/opt_rmdff_sat.v
deleted file mode 100644 (file)
index 5a0a6fe..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-module top (
-       input clk,
-       output reg [7:0] cnt
-);
-       initial cnt = 0;
-       always @(posedge clk) begin
-               if (cnt < 20)
-                       cnt <= cnt + 1;
-               else
-                       cnt <= 0;
-       end
-endmodule
diff --git a/tests/opt/opt_rmdff_sat.ys b/tests/opt/opt_rmdff_sat.ys
deleted file mode 100644 (file)
index 1c3dd9c..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-read_verilog opt_rmdff_sat.v
-prep -flatten
-opt_rmdff -sat
-synth
-select -assert-count 5 t:$_DFF_P_
diff --git a/tests/various/opt_expr.ys b/tests/various/opt_expr.ys
new file mode 100644 (file)
index 0000000..0c61ac8
--- /dev/null
@@ -0,0 +1,148 @@
+
+read_verilog <<EOT
+module opt_expr_add_test(input [3:0] i, input [7:0] j, output [8:0] o);
+    assign o = (i << 4) + j;
+endmodule
+EOT
+
+hierarchy -auto-top
+proc
+design -save gold
+
+opt_expr -fine
+wreduce
+
+select -assert-count 1 t:$add r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i
+
+design -stash gate
+
+design -import gold -as gold
+design -import gate -as gate
+
+miter -equiv -flatten -make_assert -make_outputs gold gate miter
+sat -verify -prove-asserts -show-ports miter
+
+##########
+
+read_verilog <<EOT
+module opt_expr_add_signed_test(input signed [3:0] i, input signed [7:0] j, output signed [8:0] o);
+    assign o = (i << 4) + j;
+endmodule
+EOT
+
+hierarchy -auto-top
+proc
+design -save gold
+
+opt_expr -fine
+wreduce
+
+select -assert-count 1 t:$add r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i
+
+design -stash gate
+
+design -import gold -as gold
+design -import gate -as gate
+
+miter -equiv -flatten -make_assert -make_outputs gold gate miter
+sat -verify -prove-asserts -show-ports miter
+
+##########
+
+read_verilog <<EOT
+module opt_expr_sub_test1(input [3:0] i, input [7:0] j, output [8:0] o);
+    assign o = j - (i << 4);
+endmodule
+EOT
+
+hierarchy -auto-top
+proc
+design -save gold
+
+opt_expr -fine
+wreduce
+
+select -assert-count 1 t:$sub r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i
+
+design -stash gate
+
+design -import gold -as gold
+design -import gate -as gate
+
+miter -equiv -flatten -make_assert -make_outputs gold gate miter
+sat -verify -prove-asserts -show-ports miter
+
+##########
+
+read_verilog <<EOT
+module opt_expr_sub_signed_test1(input signed [3:0] i, input signed [7:0] j, output signed [8:0] o);
+    assign o = j - (i << 4);
+endmodule
+EOT
+
+hierarchy -auto-top
+proc
+design -save gold
+
+opt_expr -fine
+wreduce
+
+select -assert-count 1 t:$sub r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i
+
+design -stash gate
+
+design -import gold -as gold
+design -import gate -as gate
+
+miter -equiv -flatten -make_assert -make_outputs gold gate miter
+sat -verify -prove-asserts -show-ports miter
+
+##########
+
+read_verilog <<EOT
+module opt_expr_sub_test2(input [3:0] i, input [7:0] j, output [8:0] o);
+    assign o = (i << 4) - j;
+endmodule
+EOT
+
+hierarchy -auto-top
+proc
+design -save gold
+
+opt_expr -fine
+wreduce
+
+select -assert-count 1 t:$sub r:A_WIDTH=8 r:B_WIDTH=8 r:Y_WIDTH=9 %i %i %i
+
+design -stash gate
+
+design -import gold -as gold
+design -import gate -as gate
+
+miter -equiv -flatten -make_assert -make_outputs gold gate miter
+sat -verify -prove-asserts -show-ports miter
+
+##########
+
+read_verilog <<EOT
+module opt_expr_sub_test4(input [3:0] i, output [8:0] o);
+    assign o = 5'b00010 - i;
+endmodule
+EOT
+
+hierarchy -auto-top
+proc
+design -save gold
+
+opt_expr -fine
+wreduce
+
+select -assert-count 1 t:$sub r:A_WIDTH=2 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i
+
+design -stash gate
+
+design -import gold -as gold
+design -import gate -as gate
+
+miter -equiv -flatten -make_assert -make_outputs gold gate miter
+sat -verify -prove-asserts -show-ports miter
diff --git a/tests/various/opt_rmdff.v b/tests/various/opt_rmdff.v
new file mode 100644 (file)
index 0000000..b1c0670
--- /dev/null
@@ -0,0 +1,50 @@
+module opt_rmdff_test (input C, input D, input E, output [29:0] Q);
+\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) remove0 (.CLK(C), .D(D), .EN(1'b0), .Q(Q[0])); // EN is never active
+(* init = "1'b1" *) wire Q1; assign Q[1] = Q1;
+\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) remove1 (.CLK(C), .D(D), .EN(1'b0), .Q(Q1)); // EN is never active
+\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) remove2 (.CLK(C), .D(D), .EN(1'bx), .Q(Q[2])); // EN is don't care
+\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) keep3 (.CLK(C), .D(D), .EN(1'b1), .Q(Q[3])); // EN is always active
+(* init = "1'b0" *) wire Q4; assign Q[4] = Q4;
+\$dffe #(.WIDTH(1), .CLK_POLARITY(0), .EN_POLARITY(1)) keep4 (.CLK(C), .D(D), .EN(1'b1), .Q(Q4)); // EN is always active
+\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(0)) remove5 (.CLK(C), .D(D), .EN(1'b1), .Q(Q[5])); // EN is never active
+\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(0)) remove6 (.CLK(C), .D(D), .EN(1'bx), .Q(Q[6])); // EN is don't care
+(* init = "1'b0" *) wire Q7; assign Q[7] = Q7;
+\$dffe #(.WIDTH(1), .CLK_POLARITY(0), .EN_POLARITY(0)) keep7 (.CLK(C), .D(D), .EN(E), .Q(Q7)); // EN is non constant
+
+\$_DFFE_PP_ remove8 (.C(C), .D(D), .E(1'b0), .Q(Q[8])); // EN is never active
+(* init = "1'b1" *) wire Q9; assign Q[9] = Q9;
+\$_DFFE_PP_ remove9 (.C(C), .D(D), .E(1'b0), .Q(Q9)); // EN is never active
+\$_DFFE_PP_ remove10 (.C(C), .D(D), .E(1'bx), .Q(Q[10])); // EN is don't care
+\$_DFFE_PP_ keep11 (.C(C), .D(D), .E(1'b1), .Q(Q[11])); // EN is always active
+(* init = "1'b0" *) wire Q12; assign Q[12] = Q12;
+\$_DFFE_PP_ keep12 (.C(C), .D(D), .E(1'b1), .Q(Q12)); // EN is always active
+
+\$_DFFE_NN_ remove13 (.C(C), .D(D), .E(1'b1), .Q(Q[13])); // EN is never active
+(* init = "1'b1" *) wire Q14; assign Q[14] = Q14;
+\$_DFFE_NN_ remove14 (.C(C), .D(D), .E(1'b1), .Q(Q14)); // EN is never active
+\$_DFFE_NN_ remove15 (.C(C), .D(D), .E(1'bx), .Q(Q[15])); // EN is don't care
+\$_DFFE_NN_ keep16 (.C(C), .D(D), .E(1'b0), .Q(Q[16])); // EN is always active
+(* init = "1'b0" *) wire Q17; assign Q[17] = Q17;
+\$_DFFE_NN_ keep17 (.C(C), .D(D), .E(1'b0), .Q(Q17)); // EN is always active
+
+\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) remove18 (.CLK(1'b0), .D(D), .EN(E), .Q(Q[18])); // CLK is constant
+(* init = "1'b1" *) wire Q19; assign Q[19] = Q19;
+\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) remove19 (.CLK(1'b1), .D(D), .EN(E), .Q(Q19)); // CLK is constant
+\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) remove20 (.CLK(C), .D(1'bx), .EN(E), .Q(Q[20])); // D is undriven, Q has no initial value
+(* init = "1'b0" *) wire Q21; assign Q[21] = Q21;
+\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) keep21 (.CLK(C), .D(1'bx), .EN(E), .Q(Q21)); // D is undriven, Q has initial value
+//\$dffe #(.WIDTH(1), .CLK_POLARITY(0), .EN_POLARITY(1)) remove22 (.CLK(C), .D(1'b0), .EN(1'b1), .Q(Q[22])); // D is constant, no initial Q value, EN is always active
+//                                                                                                           // (TODO, Q starts with 1'bx and becomes 1'b0)
+(* init = "1'b0" *) wire Q23; assign Q[23] = Q23;
+\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) noenable23 (.CLK(C), .D(1'b0), .EN(1'b1), .Q(Q23)); // D is constant, initial Q value same as D, EN is always active
+(* init = "1'b1" *) wire Q24; assign Q[24] = Q24;
+\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(0)) keep24 (.CLK(C), .D(1'b0), .EN(1'b0), .Q(Q24)); // D is constant, initial Q value NOT same as D, EN is always active
+(* init = "1'b1" *) wire Q25; assign Q[25] = Q25;
+\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(0)) remove25 (.CLK(C), .D(1'b0), .EN(1'b1), .Q(Q25)); // D is constant, EN is never active
+\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) remove26 (.CLK(C), .D(Q[26]), .EN(1'b1), .Q(Q[26])); // D is Q, EN is always active
+\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(0)) remove27 (.CLK(C), .D(Q[27]), .EN(1'b1), .Q(Q[27])); // D is Q, EN is never active, but no initial value
+\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(0)) remove28 (.CLK(C), .D(Q[28]), .EN(E), .Q(Q[28])); // EN is nonconst, but no initial value
+(* init = "1'b1" *) wire Q29; assign Q[29] = Q29;
+\$dffe #(.WIDTH(1), .CLK_POLARITY(1), .EN_POLARITY(1)) keep29 (.CLK(C), .D(Q[29]), .EN(1'b1), .Q(Q29)); // EN is always active, but with initial value
+
+endmodule
diff --git a/tests/various/opt_rmdff.ys b/tests/various/opt_rmdff.ys
new file mode 100644 (file)
index 0000000..081f817
--- /dev/null
@@ -0,0 +1,26 @@
+read_verilog -icells opt_rmdff.v
+prep
+design -stash gold
+read_verilog -icells opt_rmdff.v
+proc
+opt_rmdff
+
+select -assert-count 0 c:remove*
+select -assert-min 7 c:keep*
+select -assert-count 0  t:$dffe 7:$_DFFE_* %u c:noenable* %i
+
+design -stash gate
+
+design -import gold -as gold
+design -import gate -as gate
+
+equiv_make gold gate equiv
+hierarchy -top equiv
+equiv_simple -undef
+equiv_status -assert
+
+design -load gold
+stat
+
+design -load gate
+stat
index 2e0812c483a8b019121ef622373e909597db9a89..4257292f57cf48d3abd00e18478170ab82df504a 100644 (file)
@@ -36,6 +36,7 @@ design -save gold
 opt_expr
 wreduce
 
+dump
 select -assert-count 1 t:$sub r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i
 
 design -stash gate
@@ -45,35 +46,3 @@ design -import gate -as gate
 
 miter -equiv -flatten -make_assert -make_outputs gold gate miter
 sat -verify -prove-asserts -show-ports miter
-
-##########
-
-# Testcase from: https://github.com/YosysHQ/yosys/commit/25680f6a078bb32f157bd580705656496717bafb
-design -reset
-read_verilog <<EOT
-module top(
-    input clk,
-    input rst,
-    input [2:0] a,
-    output [1:0] b
-);
-    reg [2:0] b_reg;
-    initial begin
-        b_reg <= 3'b0;
-    end
-
-    assign b = b_reg[1:0];
-    always @(posedge clk or posedge rst) begin
-        if(rst) begin
-            b_reg <= 3'b0;
-        end else begin
-            b_reg <= a;
-        end
-    end
-endmodule
-EOT
-
-proc
-wreduce
-
-select -assert-count 1 t:$adff r:ARST_VALUE=2'b00 %i