diff options
| author | Claire Xen <claire@clairexen.net> | 2022-02-11 16:03:12 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-02-11 16:03:12 +0100 |
| commit | 49545c73f7f5a5cf73d287fd371f2ff39311f621 (patch) | |
| tree | d0f20b8def36e551c6735d4fc6033aaa2633fe80 /tests/opt | |
| parent | 90b40aa51f7d666792d4f0b1830ee75b81678a1f (diff) | |
| parent | e0165188669fcef2c5784c9916683889a2164e5d (diff) | |
| download | yosys-49545c73f7f5a5cf73d287fd371f2ff39311f621.tar.gz yosys-49545c73f7f5a5cf73d287fd371f2ff39311f621.tar.bz2 yosys-49545c73f7f5a5cf73d287fd371f2ff39311f621.zip | |
Merge branch 'master' into clk2ff-better-names
Diffstat (limited to 'tests/opt')
| -rw-r--r-- | tests/opt/bug1854.ys | 17 | ||||
| -rw-r--r-- | tests/opt/bug2623.ys | 14 | ||||
| -rw-r--r-- | tests/opt/bug2765.ys | 34 | ||||
| -rw-r--r-- | tests/opt/bug2766.ys | 101 | ||||
| -rw-r--r-- | tests/opt/bug2824.ys | 7 | ||||
| -rw-r--r-- | tests/opt/bug2920.ys | 42 | ||||
| -rw-r--r-- | tests/opt/bug3047.ys | 12 | ||||
| -rw-r--r-- | tests/opt/bug3117.ys | 34 | ||||
| -rw-r--r-- | tests/opt/memory_dff_trans.ys | 874 | ||||
| -rw-r--r-- | tests/opt/memory_map_offset.ys | 100 | ||||
| -rw-r--r-- | tests/opt/opt_clean_init.ys | 31 | ||||
| -rw-r--r-- | tests/opt/opt_clean_mem.ys | 17 | ||||
| -rw-r--r-- | tests/opt/opt_dff_sr.ys | 21 | ||||
| -rw-r--r-- | tests/opt/opt_expr_constconn.v | 8 | ||||
| -rw-r--r-- | tests/opt/opt_expr_constconn.ys | 7 | ||||
| -rw-r--r-- | tests/opt/opt_mem_feedback.ys | 189 | ||||
| -rw-r--r-- | tests/opt/opt_mem_priority.ys | 209 | ||||
| -rw-r--r-- | tests/opt/opt_merge_init.ys | 2 | ||||
| -rw-r--r-- | tests/opt/opt_reduce_bmux.ys | 117 | ||||
| -rw-r--r-- | tests/opt/opt_reduce_demux.ys | 91 |
20 files changed, 1898 insertions, 29 deletions
diff --git a/tests/opt/bug1854.ys b/tests/opt/bug1854.ys new file mode 100644 index 000000000..00a36ae94 --- /dev/null +++ b/tests/opt/bug1854.ys @@ -0,0 +1,17 @@ +read_verilog << EOT +module top(input clk, input [3:0] addr, output reg [0:0] dout); + reg [1:0] mem[0:15]; + initial begin + mem[0] = 2'b00; + mem[1] = 2'b01; + mem[2] = 2'b10; + mem[3] = 2'b11; + end + always @(posedge clk) + dout <= mem[addr]; +endmodule +EOT + +prep -rdff + +select -assert-none t:$dff diff --git a/tests/opt/bug2623.ys b/tests/opt/bug2623.ys new file mode 100644 index 000000000..2ff23ea6f --- /dev/null +++ b/tests/opt/bug2623.ys @@ -0,0 +1,14 @@ +read_rtlil << EOT + +module \top + wire output 1 \a + wire width 0 $dummy + cell \abc \abc + connect \a \a + connect \b $dummy + end +end + +EOT + +opt_clean diff --git a/tests/opt/bug2765.ys b/tests/opt/bug2765.ys new file mode 100644 index 000000000..7cb790bd7 --- /dev/null +++ b/tests/opt/bug2765.ys @@ -0,0 +1,34 @@ +read_verilog << EOT + +module top(...); + +input clk; +input [3:0] wa; +input [15:0] wd; +input [3:0] ra; +output [15:0] rd; + +reg [15:0] mem[0:15]; + +integer i; +reg x; + +always @(posedge clk) begin + for (i = 0; i < 2; i = i + 1) begin + x = i == 1; + if (x) + mem[wa] <= wd; + end +end + +assign rd = mem[ra]; + +endmodule + +EOT + +proc +opt +select -assert-count 2 t:$memwr_v2 +opt_mem +select -assert-count 1 t:$memwr_v2 diff --git a/tests/opt/bug2766.ys b/tests/opt/bug2766.ys new file mode 100644 index 000000000..c7aa916f4 --- /dev/null +++ b/tests/opt/bug2766.ys @@ -0,0 +1,101 @@ +# Case 1. + +read_verilog << EOT + +module top(...); + +input clk; +input sel; +input [3:0] ra; +input [3:0] wa; +input wd; +output [3:0] rd; + +reg [3:0] mem[0:15]; + +integer i; +initial begin + for (i = 0; i < 16; i = i + 1) + mem[i] <= i; +end + +assign rd = mem[ra]; + +always @(posedge clk) begin + mem[wa] <= {4{sel ? wd : mem[wa][0]}}; +end + +endmodule + +EOT + +hierarchy -auto-top +proc +opt_clean + +design -save start +memory_map +design -save preopt + +design -load start +opt_mem_feedback +memory_map +design -save postopt + +equiv_opt -assert -run prepare: : + + + +design -reset + +# Case 2. + +read_verilog << EOT + +module top(...); + +input clk; +input s1; +input s2; +input s3; +input [3:0] ra; +input [3:0] wa; +input wd; +output rd; + +reg mem[0:15]; + +integer i; +initial begin + for (i = 0; i < 16; i = i + 1) + mem[i] <= ^i; +end + +assign rd = mem[ra]; + +wire ta = s1 ? wd : mem[wa]; +wire tb = s2 ? wd : ta; +wire tc = s3 ? tb : ta; + +always @(posedge clk) begin + mem[wa] <= tc; +end + +endmodule + +EOT + +hierarchy -auto-top +proc +opt_clean + +design -save start +memory_map +design -save preopt + +design -load start +opt_mem_feedback +memory_map +design -save postopt + +equiv_opt -assert -run prepare: : diff --git a/tests/opt/bug2824.ys b/tests/opt/bug2824.ys new file mode 100644 index 000000000..9d0d1e9e5 --- /dev/null +++ b/tests/opt/bug2824.ys @@ -0,0 +1,7 @@ +read_verilog -icells << EOT +module top(input I, output O); +$pmux #(.WIDTH(1), .S_WIDTH(2)) m (.S({I, 1'b0}), .A(1'b0), .B({I, 1'b0}), .Y(O)); +endmodule +EOT + +equiv_opt -assert opt_muxtree diff --git a/tests/opt/bug2920.ys b/tests/opt/bug2920.ys new file mode 100644 index 000000000..a8281a73a --- /dev/null +++ b/tests/opt/bug2920.ys @@ -0,0 +1,42 @@ +read_ilang <<EOT + +module \mod + wire input 1 \clk + attribute \init 2'00 + wire width 2 $q1 + attribute \init 2'00 + wire width 2 $q2 + wire output 2 width 4 \q + cell $dff $ff1 + parameter \CLK_POLARITY 1'1 + parameter \WIDTH 1 + connect \CLK \clk + connect \D 1'0 + connect \Q $q1 [0] + end + cell $dff $ff2 + parameter \CLK_POLARITY 1'1 + parameter \WIDTH 1 + connect \CLK \clk + connect \D 1'0 + connect \Q $q2 [0] + end + cell $dff $ff3 + parameter \CLK_POLARITY 1'1 + parameter \WIDTH 2 + connect \CLK \clk + connect \D 2'00 + connect \Q { $q1 [1] $q2 [1] } + end + connect \q [0] $q1 [0] + connect \q [1] $q2 [0] + connect \q [2] $q1 [1] + connect \q [3] $q2 [1] +end + +EOT + +opt_clean +opt_merge +opt_dff +opt_clean diff --git a/tests/opt/bug3047.ys b/tests/opt/bug3047.ys new file mode 100644 index 000000000..6713877ce --- /dev/null +++ b/tests/opt/bug3047.ys @@ -0,0 +1,12 @@ +read_verilog << EOT + +module test (A, B, C, D, Y); + input A, B, C, D; + output Y; + assign Y = A^B^C^D^A; +endmodule + +EOT + +techmap +equiv_opt -assert extract_reduce diff --git a/tests/opt/bug3117.ys b/tests/opt/bug3117.ys new file mode 100644 index 000000000..177b3ab9a --- /dev/null +++ b/tests/opt/bug3117.ys @@ -0,0 +1,34 @@ +read_verilog << EOT + +module test (...); + +input [7:1] wa1; +input [7:1] wa2; +input [7:0] ra; +output [7:0] rd; +input clk; +input we1, we2; +input [15:0] wd1, wd2; + +reg [7:0] mem [0:255]; + +assign rd = mem[ra]; + +always @(posedge clk) begin + if (we1) begin + mem[{wa1, 1'b0}] <= wd1[7:0]; + mem[{wa1, 1'b1}] <= wd1[15:8]; + end else begin + mem[{wa2, 1'b0}] <= wd2[7:0]; + mem[{wa2, 1'b1}] <= wd2[15:8]; + end +end + +endmodule + +EOT + +proc +opt +memory_share +select -assert-count 1 t:$memwr_v2 diff --git a/tests/opt/memory_dff_trans.ys b/tests/opt/memory_dff_trans.ys new file mode 100644 index 000000000..102b36f26 --- /dev/null +++ b/tests/opt/memory_dff_trans.ys @@ -0,0 +1,874 @@ +# Good case 1: single port. + +read_verilog << EOT + +module top( + input [3:0] addr, + input [3:0] wd, + input we, + input clk, + output reg [3:0] rd, +); + +reg [3:0] mem[0:15]; + +always @(posedge clk) begin + if (we) begin + mem[addr] <= wd; + rd <= wd; + end else begin + rd <= mem[addr]; + end +end + +endmodule + +EOT + +hierarchy -auto-top +proc +opt_dff +opt_clean +memory_dff +memory_collect +select -assert-count 1 t:$mem_v2 +select -assert-count 1 t:$mem_v2 r:RD_TRANSPARENCY_MASK=1'b1 r:RD_COLLISION_X_MASK=1'b0 %i %i + +design -reset + +# Good case 2: single port, exclusive. + +read_verilog << EOT + +module top( + input [3:0] addr, + input [3:0] wd, + input we, + input clk, + output reg [3:0] rd, +); + +reg [3:0] mem[0:15]; + +always @(posedge clk) begin + if (we) begin + mem[addr] <= wd; + end else begin + rd <= mem[addr]; + end +end + +endmodule + +EOT + +hierarchy -auto-top +proc +opt_dff +opt_clean +memory_dff +memory_collect +select -assert-count 1 t:$mem_v2 +select -assert-count 1 t:$mem_v2 r:RD_TRANSPARENCY_MASK=1'b0 r:RD_COLLISION_X_MASK=1'b1 %i %i + +design -reset + +# Good case 3: proper bypass muxes. + +read_verilog << EOT + +module top( + input [3:0] ra, + input [3:0] wa1, + input [3:0] wa2, + input [3:0] wd1, + input [3:0] wd2, + input we1, we2, + input re, + input clk, + output reg [3:0] rd, +); + +reg [3:0] mem[0:15]; + +always @(posedge clk) begin + if (we1) + mem[wa1] <= wd1; + if (we2) + mem[wa2] <= wd2; + if (re) begin + rd <= mem[ra]; + if (we1 && wa1 == ra) + rd <= wd1; + if (we2 && wa2 == ra) + rd <= wd2; + end +end + +endmodule + +EOT + +hierarchy -auto-top +proc +opt_dff +opt_clean +memory_dff +memory_collect +select -assert-count 1 t:$mem_v2 +select -assert-count 1 t:$mem_v2 r:RD_TRANSPARENCY_MASK=2'b11 r:RD_COLLISION_X_MASK=2'b00 %i %i + +design -reset + +# Good case 4: proper bypass mux, but only one. + +read_verilog << EOT + +module top( + input [3:0] ra, + input [3:0] wa1, + input [3:0] wa2, + input [3:0] wd1, + input [3:0] wd2, + input we1, we2, + input re, + input clk, + output reg [3:0] rd, +); + +reg [3:0] mem[0:15]; + +always @(posedge clk) begin + if (we1) + mem[wa1] <= wd1; + if (we2) + mem[wa2] <= wd2; + if (re) begin + rd <= mem[ra]; + if (we1 && wa1 == ra) + rd <= wd1; + end +end + +endmodule + +EOT + +hierarchy -auto-top +proc +opt_dff +opt_clean +memory_dff +memory_collect +select -assert-count 1 t:$mem_v2 +select -assert-count 1 t:$mem_v2 r:RD_TRANSPARENCY_MASK=2'b01 r:RD_COLLISION_X_MASK=2'b00 %i %i + +design -reset + +# Good case 5: proper bypass mux, but the other one. + +read_verilog << EOT + +module top( + input [3:0] ra, + input [3:0] wa1, + input [3:0] wa2, + input [3:0] wd1, + input [3:0] wd2, + input we1, we2, + input re, + input clk, + output reg [3:0] rd, +); + +reg [3:0] mem[0:15]; + +always @(posedge clk) begin + if (we1) + mem[wa1] <= wd1; + if (we2) + mem[wa2] <= wd2; + if (re) begin + rd <= mem[ra]; + if (we2 && wa2 == ra) + rd <= wd2; + end +end + +endmodule + +EOT + +hierarchy -auto-top +proc +opt_dff +opt_clean +memory_dff +memory_collect +select -assert-count 1 t:$mem_v2 +select -assert-count 1 t:$mem_v2 r:RD_TRANSPARENCY_MASK=2'b10 r:RD_COLLISION_X_MASK=2'b00 %i %i + +design -reset + +# Good case 6: 'x mux. + +read_verilog << EOT + +module top( + input [3:0] ra, + input [3:0] wa1, + input [3:0] wa2, + input [3:0] wd1, + input [3:0] wd2, + input we1, we2, + input re, + input clk, + output reg [3:0] rd, +); + +reg [3:0] mem[0:15]; + +always @(posedge clk) begin + if (we1) + mem[wa1] <= wd1; + if (we2) + mem[wa2] <= wd2; + if (re) begin + rd <= mem[ra]; + if (we1 && wa1 == ra) + rd <= 4'hx; + if (we2 && wa2 == ra) + rd <= wd2; + end +end + +endmodule + +EOT + +hierarchy -auto-top +proc +opt_dff +opt_clean +memory_dff +memory_collect +select -assert-count 1 t:$mem_v2 +select -assert-count 1 t:$mem_v2 r:RD_TRANSPARENCY_MASK=2'b10 r:RD_COLLISION_X_MASK=2'b01 %i %i + +design -reset + +# Good case 7: uncollidable addresses. + +read_verilog << EOT + +module top( + input [3:0] addr, + input [3:0] wd1, + input [3:0] wd2, + input we1, we2, + input re, + input clk, + output reg [3:0] rd, +); + +reg [3:0] mem[0:15]; + +wire [3:0] wa1 = addr; +wire [3:0] wa2 = addr + 1; +wire [3:0] ra = addr + 2; + +always @(posedge clk) begin + if (we1) + mem[wa1] <= wd1; + if (we2) + mem[wa2] <= wd2; + if (re) begin + rd <= mem[ra]; + end +end + +endmodule + +EOT + +hierarchy -auto-top +proc +opt_dff +opt_clean +memory_dff +memory_collect +select -assert-count 1 t:$mem_v2 +select -assert-count 1 t:$mem_v2 r:RD_TRANSPARENCY_MASK=2'b00 r:RD_COLLISION_X_MASK=2'b11 %i %i + +design -reset + +# Good case 8: uncollidable addresses, but still have soft transparency logic. + +read_verilog << EOT + +module top( + input [3:0] addr, + input [3:0] wd1, + input [3:0] wd2, + input we1, we2, + input re, + input clk, + output reg [3:0] rd, +); + +reg [3:0] mem[0:15]; + +wire [3:0] wa1 = addr; +wire [3:0] wa2 = addr + 1; +wire [3:0] ra = addr + 2; + +always @(posedge clk) begin + if (we1) + mem[wa1] <= wd1; + if (we2) + mem[wa2] <= wd2; + if (re) begin + rd <= mem[ra]; + if (we1 && wa1 == ra) + rd <= wd1; + if (we2 && wa2 == ra) + rd <= wd2; + end +end + +endmodule + +EOT + +hierarchy -auto-top +proc +opt_dff +opt_clean +memory_dff +memory_collect +select -assert-count 1 t:$mem_v2 +select -assert-count 1 t:$mem_v2 r:RD_TRANSPARENCY_MASK=2'b00 r:RD_COLLISION_X_MASK=2'b11 %i %i + +design -reset + +# Bad case 1: broken bypass signal. + +read_verilog << EOT + +module top( + input [3:0] ra, + input [3:0] wa1, + input [3:0] wa2, + input [3:0] wd1, + input [3:0] wd2, + input we1, we2, + input re, + input clk, + output reg [3:0] rd, +); + +reg [3:0] mem[0:15]; + +always @(posedge clk) begin + if (we1) + mem[wa1] <= wd1; + if (we2) + mem[wa2] <= wd2; + if (re) begin + rd <= mem[ra]; + if (we1 && wa1 == ra) + rd <= wd1; + if (we2 && wa2 == ra && we1) + rd <= wd2; + end +end + +endmodule + +EOT + +hierarchy -auto-top +proc +opt_dff +opt_clean +logger -expect log "FF found, but with a mux select that doesn't seem to correspond to transparency logic" 1 +memory_dff +logger -check-expected +memory_collect +select -assert-count 1 t:$mem_v2 +select -assert-count 1 t:$mem_v2 r:RD_CLK_ENABLE=1'b0 %i + +design -reset + +# Bad case 2: bad data signal. + +read_verilog << EOT + +module top( + input [3:0] ra, + input [3:0] wa1, + input [3:0] wa2, + input [3:0] wd1, + input [3:0] wd2, + input we1, we2, + input re, + input clk, + output reg [3:0] rd, +); + +reg [3:0] mem[0:15]; + +always @(posedge clk) begin + if (we1) + mem[wa1] <= wd1; + if (we2) + mem[wa2] <= wd2; + if (re) begin + rd <= mem[ra]; + if (we1 && wa1 == ra) + rd <= wd1; + if (we2 && wa2 == ra) + rd <= wd1; + end +end + +endmodule + +EOT + +hierarchy -auto-top +proc +opt_dff +opt_clean +logger -expect log "FF found, but with a mux data input that doesn't seem to correspond to transparency logic" 1 +memory_dff +logger -check-expected +memory_collect +select -assert-count 1 t:$mem_v2 +select -assert-count 1 t:$mem_v2 r:RD_CLK_ENABLE=1'b0 %i + +design -reset + +# Bad case 3: priority mismatch. + +read_verilog << EOT + +module top( + input [3:0] ra, + input [3:0] wa1, + input [3:0] wa2, + input [3:0] wd1, + input [3:0] wd2, + input we1, we2, + input re, + input clk, + output reg [3:0] rd, +); + +reg [3:0] mem[0:15]; + +always @(posedge clk) begin + if (we1) + mem[wa1] <= wd1; + if (we2) + mem[wa2] <= wd2; + if (re) begin + rd <= mem[ra]; + if (we2 && wa2 == ra) + rd <= wd2; + if (we1 && wa1 == ra) + rd <= wd1; + end +end + +endmodule + +EOT + +hierarchy -auto-top +proc +opt_dff +opt_clean +logger -expect log "FF found, but transparency logic priority doesn't match write priority." 1 +memory_dff +logger -check-expected +memory_collect +select -assert-count 1 t:$mem_v2 +select -assert-count 1 t:$mem_v2 r:RD_CLK_ENABLE=1'b0 %i + +design -reset + +# Good case 10: priority mismatch, but since the second value is 'x, it's still OK. + +read_verilog << EOT + +module top( + input [3:0] ra, + input [3:0] wa1, + input [3:0] wa2, + input [3:0] wd1, + input [3:0] wd2, + input we1, we2, + input re, + input clk, + output reg [3:0] rd, +); + +reg [3:0] mem[0:15]; + +always @(posedge clk) begin + if (we1) + mem[wa1] <= wd1; + if (we2) + mem[wa2] <= wd2; + if (re) begin + rd <= mem[ra]; + if (we2 && wa2 == ra) + rd <= wd2; + if (we1 && wa1 == ra) + rd <= 4'hx; + end +end + +endmodule + +EOT + +hierarchy -auto-top +proc +opt_dff +opt_clean +memory_dff +memory_collect +select -assert-count 1 t:$mem_v2 +select -assert-count 1 t:$mem_v2 r:RD_TRANSPARENCY_MASK=2'b10 r:RD_COLLISION_X_MASK=2'b01 %i %i + +design -reset + +# Good case 11: priority mismatch, but since three-way collision cannot happen, it's still OK. + +read_verilog << EOT + +module top( + input [3:0] addr, + input [1:0] mode, + input [3:0] wd1, + input [3:0] wd2, + input we1, we2, + input re, + input clk, + output reg [3:0] rd, +); + +reg [3:0] wa1, wa2, ra; + +always @* begin + case (mode) + 0: begin + wa1 = addr+1; + wa2 = addr; + ra = addr; + end + 1: begin + wa1 = addr; + wa2 = addr+1; + ra = addr; + end + 2: begin + wa1 = addr; + wa2 = addr; + ra = addr+1; + end + 3: begin + wa1 = addr; + wa2 = addr+1; + ra = addr+2; + end + endcase +end + +reg [3:0] mem[0:15]; + +always @(posedge clk) begin + if (we1) + mem[wa1] <= wd1; + if (we2) + mem[wa2] <= wd2; + if (re) begin + rd <= mem[ra]; + if (we2 && wa2 == ra) + rd <= wd2; + if (we1 && wa1 == ra) + rd <= wd1; + end +end + +endmodule + +EOT + +hierarchy -auto-top +proc +opt_dff +opt_clean +memory_dff +memory_collect +select -assert-count 1 t:$mem_v2 +select -assert-count 1 t:$mem_v2 r:RD_TRANSPARENCY_MASK=2'b11 r:RD_COLLISION_X_MASK=2'b00 %i %i + +design -reset + +# Bad case 4: half of the port is transparent. + +read_verilog << EOT + +module top( + input [3:0] ra, + input [3:0] wa1, + input [3:0] wa2, + input [3:0] wd1, + input [3:0] wd2, + input we1, we2, + input re, + input clk, + output reg [3:0] rd, +); + +reg [3:0] mem[0:15]; + +always @(posedge clk) begin + if (we1) + mem[wa1] <= wd1; + if (we2) + mem[wa2] <= wd2; + if (re) begin + rd <= mem[ra]; + if (we1 && wa1 == ra) + rd <= wd1; + if (we2 && wa2 == ra) + rd[3:2] <= wd2[3:2]; + end +end + +endmodule + +EOT + +hierarchy -auto-top +proc +opt_dff +opt_clean +logger -expect log "FF found, but soft transparency logic is inconsistent for port 1." 1 +memory_dff +logger -check-expected +memory_collect +select -assert-count 1 t:$mem_v2 +select -assert-count 1 t:$mem_v2 r:RD_CLK_ENABLE=1'b0 %i + +design -reset + +# Good case 12: like above, but the other bits aren't changed by the port anyway. + +read_verilog << EOT + +module top( + input [3:0] ra, + input [3:0] wa1, + input [3:0] wa2, + input [3:0] wd1, + input [3:0] wd2, + input we1, we2, + input re, + input clk, + output reg [3:0] rd, +); + +reg [3:0] mem[0:15]; + +always @(posedge clk) begin + if (we1) + mem[wa1] <= wd1; + if (we2) + mem[wa2][3:2] <= wd2[3:2]; + if (re) begin + rd <= mem[ra]; + if (we1 && wa1 == ra) + rd <= wd1; + if (we2 && wa2 == ra) + rd[3:2] <= wd2[3:2]; + end +end + +endmodule + +EOT + +hierarchy -auto-top +proc +opt_dff +opt_clean +memory_dff +memory_collect +select -assert-count 1 t:$mem_v2 +select -assert-count 1 t:$mem_v2 r:RD_TRANSPARENCY_MASK=2'b11 r:RD_COLLISION_X_MASK=2'b00 %i %i + +design -reset + +# Good case 13: wide read, narrow write. + +read_verilog << EOT + +module top( + input [7:0] addr, + input [7:0] wd, + input we, + input re, + input clk, + output reg [31:0] rd, +); + +reg [7:0] mem[0:255]; + +always @(posedge clk) begin + if (we) + mem[addr] <= wd; + if (re) begin + rd[7:0] <= mem[{addr[7:2], 2'b00}]; + rd[15:8] <= mem[{addr[7:2], 2'b01}]; + rd[23:16] <= mem[{addr[7:2], 2'b10}]; + rd[31:24] <= mem[{addr[7:2], 2'b11}]; + case ({we, addr[1:0]}) + 3'b100: rd[7:0] <= wd; + 3'b101: rd[15:8] <= wd; + 3'b110: rd[23:16] <= wd; + 3'b111: rd[31:24] <= wd; + endcase + end +end + +endmodule + +EOT + +hierarchy -auto-top +proc +opt_dff +opt_clean +dump +memory_dff +memory_collect +select -assert-count 1 t:$mem_v2 +select -assert-count 1 t:$mem_v2 r:RD_TRANSPARENCY_MASK=4'b1111 r:RD_COLLISION_X_MASK=4'b0000 %i %i +memory_share +select -assert-count 1 t:$mem_v2 +select -assert-count 1 t:$mem_v2 r:RD_TRANSPARENCY_MASK=4'b1111 r:RD_COLLISION_X_MASK=4'b0000 %i %i +select -assert-count 1 t:$mem_v2 r:RD_WIDE_CONTINUATION=4'b1110 %i + +design -reset + +# Good case 14: narrow read, wide write. + +read_verilog << EOT + +module top( + input [7:0] addr, + input [31:0] wd, + input we, + input re, + input clk, + output reg [7:0] rd, +); + +reg [7:0] mem[0:255]; + +always @(posedge clk) begin + if (we) begin + mem[{addr[7:2], 2'b00}] <= wd[7:0]; + mem[{addr[7:2], 2'b01}] <= wd[15:8]; + mem[{addr[7:2], 2'b10}] <= wd[23:16]; + mem[{addr[7:2], 2'b11}] <= wd[31:24]; + end + if (re) begin + rd <= mem[addr]; + case ({we, addr[1:0]}) + 3'b100: rd <= wd[7:0]; + 3'b101: rd <= wd[15:8]; + 3'b110: rd <= wd[23:16]; + 3'b111: rd <= wd[31:24]; + endcase + end +end + +endmodule + +EOT + +hierarchy -auto-top +proc +opt_dff +opt_clean +dump +memory_dff +memory_collect +select -assert-count 1 t:$mem_v2 +select -assert-count 1 t:$mem_v2 r:RD_TRANSPARENCY_MASK=4'b1111 r:RD_COLLISION_X_MASK=4'b0000 %i %i +memory_share +select -assert-count 1 t:$mem_v2 +select -assert-count 1 t:$mem_v2 r:RD_TRANSPARENCY_MASK=4'b1111 r:RD_COLLISION_X_MASK=4'b0000 %i %i +select -assert-count 1 t:$mem_v2 r:WR_WIDE_CONTINUATION=4'b1110 %i + +design -reset + +# Good case 15: wide read, wide write. + +read_verilog << EOT + +module top( + input [7:0] addr, + input [31:0] wd, + input we, + input re, + input clk, + output reg [31:0] rd, +); + +reg [7:0] mem[0:255]; + +always @(posedge clk) begin + if (we) begin + mem[{addr[7:2], 2'b00}] <= wd[7:0]; + mem[{addr[7:2], 2'b01}] <= wd[15:8]; + mem[{addr[7:2], 2'b10}] <= wd[23:16]; + mem[{addr[7:2], 2'b11}] <= wd[31:24]; + end + if (re) begin + rd[7:0] <= mem[{addr[7:2], 2'b00}]; + rd[15:8] <= mem[{addr[7:2], 2'b01}]; + rd[23:16] <= mem[{addr[7:2], 2'b10}]; + rd[31:24] <= mem[{addr[7:2], 2'b11}]; + if (we) + rd <= wd; + end +end + +endmodule + +EOT + +hierarchy -auto-top +proc +opt_dff +opt_clean +dump +memory_dff +select -assert-count 4 t:$memrd_v2 +select -assert-count 1 t:$memrd_v2 r:TRANSPARENCY_MASK=4'b0001 r:COLLISION_X_MASK=4'b1110 %i %i +select -assert-count 1 t:$memrd_v2 r:TRANSPARENCY_MASK=4'b0010 r:COLLISION_X_MASK=4'b1101 %i %i +select -assert-count 1 t:$memrd_v2 r:TRANSPARENCY_MASK=4'b0100 r:COLLISION_X_MASK=4'b1011 %i %i +select -assert-count 1 t:$memrd_v2 r:TRANSPARENCY_MASK=4'b1000 r:COLLISION_X_MASK=4'b0111 %i %i +memory_share +select -assert-count 1 t:$memrd_v2 +select -assert-count 1 t:$memwr_v2 +select -assert-count 1 t:$memrd_v2 r:TRANSPARENCY_MASK=1'b1 r:COLLISION_X_MASK=1'b0 %i %i + +design -reset diff --git a/tests/opt/memory_map_offset.ys b/tests/opt/memory_map_offset.ys new file mode 100644 index 000000000..06969922d --- /dev/null +++ b/tests/opt/memory_map_offset.ys @@ -0,0 +1,100 @@ +read_verilog << EOT + +module top(...); + +input [3:0] ra; +input [3:0] wa; + +input [15:0] wd; +output [15:0] rd; +input en, clk; + +reg [15:0] mem[3:9]; + +always @(posedge clk) + if (en) + mem[wa] <= wd; + +assign rd = mem[ra]; + +endmodule + +EOT + +hierarchy -auto-top +proc +opt_clean +memory_map + +design -stash gate + +read_verilog << EOT + +module top(...); + +input [3:0] ra; +input [3:0] wa; + +input [15:0] wd; +output reg [15:0] rd; +input en, clk; + +reg [15:0] \mem[3] ; +reg [15:0] \mem[4] ; +reg [15:0] \mem[5] ; +reg [15:0] \mem[6] ; +reg [15:0] \mem[7] ; +reg [15:0] \mem[8] ; +reg [15:0] \mem[9] ; + +always @(posedge clk) begin + if (en && wa == 3) + \mem[3] <= wd; + if (en && wa == 4) + \mem[4] <= wd; + if (en && wa == 5) + \mem[5] <= wd; + if (en && wa == 6) + \mem[6] <= wd; + if (en && wa == 7) + \mem[7] <= wd; + if (en && wa == 8) + \mem[8] <= wd; + if (en && wa == 9) + \mem[9] <= wd; +end + +always @* begin + rd = 16'bx; + if (ra == 3) + rd = \mem[3] ; + if (ra == 4) + rd = \mem[4] ; + if (ra == 5) + rd = \mem[5] ; + if (ra == 6) + rd = \mem[6] ; + if (ra == 7) + rd = \mem[7] ; + if (ra == 8) + rd = \mem[8] ; + if (ra == 9) + rd = \mem[9] ; +end + +endmodule + +EOT + +hierarchy -auto-top +proc +opt_clean + +design -stash gold + +design -copy-from gold -as gold A:top +design -copy-from gate -as gate A:top + +equiv_make gold gate equiv +equiv_induct -undef equiv +equiv_status -assert equiv diff --git a/tests/opt/opt_clean_init.ys b/tests/opt/opt_clean_init.ys index 0d567608d..7933f3e17 100644 --- a/tests/opt/opt_clean_init.ys +++ b/tests/opt/opt_clean_init.ys @@ -1,13 +1,22 @@ -logger -expect warning "Initial value conflict for \\y resolving to 1'0 but with init 1'1" 1 -logger -expect-no-warnings -read_verilog <<EOT -module top; -(* init=1'b0 *) wire w = 1'b0; -(* init=1'bx *) wire x = 1'b0; -(* init=1'b1 *) wire y = 1'b0; -(* init=1'b0 *) wire z = 1'bx; +read_verilog << EOT +module top(...); + +input [1:0] D; +input C; +output O; +reg [1:0] Q; + +initial Q = 0; + +always @(posedge C) + Q <= D; + +assign O = Q[1]; + endmodule EOT -clean -select -assert-count 1 a:init -select -assert-count 1 w:y a:init %i + +synth +check -assert -initdrv + +select -assert-count 1 a:init=2'b0x diff --git a/tests/opt/opt_clean_mem.ys b/tests/opt/opt_clean_mem.ys index b35b15871..71f9e0d7b 100644 --- a/tests/opt/opt_clean_mem.ys +++ b/tests/opt/opt_clean_mem.ys @@ -22,28 +22,27 @@ endmodule EOT proc -memory_dff select -assert-count 2 t:$memrd -select -assert-count 1 t:$memwr -select -assert-count 1 t:$meminit +select -assert-count 1 t:$memwr_v2 +select -assert-count 1 t:$meminit_v2 design -save orig opt_clean select -assert-none t:$memrd -select -assert-none t:$memwr -select -assert-none t:$meminit +select -assert-none t:$memwr_v2 +select -assert-none t:$meminit_v2 design -load orig expose top/rd1 opt_clean select -assert-count 1 t:$memrd -select -assert-count 1 t:$memwr -select -assert-count 1 t:$meminit +select -assert-count 1 t:$memwr_v2 +select -assert-count 1 t:$meminit_v2 design -load orig expose top/rd1 top/rd2 opt_clean select -assert-count 2 t:$memrd -select -assert-count 1 t:$memwr -select -assert-count 1 t:$meminit +select -assert-count 1 t:$memwr_v2 +select -assert-count 1 t:$meminit_v2 diff --git a/tests/opt/opt_dff_sr.ys b/tests/opt/opt_dff_sr.ys index daedb115c..0961cb11e 100644 --- a/tests/opt/opt_dff_sr.ys +++ b/tests/opt/opt_dff_sr.ys @@ -22,8 +22,10 @@ EOT design -save orig -equiv_opt -undef -assert -multiclock opt_dff -design -load postopt +# Equivalence check will fail for unmapped adlatch and dlatchsr due to negative hold hack. +#equiv_opt -undef -assert -multiclock opt_dff +#design -load postopt +opt_dff select -assert-count 1 t:$dffsr select -assert-count 1 t:$dffsr r:WIDTH=2 %i select -assert-count 1 t:$dffsre @@ -34,8 +36,9 @@ select -assert-none t:$sr design -load orig -equiv_opt -undef -assert -multiclock opt_dff -keepdc -design -load postopt +#equiv_opt -undef -assert -multiclock opt_dff -keepdc +#design -load postopt +opt_dff -keepdc select -assert-count 1 t:$dffsr select -assert-count 1 t:$dffsr r:WIDTH=4 %i select -assert-count 1 t:$dffsre @@ -48,8 +51,9 @@ select -assert-count 1 t:$sr r:WIDTH=4 %i design -load orig simplemap -equiv_opt -undef -assert -multiclock opt_dff -design -load postopt +#equiv_opt -undef -assert -multiclock opt_dff +#design -load postopt +opt_dff select -assert-count 1 t:$_DFF_PP0_ select -assert-count 1 t:$_DFF_PP1_ select -assert-count 1 t:$_DFFE_PN0P_ @@ -61,8 +65,9 @@ select -assert-none t:$_DFF_PP0_ t:$_DFF_PP1_ t:$_DFFE_PN0P_ t:$_DFFE_PN1P_ t:$_ design -load orig simplemap -equiv_opt -undef -assert -multiclock opt_dff -keepdc -design -load postopt +#equiv_opt -undef -assert -multiclock opt_dff -keepdc +#design -load postopt +opt_dff -keepdc select -assert-count 1 t:$_DFF_PP0_ select -assert-count 1 t:$_DFF_PP1_ select -assert-count 2 t:$_DFFSR_PPP_ diff --git a/tests/opt/opt_expr_constconn.v b/tests/opt/opt_expr_constconn.v new file mode 100644 index 000000000..d18b120e3 --- /dev/null +++ b/tests/opt/opt_expr_constconn.v @@ -0,0 +1,8 @@ +module top(...); + +input [7:0] A; +output [7:0] B; +wire [7:0] C = 3; +assign B = A + C; + +endmodule diff --git a/tests/opt/opt_expr_constconn.ys b/tests/opt/opt_expr_constconn.ys new file mode 100644 index 000000000..9dd848a4b --- /dev/null +++ b/tests/opt/opt_expr_constconn.ys @@ -0,0 +1,7 @@ +read_verilog opt_expr_constconn.v +select -assert-count 1 t:$add +select -assert-count 1 t:$add %ci w:C %i +equiv_opt -assert opt_expr +design -load postopt +select -assert-count 1 t:$add +select -assert-count 0 t:$add %ci w:C %i diff --git a/tests/opt/opt_mem_feedback.ys b/tests/opt/opt_mem_feedback.ys new file mode 100644 index 000000000..06d6e7e77 --- /dev/null +++ b/tests/opt/opt_mem_feedback.ys @@ -0,0 +1,189 @@ +# Good case: proper feedback port. + +read_verilog << EOT + +module top(...); + +input clk; +input en; +input s; + +input [3:0] ra; +output [15:0] rd; +input [3:0] wa; +input [15:0] wd; + +reg [15:0] mem[0:15]; + +assign rd = mem[ra]; + +always @(posedge clk) begin + if (en) begin + mem[wa] <= {mem[wa][15:8], s ? wd[7:0] : mem[wa][7:0]}; + end +end + +endmodule + +EOT + +hierarchy -auto-top +proc +opt_clean + +design -save start +memory_map +design -save preopt + +design -load start +opt_mem_feedback +select -assert-count 1 t:$memrd_v2 +memory_map +design -save postopt + +equiv_opt -assert -run prepare: : + + + +design -reset + +# Bad case: read port also used for other things. + +read_verilog << EOT + +module top(...); + +input clk; +input en; +input s; + +output [15:0] rd; +input [3:0] wa; +input [15:0] wd; + +reg [15:0] mem[0:15]; + +assign rd = mem[wa]; + +always @(posedge clk) begin + if (en) begin + mem[wa] <= {s ? rd : wd[15:8], s ? wd[7:0] : rd}; + end +end + +endmodule + +EOT + +hierarchy -auto-top +proc +opt_clean + +design -save start +memory_map +design -save preopt + +design -load start +select -assert-count 1 t:$memrd +opt_mem_feedback +select -assert-count 1 t:$memrd +memory_map +design -save postopt + +equiv_opt -assert -run prepare: : + + + +design -reset + +# Bad case: another user of the mux out. + +read_verilog << EOT + +module top(...); + +input clk; +input en; +input s; + +output [15:0] rd; +input [3:0] wa; +input [15:0] wd; + +reg [15:0] mem[0:15]; + +assign rd = s ? wd : mem[wa]; + +always @(posedge clk) begin + if (en) begin + mem[wa] <= rd; + end +end + +endmodule + +EOT + +hierarchy -auto-top +proc +opt_clean + +design -save start +memory_map +design -save preopt + +design -load start +select -assert-count 1 t:$memrd +opt_mem_feedback +select -assert-count 1 t:$memrd +memory_map +design -save postopt + +equiv_opt -assert -run prepare: : + + + +design -reset + +# Tricky case: legit feedback path, but priority needs to be preserved. + +read_verilog << EOT + +module top(...); + +input clk; +input sel; +input [3:0] wa1; +input [3:0] wa2; +input [15:0] wd1; +input [3:0] ra; +output [15:0] rd; + +reg [15:0] mem [0:15]; + +always @(posedge clk) begin + mem[wa1] <= sel ? wd1 : mem[wa1]; + mem[wa2] <= mem[wa2]; +end + +assign rd = mem[ra]; + +endmodule + +EOT + +hierarchy -auto-top +proc +opt_clean + +design -save start +memory_map +design -save preopt + +design -load start +opt_mem_feedback +select -assert-count 1 t:$memrd_v2 +memory_map +design -save postopt + +equiv_opt -assert -run prepare: : diff --git a/tests/opt/opt_mem_priority.ys b/tests/opt/opt_mem_priority.ys new file mode 100644 index 000000000..a4119e12a --- /dev/null +++ b/tests/opt/opt_mem_priority.ys @@ -0,0 +1,209 @@ +# Bad case: independent write ports. + +read_verilog << EOT + +module top( + input [3:0] wa1, wa2, ra, wd1, wd2, + input clk, we1, we2, + output [3:0] rd); + +reg [3:0] mem[0:15]; +assign rd = mem[ra]; + +always @(posedge clk) begin + if (we1) + mem[wa1] <= wd1; + if (we2) + mem[wa2] <= wd2; +end + +endmodule + +EOT + +hierarchy -auto-top +proc +opt +memory -nomap +select -assert-count 1 t:$mem_v2 +select -assert-count 1 t:$mem_v2 r:WR_PRIORITY_MASK=4'b0100 %i + + +design -reset + +# Good case: write ports with definitely different addresses. + +read_verilog << EOT + +module top( + input [3:0] wa, ra, wd1, wd2, + input clk, we1, we2, + output [3:0] rd); + +reg [3:0] mem[0:15]; +assign rd = mem[ra]; + +always @(posedge clk) begin + if (we1) + mem[wa] <= wd1; + if (we2) + mem[wa ^ 1] <= wd2; +end + +endmodule + +EOT + +hierarchy -auto-top +proc +opt +memory -nomap +select -assert-count 1 t:$mem_v2 +select -assert-count 1 t:$mem_v2 r:WR_PRIORITY_MASK=4'b0000 %i + + +design -reset + +# Bad case 2: the above, but broken. + +read_verilog << EOT + +module top( + input [3:0] wa, ra, wd1, wd2, + input clk, we1, we2, + output [3:0] rd); + +reg [3:0] mem[0:15]; +assign rd = mem[ra]; + +always @(posedge clk) begin + if (we1) + mem[wa] <= wd1; + if (we2) + mem[wa | 1] <= wd2; +end + +endmodule + +EOT + +hierarchy -auto-top +proc +opt +memory -nomap +select -assert-count 1 t:$mem_v2 +select -assert-count 1 t:$mem_v2 r:WR_PRIORITY_MASK=4'b0100 %i + + +design -reset + +# Good case 2: write ports with disjoint bit enables. + +read_verilog << EOT + +module top( + input [3:0] wa1, wa2, ra, + input [1:0] wd1, wd2, + input clk, we1, we2, + output [3:0] rd); + +reg [3:0] mem[0:15]; +assign rd = mem[ra]; + +always @(posedge clk) begin + if (we1) + mem[wa1][1:0] <= wd1; + if (we2) + mem[wa2][3:2] <= wd2; +end + +endmodule + +EOT + +hierarchy -auto-top +proc +opt +memory -nomap +select -assert-count 1 t:$mem_v2 +select -assert-count 1 t:$mem_v2 r:WR_PRIORITY_MASK=4'b0000 %i + + +design -reset + +# Good case 3: write ports with soft priority logic already + +read_verilog << EOT + +module top( + input [3:0] wa1, wa2, ra, wd1, wd2, + input clk, we1, we2, + output [3:0] rd); + +reg [3:0] mem[0:15]; +assign rd = mem[ra]; + +always @(posedge clk) begin + if (we1) + mem[wa1] <= wd1; + if (we2 && wa1 != wa2) + mem[wa2] <= wd2; +end + +endmodule + +EOT + +hierarchy -auto-top +proc +opt +memory -nomap +select -assert-count 1 t:$mem_v2 +select -assert-count 1 t:$mem_v2 r:WR_PRIORITY_MASK=4'b0000 %i + + +design -reset + +# Good case 4: two wide write ports + +read_verilog << EOT + +module top( + input [5:0] wa1, wa2, + input [7:0] ra, + input [31:0] wd1, wd2, + input clk, we1, we2, + output [7:0] rd); + +reg [7:0] mem[0:255]; +assign rd = mem[ra]; + +always @(posedge clk) begin + if (we1) begin + mem[{wa1, 2'b00}] <= wd1[7:0]; + mem[{wa1, 2'b01}] <= wd1[15:8]; + mem[{wa1, 2'b10}] <= wd1[23:16]; + mem[{wa1, 2'b11}] <= wd1[31:24]; + end + if (we2) begin + mem[{wa2, 2'b00}] <= wd2[7:0]; + mem[{wa2, 2'b01}] <= wd2[15:8]; + mem[{wa2, 2'b10}] <= wd2[23:16]; + mem[{wa2, 2'b11}] <= wd2[31:24]; + end +end + +endmodule + +EOT + +hierarchy -auto-top +proc +opt +opt_mem_priority +memory_collect +select -assert-count 1 t:$mem_v2 +select -assert-count 1 t:$mem_v2 r:WR_PRIORITY_MASK=64'h0804020100000000 %i +memory_share +select -assert-count 1 t:$mem_v2 r:WR_PRIORITY_MASK=64'h0f0f0f0f00000000 %i +select -assert-count 1 t:$mem_v2 r:WR_WIDE_CONTINUATION=8'hee %i diff --git a/tests/opt/opt_merge_init.ys b/tests/opt/opt_merge_init.ys index 0176f09c7..20b6cabee 100644 --- a/tests/opt/opt_merge_init.ys +++ b/tests/opt/opt_merge_init.ys @@ -48,7 +48,7 @@ EOT opt_merge select -assert-count 1 t:$dff -select -assert-count 1 a:init=2'bx1 +select -assert-count 1 a:init=2'bx1 a:init=2'b1x design -reset diff --git a/tests/opt/opt_reduce_bmux.ys b/tests/opt/opt_reduce_bmux.ys new file mode 100644 index 000000000..55e0b6d4b --- /dev/null +++ b/tests/opt/opt_reduce_bmux.ys @@ -0,0 +1,117 @@ +read_ilang << EOT + +module \top + wire width 12 input 0 \A + wire width 2 input 1 \S + wire width 6 output 2 \Y + + cell $bmux $0 + parameter \WIDTH 6 + parameter \S_WIDTH 2 + connect \A { \A [11:10] \A [3:2] \A [10:9] \A [7] \A [7] \A [8] \A [2] \A [7:6] \A [5] \A [5] \A [3:2] \A [5:4] \A [1] \A [1] \A [3:0] } + connect \S \S + connect \Y \Y + end +end + +EOT + +equiv_opt -assert opt_reduce -fine +opt_reduce -fine +select -assert-count 1 t:$bmux r:WIDTH=4 %i + +design -reset + +read_ilang << EOT + +module \top + wire width 6 input 0 \A + wire width 2 input 1 \S + wire width 6 output 2 \Y + + cell $bmux $0 + parameter \WIDTH 6 + parameter \S_WIDTH 2 + connect \A { \A [5:0] \A [5:0] \A [5:0] \A [5:0] } + connect \S \S + connect \Y \Y + end +end + +EOT + +equiv_opt -assert opt_reduce -fine +opt_reduce -fine +select -assert-count 0 t:$bmux + +design -reset + +read_ilang << EOT + +module \top + wire width 160 input 0 \A + wire width 2 input 1 \S + wire width 5 output 2 \Y + + cell $bmux $0 + parameter \WIDTH 5 + parameter \S_WIDTH 5 + connect \A \A + connect \S { \S [1] 1'1 \S [0] \S [1] 1'0 } + connect \Y \Y + end +end + +EOT + +equiv_opt -assert opt_reduce -fine +opt_reduce -fine +select -assert-count 1 t:$bmux r:S_WIDTH=2 %i + +design -reset + +read_ilang << EOT + +module \top + wire width 10 input 0 \A + wire input 1 \S + wire width 5 output 2 \Y + + cell $bmux $0 + parameter \WIDTH 5 + parameter \S_WIDTH 1 + connect \A \A + connect \S \S + connect \Y \Y + end +end + +EOT + +equiv_opt -assert opt_reduce -fine +opt_reduce -fine +select -assert-count 0 t:$bmux +select -assert-count 1 t:$mux + +design -reset + +read_ilang << EOT + +module \top + wire width 5 input 0 \A + wire width 5 output 1 \Y + + cell $bmux $0 + parameter \WIDTH 5 + parameter \S_WIDTH 0 + connect \A \A + connect \S { } + connect \Y \Y + end +end + +EOT + +equiv_opt -assert opt_reduce -fine +opt_reduce -fine +select -assert-count 0 t:$bmux diff --git a/tests/opt/opt_reduce_demux.ys b/tests/opt/opt_reduce_demux.ys new file mode 100644 index 000000000..3c5bd7d43 --- /dev/null +++ b/tests/opt/opt_reduce_demux.ys @@ -0,0 +1,91 @@ +read_ilang << EOT + +module \top + wire width 4 input 0 \A + wire width 2 input 1 \S + wire width 24 output 2 \Y + + cell $demux $0 + parameter \WIDTH 6 + parameter \S_WIDTH 2 + connect \A { \A [3] \A [1] 1'0 \A [2:0] } + connect \S \S + connect \Y \Y + end +end + +EOT + +equiv_opt -assert opt_reduce -fine +opt_reduce -fine +select -assert-count 1 t:$demux r:WIDTH=4 %i + +design -reset + +read_ilang << EOT + +module \top + wire width 2 input 1 \S + wire width 24 output 2 \Y + + cell $demux $0 + parameter \WIDTH 6 + parameter \S_WIDTH 2 + connect \A 6'000000 + connect \S \S + connect \Y \Y + end +end + +EOT + +equiv_opt -assert opt_reduce -fine +opt_reduce -fine +select -assert-count 0 t:$demux + +design -reset + +read_ilang << EOT + +module \top + wire width 5 input 0 \A + wire width 2 input 1 \S + wire width 160 output 2 \Y + + cell $demux $0 + parameter \WIDTH 5 + parameter \S_WIDTH 5 + connect \A \A + connect \S { \S [0] \S [1] 1'1 \S [0] 1'0 } + connect \Y \Y + end +end + +EOT + +equiv_opt -assert opt_reduce -fine +opt_reduce -fine +select -assert-count 1 t:$demux r:S_WIDTH=2 %i + +design -reset + +read_ilang << EOT + +module \top + wire width 5 input 0 \A + wire width 20 output 2 \Y + + cell $demux $0 + parameter \WIDTH 5 + parameter \S_WIDTH 2 + connect \A \A + connect \S { 2'10 } + connect \Y \Y + end +end + +EOT + +equiv_opt -assert opt_reduce -fine +opt_reduce -fine +select -assert-count 0 t:$demux |
